From 66a1d38c9891aa59fc896eacb4607cf5e953fe33 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Mon, 13 Mar 2023 01:30:57 +0100 Subject: [PATCH] rockchip: rk3288: syscon_rk3288: store syscon platdata in regmap 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 Reviewed-by: Simon Glass Tested-by: Simon Glass --- 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 9c1ae880c7..8b2c2f323a 100644 --- a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c @@ -6,7 +6,10 @@ #include #include +#include #include +#include +#include #include #include @@ -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.39.5