pmdomain: renesas: rcar-sysc: Cleanups and R-Car M3-W quirk handling
Subsystems (2)
Geert Uytterhoeven
maintainercover pmdomain: renesas: rcar-sysc: Cleanups and R-Car M3-W quirk handling
Hi all,
According to the hardware team, R-Car H3 ES1.0 and R-Car M3-W have a rare quirk where powering down the A3IR, A3VC, and A3VP power domains requires an extra delay of 1 µs. So far upstream never handled that, but the BSP has a fix[1]. As support for R-Car H3 ES1.x was dropped in v6.4, only R-Car M3-W still needs to be handled.
The BSP fix relies on hard-coded string comparisons of power domain names, and thus applies to all R-Car Gen3 SoCs (many introduced after the original fix was written) having domains with a matching name, whether they are affected or not. Hence I took the opportunity to refactor the R-Car SYSC driver first, and came up with a less-intrusive fix.
Thanks for your comments!
[1] https://github.com/renesas-rcar/linux-bsp/commit/495e47e390499c522197352a08f423e8a3b41e83
Geert Uytterhoeven (4):
pmdomain: renesas: rcar-sysc: Absorb rcar_sysc_ch into rcar_sysc_pd
pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers
pmdomain: renesas: rcar-sysc: Remove rcar_sysc_nullify() helper
pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk
drivers/pmdomain/renesas/Makefile | 4 +-
.../{r8a7796-sysc.c => r8a77960-sysc.c} | 34 +++------
.../{r8a7796-sysc.c => r8a77961-sysc.c} | 28 ++------
drivers/pmdomain/renesas/rcar-sysc.c | 70 ++++++++-----------
drivers/pmdomain/renesas/rcar-sysc.h | 9 +--
5 files changed, 43 insertions(+), 102 deletions(-)
copy drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77960-sysc.c} (64%)
rename drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77961-sysc.c} (69%)Signature · 12 lines
2.34.1
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus TorvaldsGeert Uytterhoeven
maintainerPATCH 1/4 pmdomain: renesas: rcar-sysc: Absorb rcar_sysc_ch into rcar_sysc_pd
Until commit 7e8a50df26f4e700 ("soc: renesas: rcar-sysc: Drop legacy handling") in v4.19, the rcar_sysc_ch structure was part of the API for legacy board code not yet using DT. Since then, there is no longer a reason to keep it as a separate structure.
Moreover, a future quirk handling will need access to the rcar_sysc_pd structure's flags member in rcar_sysc_pwr_on_off(). Hence absorb the rcar_sysc_ch structure into the rcar_sysc_pd structure, and pass around the latter instead of the former.
--- drivers/pmdomain/renesas/rcar-sysc.c | 54 +++++++++++++--------------- 1 file changed, 24 insertions(+), 30 deletions(-)
drivers/pmdomain/renesas/rcar-sysc.c +24 -30
@@ -56,17 +56,20 @@#define RCAR_PD_ALWAYS_ON 32/* Always-on power area */ -struct rcar_sysc_ch { +struct rcar_sysc_pd { +struct generic_pm_domain genpd;u16 chan_offs;u8 chan_bit;u8 isr_bit; +unsigned int flags; +char name[]; };static void __iomem *rcar_sysc_base;static DEFINE_SPINLOCK (rcar_sysc_lock);/* SMP CPUs + I/O devices */ static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val; -static int rcar_sysc_pwr_on_off (const struct rcar_sysc_ch *sysc_ch,bool on) +static int rcar_sysc_pwr_on_off (const struct rcar_sysc_pd *pd,bool on) {unsigned int sr_bit, reg_offs;u32 val;
@@ -88,16 +91,15 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)return -EAGAIN ;/* Submit power shutoff or power resume request */ -iowrite32 (BIT (sysc_ch->chan_bit), - rcar_sysc_base + sysc_ch->chan_offs + reg_offs); +iowrite32 (BIT (pd->chan_bit), rcar_sysc_base + pd->chan_offs + reg_offs);return 0 ; } -static int rcar_sysc_power (const struct rcar_sysc_ch *sysc_ch,bool on) +static int rcar_sysc_power (const struct rcar_sysc_pd *pd,bool on) { -unsigned int isr_mask =BIT (sysc_ch->isr_bit); -unsigned int chan_mask =BIT (sysc_ch->chan_bit); +unsigned int isr_mask =BIT (pd->isr_bit); +unsigned int chan_mask =BIT (pd->chan_bit);unsigned int status, k;unsigned long flags;int ret;
@@ -125,12 +127,11 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)/* Submit power shutoff or resume request until it was accepted */ for (k =0 ; k <PWRER_RETRIES ; k++) { - ret =rcar_sysc_pwr_on_off (sysc_ch, on); + ret =rcar_sysc_pwr_on_off (pd, on);if (ret) goto out; - status =ioread32 (rcar_sysc_base + - sysc_ch->chan_offs +PWRER_OFFS ); + status =ioread32 (rcar_sysc_base + pd->chan_offs +PWRER_OFFS );if (!(status & chan_mask))break ;
@@ -158,28 +159,21 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)spin_unlock_irqrestore (&rcar_sysc_lock, flags);pr_debug ("sysc power %s domain %d: %08x -> %d\n" , on ?"on" :"off" , - sysc_ch->isr_bit,ioread32 (rcar_sysc_base +SYSCISR ), ret); + pd->isr_bit,ioread32 (rcar_sysc_base +SYSCISR ), ret);return ret; } -static bool rcar_sysc_power_is_off (const struct rcar_sysc_ch *sysc_ch) +static bool rcar_sysc_power_is_off (const struct rcar_sysc_pd *pd) {unsigned int st; - st =ioread32 (rcar_sysc_base + sysc_ch->chan_offs +PWRSR_OFFS ); -if (st &BIT (sysc_ch->chan_bit)) + st =ioread32 (rcar_sysc_base + pd->chan_offs +PWRSR_OFFS ); +if (st &BIT (pd->chan_bit))return true;return false; } -struct rcar_sysc_pd { -struct generic_pm_domain genpd; -struct rcar_sysc_ch ch; -unsigned int flags; -char name[]; -}; -static inline struct rcar_sysc_pd *to_rcar_pd (struct generic_pm_domain *d) { return container_of(d, struct rcar_sysc_pd, genpd);
@@ -190,7 +184,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd)struct rcar_sysc_pd *pd =to_rcar_pd (genpd);pr_debug ("%s: %s\n" , __func__, genpd->name); -return rcar_sysc_power (&pd->ch, false); +return rcar_sysc_power (pd, false); }static int rcar_sysc_pd_power_on (struct generic_pm_domain *genpd)
@@ -198,7 +192,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)struct rcar_sysc_pd *pd =to_rcar_pd (genpd);pr_debug ("%s: %s\n" , __func__, genpd->name); -return rcar_sysc_power (&pd->ch, true); +return rcar_sysc_power (pd, true); }static bool has_cpg_mstp;
@@ -252,12 +246,12 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd) goto finalize; } -if (!rcar_sysc_power_is_off (&pd->ch)) { +if (!rcar_sysc_power_is_off (pd)) {pr_debug ("%s: %s is already powered\n" , __func__, genpd->name); goto finalize; } -rcar_sysc_power (&pd->ch, true); +rcar_sysc_power (pd, true); finalize: error =pm_genpd_init (genpd, &simple_qos_governor, false);
@@ -412,9 +406,9 @@ static int __init rcar_sysc_pd_init(void)memcpy (pd->name, area->name, n); pd->genpd.name = pd->name; - pd->ch.chan_offs = area->chan_offs; - pd->ch.chan_bit = area->chan_bit; - pd->ch.isr_bit = area->isr_bit; + pd->chan_offs = area->chan_offs; + pd->chan_bit = area->chan_bit; + pd->isr_bit = area->isr_bit; pd->flags = area->flags; error =rcar_sysc_pd_setup (pd);
@@ -473,10 +467,10 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on)continue ; pd =to_rcar_pd (genpd); -if (!(pd->flags &PD_CPU ) || pd->ch.chan_bit != idx) +if (!(pd->flags &PD_CPU ) || pd->chan_bit != idx)continue ; -return rcar_sysc_power (&pd->ch, on); +return rcar_sysc_power (pd, on); }return -ENOENT ;
Signature · 1 line
2.34.1
Geert Uytterhoeven
maintainerPATCH 2/4 pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers
In reply to Geert UytterhoevenCurrently R-Car M3-W and M3-W+ are handled by a single sub-driver, but using separate Kconfig symbols and separate rcar_sysc_info structures, and fixup code to handle the remaining differences.
Prepare for handling more differences by splitting them in two separate sub-drivers.
---
drivers/pmdomain/renesas/Makefile | 4 +--
.../{r8a7796-sysc.c => r8a77960-sysc.c} | 28 +++----------------
.../{r8a7796-sysc.c => r8a77961-sysc.c} | 28 +++----------------
3 files changed, 10 insertions(+), 50 deletions(-)
copy drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77960-sysc.c} (69%)
rename drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77961-sysc.c} (69%)drivers/pmdomain/renesas/Makefile +2 -2
@@ -14,8 +14,8 @@ obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o -obj-$(CONFIG_SYSC_R8A77960) += r8a7796-sysc.o -obj-$(CONFIG_SYSC_R8A77961) += r8a7796-sysc.o +obj-$(CONFIG_SYSC_R8A77960) += r8a77960-sysc.o +obj-$(CONFIG_SYSC_R8A77961) += r8a77961-sysc.o obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
drivers/pmdomain/renesas/r8a77960-sysc.c renamed from drivers/pmdomain/renesas/r8a7796-sysc.c +4 -24
@@ -1,6 +1,6 @@// SPDX-License-Identifier: GPL-2.0 /* -* Renesas R-Car M3-W/W+ System Controller +* Renesas R-Car M3-W System Controller * * Copyright (C) 2016 Glider bvba * Copyright (C) 2018-2019 Renesas Electronics Corporation
@@ -13,7 +13,7 @@#include "rcar-sysc.h" -static struct rcar_sysc_area r8a7796_areas[]__initdata = { +static const struct rcar_sysc_area r8a77960_areas[]__initconst = { {"always-on" ,0 ,0 ,R8A7796_PD_ALWAYS_ON ,-1 ,PD_ALWAYS_ON }, {"ca57-scu" ,0x1c0 ,0 ,R8A7796_PD_CA57_SCU ,R8A7796_PD_ALWAYS_ON ,PD_SCU },
@@ -41,27 +41,7 @@ static struct rcar_sysc_area r8a7796_areas[] __initdata = { }; -#ifdef CONFIG_SYSC_R8A77960 const struct rcar_sysc_info r8a77960_sysc_info__initconst = { - .areas = r8a7796_areas, - .num_areas =ARRAY_SIZE (r8a7796_areas), + .areas = r8a77960_areas, + .num_areas =ARRAY_SIZE (r8a77960_areas), }; -#endif /* CONFIG_SYSC_R8A77960 */ - -#ifdef CONFIG_SYSC_R8A77961 -static int __init r8a77961_sysc_init (void ) -{ -rcar_sysc_nullify (r8a7796_areas,ARRAY_SIZE (r8a7796_areas), -R8A7796_PD_A2VC0 ); - -return 0 ; -} - -const struct rcar_sysc_info r8a77961_sysc_info__initconst = { - .init = r8a77961_sysc_init, - .areas = r8a7796_areas, - .num_areas =ARRAY_SIZE (r8a7796_areas), - .extmask_offs =0x2f8 , - .extmask_val =BIT (0 ), -}; -#endif /* CONFIG_SYSC_R8A77961 */
drivers/pmdomain/renesas/r8a77961-sysc.c renamed from drivers/pmdomain/renesas/r8a7796-sysc.c +4 -24
@@ -1,6 +1,6 @@// SPDX-License-Identifier: GPL-2.0 /* -* Renesas R-Car M3-W/W+ System Controller +* Renesas R-Car M3-W+ System Controller * * Copyright (C) 2016 Glider bvba * Copyright (C) 2018-2019 Renesas Electronics Corporation
@@ -13,7 +13,7 @@#include "rcar-sysc.h" -static struct rcar_sysc_area r8a7796_areas[]__initdata = { +static const struct rcar_sysc_area r8a77961_areas[]__initconst = { {"always-on" ,0 ,0 ,R8A7796_PD_ALWAYS_ON ,-1 ,PD_ALWAYS_ON }, {"ca57-scu" ,0x1c0 ,0 ,R8A7796_PD_CA57_SCU ,R8A7796_PD_ALWAYS_ON ,PD_SCU },
@@ -33,35 +33,15 @@ static struct rcar_sysc_area r8a7796_areas[] __initdata = { PD_CPU_NOCR }, { "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON }, { "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON }, - { "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC }, { "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC }, { "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON }, { "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A }, { "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON }, }; - -#ifdef CONFIG_SYSC_R8A77960 -const struct rcar_sysc_info r8a77960_sysc_info__initconst = { - .areas = r8a7796_areas, - .num_areas =ARRAY_SIZE (r8a7796_areas), -}; -#endif /* CONFIG_SYSC_R8A77960 */ - -#ifdef CONFIG_SYSC_R8A77961 -static int __init r8a77961_sysc_init (void ) -{ -rcar_sysc_nullify (r8a7796_areas,ARRAY_SIZE (r8a7796_areas), -R8A7796_PD_A2VC0 ); - -return 0 ; -} -const struct rcar_sysc_info r8a77961_sysc_info__initconst = { - .init = r8a77961_sysc_init, - .areas = r8a7796_areas, - .num_areas =ARRAY_SIZE (r8a7796_areas), + .areas = r8a77961_areas, + .num_areas =ARRAY_SIZE (r8a77961_areas), .extmask_offs =0x2f8 , .extmask_val =BIT (0 ), }; -#endif /* CONFIG_SYSC_R8A77961 */
Signature · 1 line
2.34.1
Geert Uytterhoeven
maintainerPATCH 3/4 pmdomain: renesas: rcar-sysc: Remove rcar_sysc_nullify() helper
In reply to Geert UytterhoevenThere are no more users left of the rcar_sysc_nullify() helper, so it can be removed.
--- drivers/pmdomain/renesas/rcar-sysc.c | 12 ------------ drivers/pmdomain/renesas/rcar-sysc.h | 8 -------- 2 files changed, 20 deletions(-)
drivers/pmdomain/renesas/rcar-sysc.c +0 -12
@@ -439,18 +439,6 @@ static int __init rcar_sysc_pd_init(void) }early_initcall (rcar_sysc_pd_init); -void __init rcar_sysc_nullify (struct rcar_sysc_area *areas, -unsigned int num_areas,u8 id) -{ -unsigned int i; - -for (i =0 ; i < num_areas; i++) -if (areas[i].isr_bit == id) { - areas[i].name =NULL ; -return ; - } -} -#ifdef CONFIG_ARCH_R8A7779 static int rcar_sysc_power_cpu (unsigned int idx,bool on) {
drivers/pmdomain/renesas/rcar-sysc.h +0 -8
@@ -71,12 +71,4 @@ extern const struct rcar_sysc_info r8a77980_sysc_info;extern const struct rcar_sysc_info r8a77990_sysc_info;extern const struct rcar_sysc_info r8a77995_sysc_info; - -/* -* Helpers for fixing up power area tables depending on SoC revision -*/ - -extern void rcar_sysc_nullify (struct rcar_sysc_area *areas, -unsigned int num_areas,u8 id); -#endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
Signature · 1 line
2.34.1
Geert Uytterhoeven
maintainerPATCH 4/4 pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk
In reply to Geert UytterhoevenR-Car M3-W needs a delay of 1 µs before powering off the A3IR and A3VC power domains. Add support for this using a new flag, which indicates that a power area is subject to this quirk.
Inspired by a patch in the BSP by Dien Pham.
---
Changes compared to the BSP:
- Use a new flag in the SoC-specific area description instead of comparing PM Domain names (which applied the quirk to all SoCs),
- Support for R-Car H3 ES1.x was dropped in v6.4, so it no longer needs handling.
--- drivers/pmdomain/renesas/r8a77960-sysc.c | 6 ++++-- drivers/pmdomain/renesas/rcar-sysc.c | 4 ++++ drivers/pmdomain/renesas/rcar-sysc.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-)
drivers/pmdomain/renesas/r8a77960-sysc.c +4 -2
@@ -32,12 +32,14 @@ static const struct rcar_sysc_area r8a77960_areas[] __initconst = { {"ca53-cpu3" ,0x200 ,3 ,R8A7796_PD_CA53_CPU3 ,R8A7796_PD_CA53_SCU , PD_CPU_NOCR }, { "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON }, - { "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON }, + { "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON, + PD_OFF_DELAY }, { "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC }, { "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC }, { "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON }, { "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A }, - { "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON }, + { "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON, + PD_OFF_DELAY }, };
drivers/pmdomain/renesas/rcar-sysc.c +4 -0
@@ -90,6 +90,10 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_pd *pd, bool on)if (ret)return -EAGAIN ; +/* Power-off delay quirk */ +if (!on && (pd->flags &PD_OFF_DELAY )) +udelay (1 ); +/* Submit power shutoff or power resume request */ iowrite32 (BIT (pd->chan_bit), rcar_sysc_base + pd->chan_offs + reg_offs);
drivers/pmdomain/renesas/rcar-sysc.h +1 -0
@@ -16,6 +16,7 @@#define PD_CPU BIT(0)/* Area contains main CPU core */ #define PD_SCU BIT(1)/* Area contains SCU and L2 cache */ #define PD_NO_CR BIT(2)/* Area lacks PWR{ON,OFF}CR registers */ +#define PD_OFF_DELAY BIT(3)/* Area is subject to power-off delay quirk */ #define PD_CPU_CR PD_CPU/* CPU area has CR (R-Car H1) */ #define PD_CPU_NOCR PD_CPU | PD_NO_CR/* CPU area lacks CR (R-Car Gen2/3) */
Signature · 1 line
2.34.1
Hi Geert
Thank you for the patch
Quoted 6 lines
According to the hardware team, R-Car H3 ES1.0 and R-Car M3-W have a rare quirk where powering down the A3IR, A3VC, and A3VP power domains requires an extra delay of 1 µs. So far upstream never handled that, but the BSP has a fix[1]. As support for R-Car H3 ES1.x was dropped in v6.4, only R-Car M3-W still needs to be handled.
Quoted 6 lines
The BSP fix relies on hard-coded string comparisons of power domain names, and thus applies to all R-Car Gen3 SoCs (many introduced after the original fix was written) having domains with a matching name, whether they are affected or not. Hence I took the opportunity to refactor the R-Car SYSC driver first, and came up with a less-intrusive fix.
For all patches
Thank you for your help !!
Best regards
---
Renesas Electronics
Ph.D. Kuninori Morimoto
Quoted 26 lines · Geert Uytterhoeven
Hi all,
According to the hardware team, R-Car H3 ES1.0 and R-Car M3-W have a rare quirk where powering down the A3IR, A3VC, and A3VP power domains requires an extra delay of 1 µs. So far upstream never handled that, but the BSP has a fix[1]. As support for R-Car H3 ES1.x was dropped in v6.4, only R-Car M3-W still needs to be handled.
The BSP fix relies on hard-coded string comparisons of power domain names, and thus applies to all R-Car Gen3 SoCs (many introduced after the original fix was written) having domains with a matching name, whether they are affected or not. Hence I took the opportunity to refactor the R-Car SYSC driver first, and came up with a less-intrusive fix.
Thanks for your comments!
[1] https://github.com/renesas-rcar/linux-bsp/commit/495e47e390499c522197352a08f423e8a3b41e83
Geert Uytterhoeven (4):
pmdomain: renesas: rcar-sysc: Absorbrcar_sysc_chintorcar_sysc_pd
pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers
pmdomain: renesas: rcar-sysc: Removercar_sysc_nullify()helper
pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk
Quoted 9 lines
drivers/pmdomain/renesas/Makefile | 4 +-
.../{r8a7796-sysc.c => r8a77960-sysc.c} | 34 +++------
.../{r8a7796-sysc.c => r8a77961-sysc.c} | 28 ++------
drivers/pmdomain/renesas/rcar-sysc.c | 70 ++++++++-----------
drivers/pmdomain/renesas/rcar-sysc.h | 9 +--
5 files changed, 43 insertions(+), 102 deletions(-)
copy drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77960-sysc.c} (64%)
rename drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77961-sysc.c} (69%)Applied for next, thanks!
Kind regards
Uffe