From 500daa0e6be292edcf635ba6b090b89da80e90a8 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:32:56 +0900 Subject: [PATCH 1/6] dt-bindings: power: Add r8a779f0 SYSC power domain definitions Add power domain indices for R-Car S4-8 (r8a779f0). Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-3-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/power/r8a779f0-sysc.h | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 include/dt-bindings/power/r8a779f0-sysc.h diff --git a/include/dt-bindings/power/r8a779f0-sysc.h b/include/dt-bindings/power/r8a779f0-sysc.h new file mode 100644 index 000000000000..0ec8ad727ed9 --- /dev/null +++ b/include/dt-bindings/power/r8a779f0-sysc.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */ +/* + * Copyright (C) 2021 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_POWER_R8A779F0_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A779F0_SYSC_H__ + +/* + * These power domain indices match the Power Domain Register Numbers (PDR) + */ + +#define R8A779F0_PD_A1E0D0C0 0 +#define R8A779F0_PD_A1E0D0C1 1 +#define R8A779F0_PD_A1E0D1C0 2 +#define R8A779F0_PD_A1E0D1C1 3 +#define R8A779F0_PD_A1E1D0C0 4 +#define R8A779F0_PD_A1E1D0C1 5 +#define R8A779F0_PD_A1E1D1C0 6 +#define R8A779F0_PD_A1E1D1C1 7 +#define R8A779F0_PD_A2E0D0 16 +#define R8A779F0_PD_A2E0D1 17 +#define R8A779F0_PD_A2E1D0 18 +#define R8A779F0_PD_A2E1D1 19 +#define R8A779F0_PD_A3E0 20 +#define R8A779F0_PD_A3E1 21 + +/* Always-on power area */ +#define R8A779F0_PD_ALWAYS_ON 64 + +#endif /* __DT_BINDINGS_POWER_R8A779A0_SYSC_H__*/ From 81c1655823237eaec74b2c175ae8e13adfccdaf7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:32:57 +0900 Subject: [PATCH 2/6] dt-bindings: clock: Add r8a779f0 CPG Core Clock Definitions Add all Clock Pulse Generator Core Clock Outputs for the Renesas R-Car S4-8 (R8A779F0) SoC. Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-4-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a779f0-cpg-mssr.h | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 include/dt-bindings/clock/r8a779f0-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a779f0-cpg-mssr.h b/include/dt-bindings/clock/r8a779f0-cpg-mssr.h new file mode 100644 index 000000000000..f2ae1c6a82dd --- /dev/null +++ b/include/dt-bindings/clock/r8a779f0-cpg-mssr.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */ +/* + * Copyright (C) 2021 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A779F0_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A779F0_CPG_MSSR_H__ + +#include + +/* r8a779f0 CPG Core Clocks */ + +#define R8A779F0_CLK_ZX 0 +#define R8A779F0_CLK_ZS 1 +#define R8A779F0_CLK_ZT 2 +#define R8A779F0_CLK_ZTR 3 +#define R8A779F0_CLK_S0D2 4 +#define R8A779F0_CLK_S0D3 5 +#define R8A779F0_CLK_S0D4 6 +#define R8A779F0_CLK_S0D2_MM 7 +#define R8A779F0_CLK_S0D3_MM 8 +#define R8A779F0_CLK_S0D4_MM 9 +#define R8A779F0_CLK_S0D2_RT 10 +#define R8A779F0_CLK_S0D3_RT 11 +#define R8A779F0_CLK_S0D4_RT 12 +#define R8A779F0_CLK_S0D6_RT 13 +#define R8A779F0_CLK_S0D3_PER 14 +#define R8A779F0_CLK_S0D6_PER 15 +#define R8A779F0_CLK_S0D12_PER 16 +#define R8A779F0_CLK_S0D24_PER 17 +#define R8A779F0_CLK_S0D2_HSC 18 +#define R8A779F0_CLK_S0D3_HSC 19 +#define R8A779F0_CLK_S0D4_HSC 20 +#define R8A779F0_CLK_S0D6_HSC 21 +#define R8A779F0_CLK_S0D12_HSC 22 +#define R8A779F0_CLK_S0D2_CC 23 +#define R8A779F0_CLK_CL 24 +#define R8A779F0_CLK_CL16M 25 +#define R8A779F0_CLK_CL16M_MM 26 +#define R8A779F0_CLK_CL16M_RT 27 +#define R8A779F0_CLK_CL16M_PER 28 +#define R8A779F0_CLK_CL16M_HSC 29 +#define R8A779F0_CLK_Z0 30 +#define R8A779F0_CLK_Z1 31 +#define R8A779F0_CLK_ZB3 32 +#define R8A779F0_CLK_ZB3D2 33 +#define R8A779F0_CLK_ZB3D4 34 +#define R8A779F0_CLK_SD0H 35 +#define R8A779F0_CLK_SD0 36 +#define R8A779F0_CLK_RPC 37 +#define R8A779F0_CLK_RPCD2 38 +#define R8A779F0_CLK_MSO 39 +#define R8A779F0_CLK_SASYNCRT 40 +#define R8A779F0_CLK_SASYNCPERD1 41 +#define R8A779F0_CLK_SASYNCPERD2 42 +#define R8A779F0_CLK_SASYNCPERD4 43 +#define R8A779F0_CLK_DBGSOC_HSC 44 +#define R8A779F0_CLK_RSW2 45 +#define R8A779F0_CLK_OSC 46 +#define R8A779F0_CLK_ZR 47 +#define R8A779F0_CLK_CPEX 48 +#define R8A779F0_CLK_CBFUSA 49 +#define R8A779F0_CLK_R 50 + +#endif /* __DT_BINDINGS_CLOCK_R8A779F0_CPG_MSSR_H__ */ From e62906d6315f652b80640df0f980086462a4953b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:32:59 +0900 Subject: [PATCH 3/6] soc: renesas: rcar-gen4-sysc: Introduce R-Car Gen4 SYSC driver According to the official website [1], the R-Car V3U SoC is based on the R-Car Gen4 architecture. So, introduce R-Car Gen4 SYSC driver. [1] https://www.renesas.com/us/en/products/automotive-products/automotive-system-chips-socs/r-car-v3u-best-class-r-car-v3u-asil-d-system-chip-automated-driving Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-6-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/Kconfig | 4 + drivers/soc/renesas/Makefile | 1 + drivers/soc/renesas/r8a779a0-sysc.c | 380 +-------------------------- drivers/soc/renesas/rcar-gen4-sysc.c | 373 ++++++++++++++++++++++++++ drivers/soc/renesas/rcar-gen4-sysc.h | 42 +++ 5 files changed, 423 insertions(+), 377 deletions(-) create mode 100644 drivers/soc/renesas/rcar-gen4-sysc.c create mode 100644 drivers/soc/renesas/rcar-gen4-sysc.h diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index ce16ef5c939c..2b09d6cf0d66 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -297,6 +297,9 @@ config RST_RCAR config SYSC_RCAR bool "System Controller support for R-Car" if COMPILE_TEST +config SYSC_RCAR_GEN4 + bool "System Controller support for R-Car Gen4" if COMPILE_TEST + config SYSC_R8A77995 bool "System Controller support for R-Car D3" if COMPILE_TEST select SYSC_RCAR @@ -351,6 +354,7 @@ config SYSC_R8A77970 config SYSC_R8A779A0 bool "System Controller support for R-Car V3U" if COMPILE_TEST + select SYSC_RCAR_GEN4 config SYSC_RMOBILE bool "System Controller support for R-Mobile" if COMPILE_TEST diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 9b29bed2a597..db90f3b06007 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -32,4 +32,5 @@ endif # Family obj-$(CONFIG_RST_RCAR) += rcar-rst.o obj-$(CONFIG_SYSC_RCAR) += rcar-sysc.o +obj-$(CONFIG_SYSC_RCAR_GEN4) += rcar-gen4-sysc.o obj-$(CONFIG_SYSC_RMOBILE) += rmobile-sysc.o diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c index 7410b9fa9846..fdfc857df334 100644 --- a/drivers/soc/renesas/r8a779a0-sysc.c +++ b/drivers/soc/renesas/r8a779a0-sysc.c @@ -21,35 +21,9 @@ #include -/* - * Power Domain flags - */ -#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 */ +#include "rcar-gen4-sysc.h" -#define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR */ -#define PD_ALWAYS_ON PD_NO_CR /* Always-on area */ - -/* - * Description of a Power Area - */ -struct r8a779a0_sysc_area { - const char *name; - u8 pdr; /* PDRn */ - int parent; /* -1 if none */ - unsigned int flags; /* See PD_* */ -}; - -/* - * SoC-specific Power Area Description - */ -struct r8a779a0_sysc_info { - const struct r8a779a0_sysc_area *areas; - unsigned int num_areas; -}; - -static struct r8a779a0_sysc_area r8a779a0_areas[] __initdata = { +static struct rcar_gen4_sysc_area r8a779a0_areas[] __initdata = { { "always-on", R8A779A0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "a3e0", R8A779A0_PD_A3E0, R8A779A0_PD_ALWAYS_ON, PD_SCU }, { "a3e1", R8A779A0_PD_A3E1, R8A779A0_PD_ALWAYS_ON, PD_SCU }, @@ -96,355 +70,7 @@ static struct r8a779a0_sysc_area r8a779a0_areas[] __initdata = { { "a1dsp1", R8A779A0_PD_A1DSP1, R8A779A0_PD_A2CN1 }, }; -static const struct r8a779a0_sysc_info r8a779a0_sysc_info __initconst = { +const struct rcar_gen4_sysc_info r8a779a0_sysc_info __initconst = { .areas = r8a779a0_areas, .num_areas = ARRAY_SIZE(r8a779a0_areas), }; - -/* SYSC Common */ -#define SYSCSR 0x000 /* SYSC Status Register */ -#define SYSCPONSR(x) (0x800 + ((x) * 0x4)) /* Power-ON Status Register 0 */ -#define SYSCPOFFSR(x) (0x808 + ((x) * 0x4)) /* Power-OFF Status Register */ -#define SYSCISCR(x) (0x810 + ((x) * 0x4)) /* Interrupt Status/Clear Register */ -#define SYSCIER(x) (0x820 + ((x) * 0x4)) /* Interrupt Enable Register */ -#define SYSCIMR(x) (0x830 + ((x) * 0x4)) /* Interrupt Mask Register */ - -/* Power Domain Registers */ -#define PDRSR(n) (0x1000 + ((n) * 0x40)) -#define PDRONCR(n) (0x1004 + ((n) * 0x40)) -#define PDROFFCR(n) (0x1008 + ((n) * 0x40)) -#define PDRESR(n) (0x100C + ((n) * 0x40)) - -/* PWRON/PWROFF */ -#define PWRON_PWROFF BIT(0) /* Power-ON/OFF request */ - -/* PDRESR */ -#define PDRESR_ERR BIT(0) - -/* PDRSR */ -#define PDRSR_OFF BIT(0) /* Power-OFF state */ -#define PDRSR_ON BIT(4) /* Power-ON state */ -#define PDRSR_OFF_STATE BIT(8) /* Processing Power-OFF sequence */ -#define PDRSR_ON_STATE BIT(12) /* Processing Power-ON sequence */ - -#define SYSCSR_BUSY GENMASK(1, 0) /* All bit sets is not busy */ - -#define SYSCSR_TIMEOUT 10000 -#define SYSCSR_DELAY_US 10 - -#define PDRESR_RETRIES 1000 -#define PDRESR_DELAY_US 10 - -#define SYSCISR_TIMEOUT 10000 -#define SYSCISR_DELAY_US 10 - -#define NUM_DOMAINS_EACH_REG BITS_PER_TYPE(u32) - -static void __iomem *r8a779a0_sysc_base; -static DEFINE_SPINLOCK(r8a779a0_sysc_lock); /* SMP CPUs + I/O devices */ - -static int r8a779a0_sysc_pwr_on_off(u8 pdr, bool on) -{ - unsigned int reg_offs; - u32 val; - int ret; - - if (on) - reg_offs = PDRONCR(pdr); - else - reg_offs = PDROFFCR(pdr); - - /* Wait until SYSC is ready to accept a power request */ - ret = readl_poll_timeout_atomic(r8a779a0_sysc_base + SYSCSR, val, - (val & SYSCSR_BUSY) == SYSCSR_BUSY, - SYSCSR_DELAY_US, SYSCSR_TIMEOUT); - if (ret < 0) - return -EAGAIN; - - /* Submit power shutoff or power resume request */ - iowrite32(PWRON_PWROFF, r8a779a0_sysc_base + reg_offs); - - return 0; -} - -static int clear_irq_flags(unsigned int reg_idx, unsigned int isr_mask) -{ - u32 val; - int ret; - - iowrite32(isr_mask, r8a779a0_sysc_base + SYSCISCR(reg_idx)); - - ret = readl_poll_timeout_atomic(r8a779a0_sysc_base + SYSCISCR(reg_idx), - val, !(val & isr_mask), - SYSCISR_DELAY_US, SYSCISR_TIMEOUT); - if (ret < 0) { - pr_err("\n %s : Can not clear IRQ flags in SYSCISCR", __func__); - return -EIO; - } - - return 0; -} - -static int r8a779a0_sysc_power(u8 pdr, bool on) -{ - unsigned int isr_mask; - unsigned int reg_idx, bit_idx; - unsigned int status; - unsigned long flags; - int ret = 0; - u32 val; - int k; - - spin_lock_irqsave(&r8a779a0_sysc_lock, flags); - - reg_idx = pdr / NUM_DOMAINS_EACH_REG; - bit_idx = pdr % NUM_DOMAINS_EACH_REG; - - isr_mask = BIT(bit_idx); - - /* - * The interrupt source needs to be enabled, but masked, to prevent the - * CPU from receiving it. - */ - iowrite32(ioread32(r8a779a0_sysc_base + SYSCIER(reg_idx)) | isr_mask, - r8a779a0_sysc_base + SYSCIER(reg_idx)); - iowrite32(ioread32(r8a779a0_sysc_base + SYSCIMR(reg_idx)) | isr_mask, - r8a779a0_sysc_base + SYSCIMR(reg_idx)); - - ret = clear_irq_flags(reg_idx, isr_mask); - if (ret) - goto out; - - /* Submit power shutoff or resume request until it was accepted */ - for (k = 0; k < PDRESR_RETRIES; k++) { - ret = r8a779a0_sysc_pwr_on_off(pdr, on); - if (ret) - goto out; - - status = ioread32(r8a779a0_sysc_base + PDRESR(pdr)); - if (!(status & PDRESR_ERR)) - break; - - udelay(PDRESR_DELAY_US); - } - - if (k == PDRESR_RETRIES) { - ret = -EIO; - goto out; - } - - /* Wait until the power shutoff or resume request has completed * */ - ret = readl_poll_timeout_atomic(r8a779a0_sysc_base + SYSCISCR(reg_idx), - val, (val & isr_mask), - SYSCISR_DELAY_US, SYSCISR_TIMEOUT); - if (ret < 0) { - ret = -EIO; - goto out; - } - - /* Clear interrupt flags */ - ret = clear_irq_flags(reg_idx, isr_mask); - if (ret) - goto out; - - out: - spin_unlock_irqrestore(&r8a779a0_sysc_lock, flags); - - pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", - pdr, ioread32(r8a779a0_sysc_base + SYSCISCR(reg_idx)), ret); - return ret; -} - -static bool r8a779a0_sysc_power_is_off(u8 pdr) -{ - unsigned int st; - - st = ioread32(r8a779a0_sysc_base + PDRSR(pdr)); - - if (st & PDRSR_OFF) - return true; - - return false; -} - -struct r8a779a0_sysc_pd { - struct generic_pm_domain genpd; - u8 pdr; - unsigned int flags; - char name[]; -}; - -static inline struct r8a779a0_sysc_pd *to_r8a779a0_pd(struct generic_pm_domain *d) -{ - return container_of(d, struct r8a779a0_sysc_pd, genpd); -} - -static int r8a779a0_sysc_pd_power_off(struct generic_pm_domain *genpd) -{ - struct r8a779a0_sysc_pd *pd = to_r8a779a0_pd(genpd); - - pr_debug("%s: %s\n", __func__, genpd->name); - return r8a779a0_sysc_power(pd->pdr, false); -} - -static int r8a779a0_sysc_pd_power_on(struct generic_pm_domain *genpd) -{ - struct r8a779a0_sysc_pd *pd = to_r8a779a0_pd(genpd); - - pr_debug("%s: %s\n", __func__, genpd->name); - return r8a779a0_sysc_power(pd->pdr, true); -} - -static int __init r8a779a0_sysc_pd_setup(struct r8a779a0_sysc_pd *pd) -{ - struct generic_pm_domain *genpd = &pd->genpd; - const char *name = pd->genpd.name; - int error; - - if (pd->flags & PD_CPU) { - /* - * This domain contains a CPU core and therefore it should - * only be turned off if the CPU is not in use. - */ - pr_debug("PM domain %s contains %s\n", name, "CPU"); - genpd->flags |= GENPD_FLAG_ALWAYS_ON; - } else if (pd->flags & PD_SCU) { - /* - * This domain contains an SCU and cache-controller, and - * therefore it should only be turned off if the CPU cores are - * not in use. - */ - pr_debug("PM domain %s contains %s\n", name, "SCU"); - genpd->flags |= GENPD_FLAG_ALWAYS_ON; - } else if (pd->flags & PD_NO_CR) { - /* - * This domain cannot be turned off. - */ - genpd->flags |= GENPD_FLAG_ALWAYS_ON; - } - - if (!(pd->flags & (PD_CPU | PD_SCU))) { - /* Enable Clock Domain for I/O devices */ - genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; - genpd->attach_dev = cpg_mssr_attach_dev; - genpd->detach_dev = cpg_mssr_detach_dev; - } - - genpd->power_off = r8a779a0_sysc_pd_power_off; - genpd->power_on = r8a779a0_sysc_pd_power_on; - - if (pd->flags & (PD_CPU | PD_NO_CR)) { - /* Skip CPUs (handled by SMP code) and areas without control */ - pr_debug("%s: Not touching %s\n", __func__, genpd->name); - goto finalize; - } - - if (!r8a779a0_sysc_power_is_off(pd->pdr)) { - pr_debug("%s: %s is already powered\n", __func__, genpd->name); - goto finalize; - } - - r8a779a0_sysc_power(pd->pdr, true); - -finalize: - error = pm_genpd_init(genpd, &simple_qos_governor, false); - if (error) - pr_err("Failed to init PM domain %s: %d\n", name, error); - - return error; -} - -static const struct of_device_id r8a779a0_sysc_matches[] __initconst = { - { .compatible = "renesas,r8a779a0-sysc", .data = &r8a779a0_sysc_info }, - { /* sentinel */ } -}; - -struct r8a779a0_pm_domains { - struct genpd_onecell_data onecell_data; - struct generic_pm_domain *domains[R8A779A0_PD_ALWAYS_ON + 1]; -}; - -static struct genpd_onecell_data *r8a779a0_sysc_onecell_data; - -static int __init r8a779a0_sysc_pd_init(void) -{ - const struct r8a779a0_sysc_info *info; - const struct of_device_id *match; - struct r8a779a0_pm_domains *domains; - struct device_node *np; - void __iomem *base; - unsigned int i; - int error; - - np = of_find_matching_node_and_match(NULL, r8a779a0_sysc_matches, &match); - if (!np) - return -ENODEV; - - info = match->data; - - base = of_iomap(np, 0); - if (!base) { - pr_warn("%pOF: Cannot map regs\n", np); - error = -ENOMEM; - goto out_put; - } - - r8a779a0_sysc_base = base; - - domains = kzalloc(sizeof(*domains), GFP_KERNEL); - if (!domains) { - error = -ENOMEM; - goto out_put; - } - - domains->onecell_data.domains = domains->domains; - domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains); - r8a779a0_sysc_onecell_data = &domains->onecell_data; - - for (i = 0; i < info->num_areas; i++) { - const struct r8a779a0_sysc_area *area = &info->areas[i]; - struct r8a779a0_sysc_pd *pd; - size_t n; - - if (!area->name) { - /* Skip NULLified area */ - continue; - } - - n = strlen(area->name) + 1; - pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL); - if (!pd) { - error = -ENOMEM; - goto out_put; - } - - memcpy(pd->name, area->name, n); - pd->genpd.name = pd->name; - pd->pdr = area->pdr; - pd->flags = area->flags; - - error = r8a779a0_sysc_pd_setup(pd); - if (error) - goto out_put; - - domains->domains[area->pdr] = &pd->genpd; - - if (area->parent < 0) - continue; - - error = pm_genpd_add_subdomain(domains->domains[area->parent], - &pd->genpd); - if (error) { - pr_warn("Failed to add PM subdomain %s to parent %u\n", - area->name, area->parent); - goto out_put; - } - } - - error = of_genpd_add_provider_onecell(np, &domains->onecell_data); - -out_put: - of_node_put(np); - return error; -} -early_initcall(r8a779a0_sysc_pd_init); diff --git a/drivers/soc/renesas/rcar-gen4-sysc.c b/drivers/soc/renesas/rcar-gen4-sysc.c new file mode 100644 index 000000000000..d9a0929f5f1d --- /dev/null +++ b/drivers/soc/renesas/rcar-gen4-sysc.c @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car Gen4 SYSC Power management support + * + * Copyright (C) 2021 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rcar-gen4-sysc.h" + +/* SYSC Common */ +#define SYSCSR 0x000 /* SYSC Status Register */ +#define SYSCPONSR(x) (0x800 + ((x) * 0x4)) /* Power-ON Status Register 0 */ +#define SYSCPOFFSR(x) (0x808 + ((x) * 0x4)) /* Power-OFF Status Register */ +#define SYSCISCR(x) (0x810 + ((x) * 0x4)) /* Interrupt Status/Clear Register */ +#define SYSCIER(x) (0x820 + ((x) * 0x4)) /* Interrupt Enable Register */ +#define SYSCIMR(x) (0x830 + ((x) * 0x4)) /* Interrupt Mask Register */ + +/* Power Domain Registers */ +#define PDRSR(n) (0x1000 + ((n) * 0x40)) +#define PDRONCR(n) (0x1004 + ((n) * 0x40)) +#define PDROFFCR(n) (0x1008 + ((n) * 0x40)) +#define PDRESR(n) (0x100C + ((n) * 0x40)) + +/* PWRON/PWROFF */ +#define PWRON_PWROFF BIT(0) /* Power-ON/OFF request */ + +/* PDRESR */ +#define PDRESR_ERR BIT(0) + +/* PDRSR */ +#define PDRSR_OFF BIT(0) /* Power-OFF state */ +#define PDRSR_ON BIT(4) /* Power-ON state */ +#define PDRSR_OFF_STATE BIT(8) /* Processing Power-OFF sequence */ +#define PDRSR_ON_STATE BIT(12) /* Processing Power-ON sequence */ + +#define SYSCSR_BUSY GENMASK(1, 0) /* All bit sets is not busy */ + +#define SYSCSR_TIMEOUT 10000 +#define SYSCSR_DELAY_US 10 + +#define PDRESR_RETRIES 1000 +#define PDRESR_DELAY_US 10 + +#define SYSCISR_TIMEOUT 10000 +#define SYSCISR_DELAY_US 10 + +#define RCAR_GEN4_PD_ALWAYS_ON 64 +#define NUM_DOMAINS_EACH_REG BITS_PER_TYPE(u32) + +static void __iomem *rcar_gen4_sysc_base; +static DEFINE_SPINLOCK(rcar_gen4_sysc_lock); /* SMP CPUs + I/O devices */ + +static int rcar_gen4_sysc_pwr_on_off(u8 pdr, bool on) +{ + unsigned int reg_offs; + u32 val; + int ret; + + if (on) + reg_offs = PDRONCR(pdr); + else + reg_offs = PDROFFCR(pdr); + + /* Wait until SYSC is ready to accept a power request */ + ret = readl_poll_timeout_atomic(rcar_gen4_sysc_base + SYSCSR, val, + (val & SYSCSR_BUSY) == SYSCSR_BUSY, + SYSCSR_DELAY_US, SYSCSR_TIMEOUT); + if (ret < 0) + return -EAGAIN; + + /* Submit power shutoff or power resume request */ + iowrite32(PWRON_PWROFF, rcar_gen4_sysc_base + reg_offs); + + return 0; +} + +static int clear_irq_flags(unsigned int reg_idx, unsigned int isr_mask) +{ + u32 val; + int ret; + + iowrite32(isr_mask, rcar_gen4_sysc_base + SYSCISCR(reg_idx)); + + ret = readl_poll_timeout_atomic(rcar_gen4_sysc_base + SYSCISCR(reg_idx), + val, !(val & isr_mask), + SYSCISR_DELAY_US, SYSCISR_TIMEOUT); + if (ret < 0) { + pr_err("\n %s : Can not clear IRQ flags in SYSCISCR", __func__); + return -EIO; + } + + return 0; +} + +static int rcar_gen4_sysc_power(u8 pdr, bool on) +{ + unsigned int isr_mask; + unsigned int reg_idx, bit_idx; + unsigned int status; + unsigned long flags; + int ret = 0; + u32 val; + int k; + + spin_lock_irqsave(&rcar_gen4_sysc_lock, flags); + + reg_idx = pdr / NUM_DOMAINS_EACH_REG; + bit_idx = pdr % NUM_DOMAINS_EACH_REG; + + isr_mask = BIT(bit_idx); + + /* + * The interrupt source needs to be enabled, but masked, to prevent the + * CPU from receiving it. + */ + iowrite32(ioread32(rcar_gen4_sysc_base + SYSCIER(reg_idx)) | isr_mask, + rcar_gen4_sysc_base + SYSCIER(reg_idx)); + iowrite32(ioread32(rcar_gen4_sysc_base + SYSCIMR(reg_idx)) | isr_mask, + rcar_gen4_sysc_base + SYSCIMR(reg_idx)); + + ret = clear_irq_flags(reg_idx, isr_mask); + if (ret) + goto out; + + /* Submit power shutoff or resume request until it was accepted */ + for (k = 0; k < PDRESR_RETRIES; k++) { + ret = rcar_gen4_sysc_pwr_on_off(pdr, on); + if (ret) + goto out; + + status = ioread32(rcar_gen4_sysc_base + PDRESR(pdr)); + if (!(status & PDRESR_ERR)) + break; + + udelay(PDRESR_DELAY_US); + } + + if (k == PDRESR_RETRIES) { + ret = -EIO; + goto out; + } + + /* Wait until the power shutoff or resume request has completed * */ + ret = readl_poll_timeout_atomic(rcar_gen4_sysc_base + SYSCISCR(reg_idx), + val, (val & isr_mask), + SYSCISR_DELAY_US, SYSCISR_TIMEOUT); + if (ret < 0) { + ret = -EIO; + goto out; + } + + /* Clear interrupt flags */ + ret = clear_irq_flags(reg_idx, isr_mask); + if (ret) + goto out; + + out: + spin_unlock_irqrestore(&rcar_gen4_sysc_lock, flags); + + pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", + pdr, ioread32(rcar_gen4_sysc_base + SYSCISCR(reg_idx)), ret); + return ret; +} + +static bool rcar_gen4_sysc_power_is_off(u8 pdr) +{ + unsigned int st; + + st = ioread32(rcar_gen4_sysc_base + PDRSR(pdr)); + + if (st & PDRSR_OFF) + return true; + + return false; +} + +struct rcar_gen4_sysc_pd { + struct generic_pm_domain genpd; + u8 pdr; + unsigned int flags; + char name[]; +}; + +static inline struct rcar_gen4_sysc_pd *to_rcar_gen4_pd(struct generic_pm_domain *d) +{ + return container_of(d, struct rcar_gen4_sysc_pd, genpd); +} + +static int rcar_gen4_sysc_pd_power_off(struct generic_pm_domain *genpd) +{ + struct rcar_gen4_sysc_pd *pd = to_rcar_gen4_pd(genpd); + + pr_debug("%s: %s\n", __func__, genpd->name); + return rcar_gen4_sysc_power(pd->pdr, false); +} + +static int rcar_gen4_sysc_pd_power_on(struct generic_pm_domain *genpd) +{ + struct rcar_gen4_sysc_pd *pd = to_rcar_gen4_pd(genpd); + + pr_debug("%s: %s\n", __func__, genpd->name); + return rcar_gen4_sysc_power(pd->pdr, true); +} + +static int __init rcar_gen4_sysc_pd_setup(struct rcar_gen4_sysc_pd *pd) +{ + struct generic_pm_domain *genpd = &pd->genpd; + const char *name = pd->genpd.name; + int error; + + if (pd->flags & PD_CPU) { + /* + * This domain contains a CPU core and therefore it should + * only be turned off if the CPU is not in use. + */ + pr_debug("PM domain %s contains %s\n", name, "CPU"); + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + } else if (pd->flags & PD_SCU) { + /* + * This domain contains an SCU and cache-controller, and + * therefore it should only be turned off if the CPU cores are + * not in use. + */ + pr_debug("PM domain %s contains %s\n", name, "SCU"); + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + } else if (pd->flags & PD_NO_CR) { + /* + * This domain cannot be turned off. + */ + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + } + + if (!(pd->flags & (PD_CPU | PD_SCU))) { + /* Enable Clock Domain for I/O devices */ + genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; + genpd->attach_dev = cpg_mssr_attach_dev; + genpd->detach_dev = cpg_mssr_detach_dev; + } + + genpd->power_off = rcar_gen4_sysc_pd_power_off; + genpd->power_on = rcar_gen4_sysc_pd_power_on; + + if (pd->flags & (PD_CPU | PD_NO_CR)) { + /* Skip CPUs (handled by SMP code) and areas without control */ + pr_debug("%s: Not touching %s\n", __func__, genpd->name); + goto finalize; + } + + if (!rcar_gen4_sysc_power_is_off(pd->pdr)) { + pr_debug("%s: %s is already powered\n", __func__, genpd->name); + goto finalize; + } + + rcar_gen4_sysc_power(pd->pdr, true); + +finalize: + error = pm_genpd_init(genpd, &simple_qos_governor, false); + if (error) + pr_err("Failed to init PM domain %s: %d\n", name, error); + + return error; +} + +static const struct of_device_id rcar_gen4_sysc_matches[] __initconst = { +#ifdef CONFIG_SYSC_R8A779A0 + { .compatible = "renesas,r8a779a0-sysc", .data = &r8a779a0_sysc_info }, +#endif + { /* sentinel */ } +}; + +struct rcar_gen4_pm_domains { + struct genpd_onecell_data onecell_data; + struct generic_pm_domain *domains[RCAR_GEN4_PD_ALWAYS_ON + 1]; +}; + +static struct genpd_onecell_data *rcar_gen4_sysc_onecell_data; + +static int __init rcar_gen4_sysc_pd_init(void) +{ + const struct rcar_gen4_sysc_info *info; + const struct of_device_id *match; + struct rcar_gen4_pm_domains *domains; + struct device_node *np; + void __iomem *base; + unsigned int i; + int error; + + np = of_find_matching_node_and_match(NULL, rcar_gen4_sysc_matches, &match); + if (!np) + return -ENODEV; + + info = match->data; + + base = of_iomap(np, 0); + if (!base) { + pr_warn("%pOF: Cannot map regs\n", np); + error = -ENOMEM; + goto out_put; + } + + rcar_gen4_sysc_base = base; + + domains = kzalloc(sizeof(*domains), GFP_KERNEL); + if (!domains) { + error = -ENOMEM; + goto out_put; + } + + domains->onecell_data.domains = domains->domains; + domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains); + rcar_gen4_sysc_onecell_data = &domains->onecell_data; + + for (i = 0; i < info->num_areas; i++) { + const struct rcar_gen4_sysc_area *area = &info->areas[i]; + struct rcar_gen4_sysc_pd *pd; + size_t n; + + if (!area->name) { + /* Skip NULLified area */ + continue; + } + + n = strlen(area->name) + 1; + pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL); + if (!pd) { + error = -ENOMEM; + goto out_put; + } + + memcpy(pd->name, area->name, n); + pd->genpd.name = pd->name; + pd->pdr = area->pdr; + pd->flags = area->flags; + + error = rcar_gen4_sysc_pd_setup(pd); + if (error) + goto out_put; + + domains->domains[area->pdr] = &pd->genpd; + + if (area->parent < 0) + continue; + + error = pm_genpd_add_subdomain(domains->domains[area->parent], + &pd->genpd); + if (error) { + pr_warn("Failed to add PM subdomain %s to parent %u\n", + area->name, area->parent); + goto out_put; + } + } + + error = of_genpd_add_provider_onecell(np, &domains->onecell_data); + +out_put: + of_node_put(np); + return error; +} +early_initcall(rcar_gen4_sysc_pd_init); diff --git a/drivers/soc/renesas/rcar-gen4-sysc.h b/drivers/soc/renesas/rcar-gen4-sysc.h new file mode 100644 index 000000000000..3470a9e2f5c7 --- /dev/null +++ b/drivers/soc/renesas/rcar-gen4-sysc.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * R-Car Gen4 System Controller + * + * Copyright (C) 2021 Renesas Electronics Corp. + */ +#ifndef __SOC_RENESAS_RCAR_GEN4_SYSC_H__ +#define __SOC_RENESAS_RCAR_GEN4_SYSC_H__ + +#include + +/* + * Power Domain flags + */ +#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_CPU_NOCR (PD_CPU | PD_NO_CR) /* CPU area lacks CR */ +#define PD_ALWAYS_ON PD_NO_CR /* Always-on area */ + +/* + * Description of a Power Area + */ +struct rcar_gen4_sysc_area { + const char *name; + u8 pdr; /* PDRn */ + int parent; /* -1 if none */ + unsigned int flags; /* See PD_* */ +}; + +/* + * SoC-specific Power Area Description + */ +struct rcar_gen4_sysc_info { + const struct rcar_gen4_sysc_area *areas; + unsigned int num_areas; +}; + +extern const struct rcar_gen4_sysc_info r8a779a0_sysc_info; + +#endif /* __SOC_RENESAS_RCAR_GEN4_SYSC_H__ */ From 654d5fdb8923994f5e79a7f0faf722958d1d759f Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:33:00 +0900 Subject: [PATCH 4/6] soc: renesas: r8a779f0-sysc: Add r8a779f0 support Add support for R-Car S4-8 (R8A779F0) SoC power areas and register access. Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-7-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/Kconfig | 4 +++ drivers/soc/renesas/Makefile | 1 + drivers/soc/renesas/r8a779f0-sysc.c | 47 ++++++++++++++++++++++++++++ drivers/soc/renesas/rcar-gen4-sysc.c | 3 ++ drivers/soc/renesas/rcar-gen4-sysc.h | 1 + 5 files changed, 56 insertions(+) create mode 100644 drivers/soc/renesas/r8a779f0-sysc.c diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 2b09d6cf0d66..59a4106a66e9 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -340,6 +340,10 @@ config SYSC_R8A77961 bool "System Controller support for R-Car M3-W+" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A779F0 + bool "System Controller support for R-Car S4-8" if COMPILE_TEST + select SYSC_RCAR_GEN4 + config SYSC_R8A7792 bool "System Controller support for R-Car V2H" if COMPILE_TEST select SYSC_RCAR diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index db90f3b06007..deeb41f84f01 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o obj-$(CONFIG_SYSC_R8A77990) += r8a77990-sysc.o obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o obj-$(CONFIG_SYSC_R8A779A0) += r8a779a0-sysc.o +obj-$(CONFIG_SYSC_R8A779F0) += r8a779f0-sysc.o ifdef CONFIG_SMP obj-$(CONFIG_ARCH_R9A06G032) += r9a06g032-smp.o endif diff --git a/drivers/soc/renesas/r8a779f0-sysc.c b/drivers/soc/renesas/r8a779f0-sysc.c new file mode 100644 index 000000000000..5602aa6bd7ed --- /dev/null +++ b/drivers/soc/renesas/r8a779f0-sysc.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas R-Car S4-8 System Controller + * + * Copyright (C) 2021 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "rcar-gen4-sysc.h" + +static struct rcar_gen4_sysc_area r8a779f0_areas[] __initdata = { + { "always-on", R8A779F0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "a3e0", R8A779F0_PD_A3E0, R8A779F0_PD_ALWAYS_ON, PD_SCU }, + { "a3e1", R8A779F0_PD_A3E1, R8A779F0_PD_ALWAYS_ON, PD_SCU }, + { "a2e0d0", R8A779F0_PD_A2E0D0, R8A779F0_PD_A3E0, PD_SCU }, + { "a2e0d1", R8A779F0_PD_A2E0D1, R8A779F0_PD_A3E0, PD_SCU }, + { "a2e1d0", R8A779F0_PD_A2E1D0, R8A779F0_PD_A3E1, PD_SCU }, + { "a2e1d1", R8A779F0_PD_A2E1D1, R8A779F0_PD_A3E1, PD_SCU }, + { "a1e0d0c0", R8A779F0_PD_A1E0D0C0, R8A779F0_PD_A2E0D0, PD_CPU_NOCR }, + { "a1e0d0c1", R8A779F0_PD_A1E0D0C1, R8A779F0_PD_A2E0D0, PD_CPU_NOCR }, + { "a1e0d1c0", R8A779F0_PD_A1E0D1C0, R8A779F0_PD_A2E0D1, PD_CPU_NOCR }, + { "a1e0d1c1", R8A779F0_PD_A1E0D1C1, R8A779F0_PD_A2E0D1, PD_CPU_NOCR }, + { "a1e1d0c0", R8A779F0_PD_A1E1D0C0, R8A779F0_PD_A2E1D0, PD_CPU_NOCR }, + { "a1e1d0c1", R8A779F0_PD_A1E1D0C1, R8A779F0_PD_A2E1D0, PD_CPU_NOCR }, + { "a1e1d1c0", R8A779F0_PD_A1E1D1C0, R8A779F0_PD_A2E1D1, PD_CPU_NOCR }, + { "a1e1d1c1", R8A779F0_PD_A1E1D1C1, R8A779F0_PD_A2E1D1, PD_CPU_NOCR }, +}; + +const struct rcar_gen4_sysc_info r8a779f0_sysc_info __initconst = { + .areas = r8a779f0_areas, + .num_areas = ARRAY_SIZE(r8a779f0_areas), +}; diff --git a/drivers/soc/renesas/rcar-gen4-sysc.c b/drivers/soc/renesas/rcar-gen4-sysc.c index d9a0929f5f1d..831162a57f9a 100644 --- a/drivers/soc/renesas/rcar-gen4-sysc.c +++ b/drivers/soc/renesas/rcar-gen4-sysc.c @@ -278,6 +278,9 @@ static int __init rcar_gen4_sysc_pd_setup(struct rcar_gen4_sysc_pd *pd) static const struct of_device_id rcar_gen4_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A779A0 { .compatible = "renesas,r8a779a0-sysc", .data = &r8a779a0_sysc_info }, +#endif +#ifdef CONFIG_SYSC_R8A779F0 + { .compatible = "renesas,r8a779f0-sysc", .data = &r8a779f0_sysc_info }, #endif { /* sentinel */ } }; diff --git a/drivers/soc/renesas/rcar-gen4-sysc.h b/drivers/soc/renesas/rcar-gen4-sysc.h index 3470a9e2f5c7..0e0bd102b1f9 100644 --- a/drivers/soc/renesas/rcar-gen4-sysc.h +++ b/drivers/soc/renesas/rcar-gen4-sysc.h @@ -38,5 +38,6 @@ struct rcar_gen4_sysc_info { }; extern const struct rcar_gen4_sysc_info r8a779a0_sysc_info; +extern const struct rcar_gen4_sysc_info r8a779f0_sysc_info; #endif /* __SOC_RENESAS_RCAR_GEN4_SYSC_H__ */ From 9711633587f4fb4376265781c75e39c2a7b21d6f Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:33:01 +0900 Subject: [PATCH 5/6] soc: renesas: Identify R-Car S4-8 Add support for identifying the R-Car S4-8 (R8A779F0) SoC. Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-8-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/Kconfig | 7 +++++++ drivers/soc/renesas/renesas-soc.c | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 59a4106a66e9..2cbd03db2cc7 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -235,6 +235,13 @@ config ARCH_R8A77961 This enables support for the Renesas R-Car M3-W+ SoC. This includes different gradings like R-Car M3e and M3e-2G. +config ARCH_R8A779F0 + bool "ARM64 Platform support for R-Car S4-8" + select ARCH_RCAR_GEN3 + select SYSC_R8A779F0 + help + This enables support for the Renesas R-Car S4-8 SoC. + config ARCH_R8A77980 bool "ARM64 Platform support for R-Car V3H" select ARCH_RCAR_GEN3 diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index dff90f504963..62540ffc581a 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -33,6 +33,10 @@ static const struct renesas_family fam_rcar_gen3 __initconst __maybe_unused = { .reg = 0xfff00044, /* PRR (Product Register) */ }; +static const struct renesas_family fam_rcar_gen4 __initconst __maybe_unused = { + .name = "R-Car Gen4", +}; + static const struct renesas_family fam_rmobile __initconst __maybe_unused = { .name = "R-Mobile", .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */ @@ -214,6 +218,11 @@ static const struct renesas_soc soc_rcar_v3u __initconst __maybe_unused = { .id = 0x59, }; +static const struct renesas_soc soc_rcar_s4 __initconst __maybe_unused = { + .family = &fam_rcar_gen4, + .id = 0x5a, +}; + static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = { .family = &fam_shmobile, .id = 0x37, @@ -319,6 +328,9 @@ static const struct of_device_id renesas_socs[] __initconst = { #ifdef CONFIG_ARCH_R8A779A0 { .compatible = "renesas,r8a779a0", .data = &soc_rcar_v3u }, #endif +#ifdef CONFIG_ARCH_R8A779F0 + { .compatible = "renesas,r8a779f0", .data = &soc_rcar_s4 }, +#endif #if defined(CONFIG_ARCH_R9A07G044) { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l }, #endif From 363b41dd25397f553bebf87594eca9b2d6445b55 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 1 Dec 2021 16:33:04 +0900 Subject: [PATCH 6/6] soc: renesas: rcar-rst: Add support for R-Car S4-8 Add support for R-Car S4-8 (R8A779F0) to the R-Car RST driver. The register map of R-Car S4-8 is the same as R-Car V3U so that renames "V3U" and "r8a779a0" to "Gen4". Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20211201073308.1003945-11-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/rcar-rst.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 1ad54e0c32e1..4d293eb2d8f3 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -66,7 +66,7 @@ static const struct rst_config rcar_rst_gen3 __initconst = { .set_rproc_boot_addr = rcar_rst_set_gen3_rproc_boot_addr, }; -static const struct rst_config rcar_rst_r8a779a0 __initconst = { +static const struct rst_config rcar_rst_gen4 __initconst = { .modemr = 0x00, /* MODEMR0 and it has CPG related bits */ }; @@ -100,8 +100,9 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a77990-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 }, - /* R-Car V3U */ - { .compatible = "renesas,r8a779a0-rst", .data = &rcar_rst_r8a779a0 }, + /* R-Car Gen4 */ + { .compatible = "renesas,r8a779a0-rst", .data = &rcar_rst_gen4 }, + { .compatible = "renesas,r8a779f0-rst", .data = &rcar_rst_gen4 }, { /* sentinel */ } };