[PATCH v8 13/24] rockchip: rk3288: syscon_rk3288: store syscon platdata in regmap
Johan Jonker
jbx6244 at gmail.com
Mon Mar 13 01:30:57 CET 2023
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 at 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
More information about the U-Boot
mailing list