]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
rockchip: rk3288: syscon_rk3288: store syscon platdata in regmap
authorJohan Jonker <jbx6244@gmail.com>
Mon, 13 Mar 2023 00:30:57 +0000 (01:30 +0100)
committerKever Yang <kever.yang@rock-chips.com>
Sat, 6 May 2023 09:28:18 +0000 (17:28 +0800)
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 <jbx6244@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
arch/arm/mach-rockchip/rk3288/syscon_rk3288.c

index 9c1ae880c74f9efc1eac548aae5b148e42f963b0..8b2c2f323a71d1bbb9bc78cc14efa1f9572e5ffd 100644 (file)
@@ -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