|
@@ -11,6 +11,9 @@
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/of_device.h>
|
|
|
+#include <linux/mfd/syscon.h>
|
|
|
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
|
|
+#include <linux/regmap.h>
|
|
|
|
|
|
struct imx_weim_devtype {
|
|
|
unsigned int cs_count;
|
|
@@ -56,6 +59,55 @@ static const struct of_device_id weim_id_table[] = {
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(of, weim_id_table);
|
|
|
|
|
|
+static int __init imx_weim_gpr_setup(struct platform_device *pdev)
|
|
|
+{
|
|
|
+ struct device_node *np = pdev->dev.of_node;
|
|
|
+ struct property *prop;
|
|
|
+ const __be32 *p;
|
|
|
+ struct regmap *gpr;
|
|
|
+ u32 gprvals[4] = {
|
|
|
+ 05, /* CS0(128M) CS1(0M) CS2(0M) CS3(0M) */
|
|
|
+ 033, /* CS0(64M) CS1(64M) CS2(0M) CS3(0M) */
|
|
|
+ 0113, /* CS0(64M) CS1(32M) CS2(32M) CS3(0M) */
|
|
|
+ 01111, /* CS0(32M) CS1(32M) CS2(32M) CS3(32M) */
|
|
|
+ };
|
|
|
+ u32 gprval = 0;
|
|
|
+ u32 val;
|
|
|
+ int cs = 0;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ gpr = syscon_regmap_lookup_by_phandle(np, "fsl,weim-cs-gpr");
|
|
|
+ if (IS_ERR(gpr)) {
|
|
|
+ dev_dbg(&pdev->dev, "failed to find weim-cs-gpr\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ of_property_for_each_u32(np, "ranges", prop, p, val) {
|
|
|
+ if (i % 4 == 0) {
|
|
|
+ cs = val;
|
|
|
+ } else if (i % 4 == 3 && val) {
|
|
|
+ val = (val / SZ_32M) | 1;
|
|
|
+ gprval |= val << cs * 3;
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i == 0 || i % 4)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(gprvals); i++) {
|
|
|
+ if (gprval == gprvals[i]) {
|
|
|
+ /* Found it. Set up IOMUXC_GPR1[11:0] with it. */
|
|
|
+ regmap_update_bits(gpr, IOMUXC_GPR1, 0xfff, gprval);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+err:
|
|
|
+ dev_err(&pdev->dev, "Invalid 'ranges' configuration\n");
|
|
|
+ return -EINVAL;
|
|
|
+}
|
|
|
+
|
|
|
/* Parse and set the timing for this device. */
|
|
|
static int __init weim_timing_setup(struct device_node *np, void __iomem *base,
|
|
|
const struct imx_weim_devtype *devtype)
|
|
@@ -92,6 +144,12 @@ static int __init weim_parse_dt(struct platform_device *pdev,
|
|
|
struct device_node *child;
|
|
|
int ret;
|
|
|
|
|
|
+ if (devtype == &imx50_weim_devtype) {
|
|
|
+ ret = imx_weim_gpr_setup(pdev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
for_each_child_of_node(pdev->dev.of_node, child) {
|
|
|
if (!child->name)
|
|
|
continue;
|