From 07623f57e4d1cad51624c5f7d3bdcefb5bd34c01 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 30 Mar 2024 22:10:36 +0100 Subject: [PATCH 01/13] pmdomain: mediatek: scpsys: drop driver owner assignment Core in platform_driver_register() already sets the .owner, so driver does not need to. Signed-off-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20240330211036.100956-1-krzysztof.kozlowski@linaro.org Signed-off-by: Ulf Hansson --- drivers/pmdomain/mediatek/mtk-scpsys.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c index 59a7a8c261ed..1a80c1537a43 100644 --- a/drivers/pmdomain/mediatek/mtk-scpsys.c +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c @@ -1138,7 +1138,6 @@ static struct platform_driver scpsys_drv = { .driver = { .name = "mtk-scpsys", .suppress_bind_attrs = true, - .owner = THIS_MODULE, .of_match_table = of_scpsys_match_tbl, }, }; From b1d4c60cbc31d862cbbba8e303d66528e29b4e4e Mon Sep 17 00:00:00 2001 From: Johnson Wang Date: Fri, 29 Mar 2024 12:38:40 +0800 Subject: [PATCH 02/13] pmdomain: mediatek: Add MT8188 buck isolation setting Add buck isolation setting to ADSP_AO, CAM_VCORE and IMG_VCORE power domains in MT8188 for proper buck isolation control in power domain on/off. Signed-off-by: Johnson Wang Signed-off-by: Fei Shao Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20240329044142.3095193-1-fshao@chromium.org Signed-off-by: Ulf Hansson --- drivers/pmdomain/mediatek/mt8188-pm-domains.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h index 06834ab6597c..007235be9efe 100644 --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h @@ -175,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { .ctl_offs = 0x35C, .pwr_sta_offs = 0x16C, .pwr_sta2nd_offs = 0x170, + .ext_buck_iso_offs = 0x3EC, + .ext_buck_iso_mask = BIT(10), .bp_cfg = { BUS_PROT_WR(INFRA, MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1, @@ -187,7 +189,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { MT8188_TOP_AXI_PROT_EN_2_CLR, MT8188_TOP_AXI_PROT_EN_2_STA), }, - .caps = MTK_SCPD_ALWAYS_ON, + .caps = MTK_SCPD_ALWAYS_ON | MTK_SCPD_EXT_BUCK_ISO, }, [MT8188_POWER_DOMAIN_ADSP_INFRA] = { .name = "adsp_infra", @@ -524,6 +526,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { .ctl_offs = 0x3A4, .pwr_sta_offs = 0x16C, .pwr_sta2nd_offs = 0x170, + .ext_buck_iso_offs = 0x3EC, + .ext_buck_iso_mask = BIT(12), .bp_cfg = { BUS_PROT_WR(INFRA, MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1, @@ -541,7 +545,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { MT8188_TOP_AXI_PROT_EN_MM_2_CLR, MT8188_TOP_AXI_PROT_EN_MM_2_STA), }, - .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY | + MTK_SCPD_EXT_BUCK_ISO, }, [MT8188_POWER_DOMAIN_IMG_MAIN] = { .name = "img_main", @@ -591,6 +596,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { .ctl_offs = 0x3A0, .pwr_sta_offs = 0x16C, .pwr_sta2nd_offs = 0x170, + .ext_buck_iso_offs = 0x3EC, + .ext_buck_iso_mask = BIT(11), .bp_cfg = { BUS_PROT_WR(INFRA, MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1, @@ -618,7 +625,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { MT8188_TOP_AXI_PROT_EN_MM_2_CLR, MT8188_TOP_AXI_PROT_EN_MM_2_STA), }, - .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, + .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY | + MTK_SCPD_EXT_BUCK_ISO, }, [MT8188_POWER_DOMAIN_CAM_MAIN] = { .name = "cam_main", From d72d7d6cf77d0f2079b7120628c9bf490de1fae2 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 28 Feb 2024 16:11:39 +0100 Subject: [PATCH 03/13] cpuidle: psci: Drop superfluous wrappers psci_dt_attach|detach_cpu() To simplify the code, let's drop psci_dt_attach|detach_cpu() and use the common dt_idle_attach|detach_cpu() directly instead. Signed-off-by: Ulf Hansson Reviewed-by: Sudeep Holla Link: https://lore.kernel.org/r/20240228151139.2650258-1-ulf.hansson@linaro.org --- drivers/cpuidle/cpuidle-psci-domain.c | 1 + drivers/cpuidle/cpuidle-psci.c | 5 +++-- drivers/cpuidle/cpuidle-psci.h | 20 -------------------- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index b88af1262f1a..2b47811d986f 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -20,6 +20,7 @@ #include #include "cpuidle-psci.h" +#include "dt_idle_genpd.h" struct psci_pd_provider { struct list_head link; diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index bf68920d038a..782030a27703 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -28,6 +28,7 @@ #include "cpuidle-psci.h" #include "dt_idle_states.h" +#include "dt_idle_genpd.h" struct psci_cpuidle_data { u32 *psci_states; @@ -224,7 +225,7 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv, if (IS_ENABLED(CONFIG_PREEMPT_RT)) return 0; - data->dev = psci_dt_attach_cpu(cpu); + data->dev = dt_idle_attach_cpu(cpu, "psci"); if (IS_ERR_OR_NULL(data->dev)) return PTR_ERR_OR_ZERO(data->dev); @@ -311,7 +312,7 @@ static void psci_cpu_deinit_idle(int cpu) { struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu); - psci_dt_detach_cpu(data->dev); + dt_idle_detach_cpu(data->dev); psci_cpuidle_use_cpuhp = false; } diff --git a/drivers/cpuidle/cpuidle-psci.h b/drivers/cpuidle/cpuidle-psci.h index 4e132640ed64..ef004ec7a7c5 100644 --- a/drivers/cpuidle/cpuidle-psci.h +++ b/drivers/cpuidle/cpuidle-psci.h @@ -3,29 +3,9 @@ #ifndef __CPUIDLE_PSCI_H #define __CPUIDLE_PSCI_H -struct device; struct device_node; void psci_set_domain_state(u32 state); int psci_dt_parse_state_node(struct device_node *np, u32 *state); -#ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN - -#include "dt_idle_genpd.h" - -static inline struct device *psci_dt_attach_cpu(int cpu) -{ - return dt_idle_attach_cpu(cpu, "psci"); -} - -static inline void psci_dt_detach_cpu(struct device *dev) -{ - dt_idle_detach_cpu(dev); -} - -#else -static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; } -static inline void psci_dt_detach_cpu(struct device *dev) { } -#endif - #endif /* __CPUIDLE_PSCI_H */ From 02e2a4b3638cdf6c001f368589966887a1420e01 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Sat, 17 Feb 2024 19:27:08 +0530 Subject: [PATCH 04/13] cpuidle: psci: Update init level to core_initcall() Clients like regulators, interconnects and clocks depend on rpmh-rsc to vote on resources and rpmh-rsc depends on psci power-domains to complete probe. All of them are in core_initcall(). Change psci domain init level to core_initcall() to avoid probe defer from all of the above. Signed-off-by: Maulik Shah Link: https://lore.kernel.org/r/20240217-init_level-v1-2-bde9e11f8317@quicinc.com Signed-off-by: Ulf Hansson --- drivers/cpuidle/cpuidle-psci-domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index 2b47811d986f..fae958794339 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -201,4 +201,4 @@ static int __init psci_idle_init_domains(void) { return platform_driver_register(&psci_cpuidle_domain_driver); } -subsys_initcall(psci_idle_init_domains); +core_initcall(psci_idle_init_domains); From 280b773959f1dee3de450c1bff6c04bafdb3c683 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 4 Apr 2024 12:59:52 +0200 Subject: [PATCH 05/13] MAINTAINERS: Add a git for the ARM PSCI PM DOMAIN Let' make it clear that we have git to manage the corresponding patches for the ARM PSCI PM DOMAIN. Cc: Sudeep Holla Cc: Rafael J. Wysocki Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20240404105952.562885-1-ulf.hansson@linaro.org --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7c121493f43d..7fb5b93dfbfe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5578,6 +5578,7 @@ M: Ulf Hansson L: linux-pm@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git F: drivers/cpuidle/cpuidle-psci-domain.c F: drivers/cpuidle/cpuidle-psci.h From dff14aff1ff783bd7e1ff5e550e72a38b665d8a8 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 4 Apr 2024 13:00:18 +0200 Subject: [PATCH 06/13] MAINTAINERS: Add a git for the DT IDLE PM DOMAIN Let' make it clear that we have git to manage the corresponding patches for for the DT IDLE PM DOMAIN. Cc: Rafael J. Wysocki Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20240404110018.568143-1-ulf.hansson@linaro.org --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7fb5b93dfbfe..c40c580f6df2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5586,6 +5586,7 @@ CPUIDLE DRIVER - DT IDLE PM DOMAIN M: Ulf Hansson L: linux-pm@vger.kernel.org S: Supported +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git F: drivers/cpuidle/dt_idle_genpd.c F: drivers/cpuidle/dt_idle_genpd.h From ce5e83925c99ff43cc0b9bebe53d9dcba8e7c08b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 Apr 2024 12:29:22 +0200 Subject: [PATCH 07/13] 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. Signed-off-by: Geert Uytterhoeven Reviewed-by: Kuninori Morimoto Link: https://lore.kernel.org/r/672805a8c52ce63200e342212bbe6f84a445397b.1713348705.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- drivers/pmdomain/renesas/rcar-sysc.c | 54 +++++++++++++--------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c index 35d9aa0dfab8..a60ce08e7d3b 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.c +++ b/drivers/pmdomain/renesas/rcar-sysc.c @@ -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; From 43fefaea066b9522ab56a7ab095f86865ca39c2f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 Apr 2024 12:29:23 +0200 Subject: [PATCH 08/13] pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers Currently 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. Signed-off-by: Geert Uytterhoeven Reviewed-by: Kuninori Morimoto Link: https://lore.kernel.org/r/a416e2bae7227c08d7e7d158366ab021f4d6cc18.1713348705.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- drivers/pmdomain/renesas/Makefile | 4 +- .../{r8a7796-sysc.c => r8a77960-sysc.c} | 28 ++--------- drivers/pmdomain/renesas/r8a77961-sysc.c | 47 +++++++++++++++++++ 3 files changed, 53 insertions(+), 26 deletions(-) rename drivers/pmdomain/renesas/{r8a7796-sysc.c => r8a77960-sysc.c} (69%) create mode 100644 drivers/pmdomain/renesas/r8a77961-sysc.c diff --git a/drivers/pmdomain/renesas/Makefile b/drivers/pmdomain/renesas/Makefile index 89180f19c23b..0391e6e67440 100644 --- a/drivers/pmdomain/renesas/Makefile +++ b/drivers/pmdomain/renesas/Makefile @@ -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 diff --git a/drivers/pmdomain/renesas/r8a7796-sysc.c b/drivers/pmdomain/renesas/r8a77960-sysc.c similarity index 69% rename from drivers/pmdomain/renesas/r8a7796-sysc.c rename to drivers/pmdomain/renesas/r8a77960-sysc.c index 471bd5b3b6ad..e6f2c3f96125 100644 --- a/drivers/pmdomain/renesas/r8a7796-sysc.c +++ b/drivers/pmdomain/renesas/r8a77960-sysc.c @@ -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 */ diff --git a/drivers/pmdomain/renesas/r8a77961-sysc.c b/drivers/pmdomain/renesas/r8a77961-sysc.c new file mode 100644 index 000000000000..a1155068ee7a --- /dev/null +++ b/drivers/pmdomain/renesas/r8a77961-sysc.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas R-Car M3-W+ System Controller + * + * Copyright (C) 2016 Glider bvba + * Copyright (C) 2018-2019 Renesas Electronics Corporation + */ + +#include +#include + +#include + +#include "rcar-sysc.h" + +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 }, + { "ca57-cpu0", 0x80, 0, R8A7796_PD_CA57_CPU0, R8A7796_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca57-cpu1", 0x80, 1, R8A7796_PD_CA57_CPU1, R8A7796_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca53-scu", 0x140, 0, R8A7796_PD_CA53_SCU, R8A7796_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A7796_PD_CA53_CPU0, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A7796_PD_CA53_CPU1, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu2", 0x200, 2, R8A7796_PD_CA53_CPU2, R8A7796_PD_CA53_SCU, + PD_CPU_NOCR }, + { "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 }, + { "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 }, +}; + +const struct rcar_sysc_info r8a77961_sysc_info __initconst = { + .areas = r8a77961_areas, + .num_areas = ARRAY_SIZE(r8a77961_areas), + .extmask_offs = 0x2f8, + .extmask_val = BIT(0), +}; From c8d87704444a8ac731249ca43b6b2039c2949218 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 Apr 2024 12:29:24 +0200 Subject: [PATCH 09/13] pmdomain: renesas: rcar-sysc: Remove rcar_sysc_nullify() helper There are no more users left of the rcar_sysc_nullify() helper, so it can be removed. Signed-off-by: Geert Uytterhoeven Reviewed-by: Kuninori Morimoto Link: https://lore.kernel.org/r/ad61b09283cc8a9cf93a5ea9fffd1cb283b9db92.1713348705.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- drivers/pmdomain/renesas/rcar-sysc.c | 12 ------------ drivers/pmdomain/renesas/rcar-sysc.h | 8 -------- 2 files changed, 20 deletions(-) diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c index a60ce08e7d3b..a9d92e38fcee 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.c +++ b/drivers/pmdomain/renesas/rcar-sysc.c @@ -439,18 +439,6 @@ out_put: } 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) { diff --git a/drivers/pmdomain/renesas/rcar-sysc.h b/drivers/pmdomain/renesas/rcar-sysc.h index 266c599a0a9b..8c4ec36ed7da 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.h +++ b/drivers/pmdomain/renesas/rcar-sysc.h @@ -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__ */ From fdea114ac26ce0eae4e248e6194d39e4e7536f7a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 Apr 2024 12:29:25 +0200 Subject: [PATCH 10/13] pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit R-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. Signed-off-by: Geert Uytterhoeven Reviewed-by: Kuninori Morimoto Link: https://lore.kernel.org/r/ecbc3465c598084c904dd3714e2894463094ed9a.1713348705.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- 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(-) diff --git a/drivers/pmdomain/renesas/r8a77960-sysc.c b/drivers/pmdomain/renesas/r8a77960-sysc.c index e6f2c3f96125..2ab3f565d2b0 100644 --- a/drivers/pmdomain/renesas/r8a77960-sysc.c +++ b/drivers/pmdomain/renesas/r8a77960-sysc.c @@ -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 }, }; diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c index a9d92e38fcee..b99326917330 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.c +++ b/drivers/pmdomain/renesas/rcar-sysc.c @@ -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); diff --git a/drivers/pmdomain/renesas/rcar-sysc.h b/drivers/pmdomain/renesas/rcar-sysc.h index 8c4ec36ed7da..07ffce310686 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.h +++ b/drivers/pmdomain/renesas/rcar-sysc.h @@ -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) */ From 5af7f593be821eb28ce81a91aac71ccdf9dbe4d5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 12 Apr 2024 12:42:07 +0200 Subject: [PATCH 11/13] pmdomain: core: Update the rejected/usage counters at system suspend too During system suspend we may try to enter a low power-state for the genpd in question. Let's take this into account for the statistics too, by updating the rejected/usage counters for the corresponding state. Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20240412104208.74361-1-ulf.hansson@linaro.org --- drivers/pmdomain/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 4215ffd9b11c..903ea0c193e1 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -1178,8 +1178,12 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, /* Choose the deepest state when suspending */ genpd->state_idx = genpd->state_count - 1; - if (_genpd_power_off(genpd, false)) + if (_genpd_power_off(genpd, false)) { + genpd->states[genpd->state_idx].rejected++; return; + } else { + genpd->states[genpd->state_idx].usage++; + } genpd->status = GENPD_STATE_OFF; From 0cebf7cb2d7050703400f426e69e2c7f72c36950 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 12 Apr 2024 12:42:08 +0200 Subject: [PATCH 12/13] pmdomain: core: Don't clear suspended_count at genpd_prepare() There is no longer any need to clear genpd->suspended_count in genpd_prepare(), as it should be correctly incremented and decremented for all cases. In fact, if the counter isn't correctly managed we would be hiding a problem that we shouldn't. Therefore, let's not clear it. Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20240412104208.74361-2-ulf.hansson@linaro.org --- drivers/pmdomain/core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 903ea0c193e1..342779464c0d 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -1255,10 +1255,7 @@ static int genpd_prepare(struct device *dev) return -EINVAL; genpd_lock(genpd); - - if (genpd->prepared_count++ == 0) - genpd->suspended_count = 0; - + genpd->prepared_count++; genpd_unlock(genpd); ret = pm_generic_prepare(dev); From 670c900f69645db394efb38934b3344d8804171a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 Apr 2024 19:00:23 +0300 Subject: [PATCH 13/13] pmdomain: ti-sci: Fix duplicate PD referrals When the dts file has multiple referrers to a single PD (e.g. simple-framebuffer and dss nodes both point to the DSS power-domain) the ti-sci driver will create two power domains, both with the same ID, and that will cause problems as one of the power domains will hide the other one. Fix this checking if a PD with the ID has already been created, and only create a PD for new IDs. Fixes: efa5c01cd7ee ("soc: ti: ti_sci_pm_domains: switch to use multiple genpds instead of one") Signed-off-by: Tomi Valkeinen Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240415-ti-sci-pd-v1-1-a0e56b8ad897@ideasonboard.com Signed-off-by: Ulf Hansson --- drivers/pmdomain/ti/ti_sci_pm_domains.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c index 9dddf227a3a6..1510d5ddae3d 100644 --- a/drivers/pmdomain/ti/ti_sci_pm_domains.c +++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c @@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = { }; MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches); +static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx) +{ + struct ti_sci_pm_domain *pd; + + list_for_each_entry(pd, &pd_provider->pd_list, node) { + if (pd->idx == idx) + return true; + } + + return false; +} + static int ti_sci_pm_domain_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -149,8 +161,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) break; if (args.args_count >= 1 && args.np == dev->of_node) { - if (args.args[0] > max_id) + if (args.args[0] > max_id) { max_id = args.args[0]; + } else { + if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) { + index++; + continue; + } + } pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); if (!pd) {