The Rockchip SoC rk3288 has 2 types of device trees floating around.
A 64bit reg size when synced from Linux and a 32bit for U-boot.
A pre-probe function in the syscon class driver assumes only 32bit.
For other odd reg structures the regmap must be defined in the individual
syscon driver. Store rk3288 platdata in a regmap before pre-probe
during bind.

Signed-off-by: Johan Jonker <jbx6...@gmail.com>
---

Note:
  Proof of concept not tested with rk3288 hardware,
  but with rk3066.

Changed V7:
  new patch
---
 arch/arm/mach-rockchip/rk3288/syscon_rk3288.c | 121 ++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c 
b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
index 9c1ae880..8b2c2f32 100644
--- a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
@@ -6,7 +6,10 @@

 #include <common.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <log.h>
+#include <malloc.h>
+#include <regmap.h>
 #include <syscon.h>
 #include <asm/arch-rockchip/clock.h>

@@ -25,6 +28,103 @@ U_BOOT_DRIVER(syscon_rk3288) = {
 };

 #if CONFIG_IS_ENABLED(OF_PLATDATA)
+#if IS_ENABLED(CONFIG_FDT_64BIT)
+struct rockchip_rk3288_noc_plat {
+       struct dtd_rockchip_rk3288_noc dtplat;
+};
+
+struct rockchip_rk3288_grf_plat {
+       struct dtd_rockchip_rk3288_grf dtplat;
+};
+
+struct rockchip_rk3288_sgrf_plat {
+       struct dtd_rockchip_rk3288_sgrf dtplat;
+};
+
+struct rockchip_rk3288_pmu_plat {
+       struct dtd_rockchip_rk3288_pmu dtplat;
+};
+
+static int rk3288_noc_bind_of_plat(struct udevice *dev)
+{
+       struct rockchip_rk3288_noc_plat *plat = dev_get_plat(dev);
+       struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+       int size = dev->uclass->uc_drv->per_device_auto;
+
+       if (size && !priv) {
+               priv = calloc(1, size);
+               if (!priv)
+                       return -ENOMEM;
+               dev_set_uclass_priv(dev, priv);
+       }
+
+       dev->driver_data = dev->driver->of_match->data;
+       debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+       return regmap_init_mem_plat(dev, plat->dtplat.reg, 
sizeof(plat->dtplat.reg[0]),
+                                   ARRAY_SIZE(plat->dtplat.reg) / 2, 
&priv->regmap);
+}
+
+static int rk3288_grf_bind_of_plat(struct udevice *dev)
+{
+       struct rockchip_rk3288_grf_plat *plat = dev_get_plat(dev);
+       struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+       int size = dev->uclass->uc_drv->per_device_auto;
+
+       if (size && !priv) {
+               priv = calloc(1, size);
+               if (!priv)
+                       return -ENOMEM;
+               dev_set_uclass_priv(dev, priv);
+       }
+
+       dev->driver_data = dev->driver->of_match->data;
+       debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+       return regmap_init_mem_plat(dev, plat->dtplat.reg, 
sizeof(plat->dtplat.reg[0]),
+                                   ARRAY_SIZE(plat->dtplat.reg) / 2, 
&priv->regmap);
+}
+
+static int rk3288_sgrf_bind_of_plat(struct udevice *dev)
+{
+       struct rockchip_rk3288_sgrf_plat *plat = dev_get_plat(dev);
+       struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+       int size = dev->uclass->uc_drv->per_device_auto;
+
+       if (size && !priv) {
+               priv = calloc(1, size);
+               if (!priv)
+                       return -ENOMEM;
+               dev_set_uclass_priv(dev, priv);
+       }
+
+       dev->driver_data = dev->driver->of_match->data;
+       debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+       return regmap_init_mem_plat(dev, plat->dtplat.reg, 
sizeof(plat->dtplat.reg[0]),
+                                   ARRAY_SIZE(plat->dtplat.reg) / 2, 
&priv->regmap);
+}
+
+static int rk3288_pmu_bind_of_plat(struct udevice *dev)
+{
+       struct rockchip_rk3288_pmu_plat *plat = dev_get_plat(dev);
+       struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+       int size = dev->uclass->uc_drv->per_device_auto;
+
+       if (size && !priv) {
+               priv = calloc(1, size);
+               if (!priv)
+                       return -ENOMEM;
+               dev_set_uclass_priv(dev, priv);
+       }
+
+       dev->driver_data = dev->driver->of_match->data;
+       debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+       return regmap_init_mem_plat(dev, plat->dtplat.reg, 
sizeof(plat->dtplat.reg[0]),
+                                   ARRAY_SIZE(plat->dtplat.reg) / 2, 
&priv->regmap);
+}
+#else
 static int rk3288_syscon_bind_of_plat(struct udevice *dev)
 {
        dev->driver_data = dev->driver->of_match->data;
@@ -32,32 +132,53 @@ static int rk3288_syscon_bind_of_plat(struct udevice *dev)

        return 0;
 }
+#endif

 U_BOOT_DRIVER(rockchip_rk3288_noc) = {
        .name = "rockchip_rk3288_noc",
        .id = UCLASS_SYSCON,
        .of_match = rk3288_syscon_ids,
+#if IS_ENABLED(CONFIG_FDT_64BIT)
+       .bind = rk3288_noc_bind_of_plat,
+       .plat_auto = sizeof(struct rockchip_rk3288_noc_plat),
+#else
        .bind = rk3288_syscon_bind_of_plat,
+#endif
 };

 U_BOOT_DRIVER(rockchip_rk3288_grf) = {
        .name = "rockchip_rk3288_grf",
        .id = UCLASS_SYSCON,
        .of_match = rk3288_syscon_ids + 1,
+#if IS_ENABLED(CONFIG_FDT_64BIT)
+       .bind = rk3288_grf_bind_of_plat,
+       .plat_auto = sizeof(struct rockchip_rk3288_grf_plat),
+#else
        .bind = rk3288_syscon_bind_of_plat,
+#endif
 };

 U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
        .name = "rockchip_rk3288_sgrf",
        .id = UCLASS_SYSCON,
        .of_match = rk3288_syscon_ids + 2,
+#if IS_ENABLED(CONFIG_FDT_64BIT)
+       .bind = rk3288_sgrf_bind_of_plat,
+       .plat_auto = sizeof(struct rockchip_rk3288_sgrf_plat),
+#else
        .bind = rk3288_syscon_bind_of_plat,
+#endif
 };

 U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
        .name = "rockchip_rk3288_pmu",
        .id = UCLASS_SYSCON,
        .of_match = rk3288_syscon_ids + 3,
+#if IS_ENABLED(CONFIG_FDT_64BIT)
+       .bind = rk3288_pmu_bind_of_plat,
+       .plat_auto = sizeof(struct rockchip_rk3288_pmu_plat),
+#else
        .bind = rk3288_syscon_bind_of_plat,
+#endif
 };
 #endif
--
2.20.1

Reply via email to