1 // SPDX-License-Identifier: GPL-2.0
3 * R-Car Gen4 SYSC Power management support
5 * Copyright (C) 2021 Renesas Electronics Corp.
8 #include <linux/bits.h>
9 #include <linux/clk/renesas.h>
10 #include <linux/delay.h>
11 #include <linux/err.h>
13 #include <linux/iopoll.h>
14 #include <linux/kernel.h>
16 #include <linux/of_address.h>
17 #include <linux/pm_domain.h>
18 #include <linux/slab.h>
19 #include <linux/spinlock.h>
20 #include <linux/types.h>
22 #include "rcar-gen4-sysc.h"
25 #define SYSCSR 0x000 /* SYSC Status Register */
26 #define SYSCPONSR(x) (0x800 + ((x) * 0x4)) /* Power-ON Status Register 0 */
27 #define SYSCPOFFSR(x) (0x808 + ((x) * 0x4)) /* Power-OFF Status Register */
28 #define SYSCISCR(x) (0x810 + ((x) * 0x4)) /* Interrupt Status/Clear Register */
29 #define SYSCIER(x) (0x820 + ((x) * 0x4)) /* Interrupt Enable Register */
30 #define SYSCIMR(x) (0x830 + ((x) * 0x4)) /* Interrupt Mask Register */
32 /* Power Domain Registers */
33 #define PDRSR(n) (0x1000 + ((n) * 0x40))
34 #define PDRONCR(n) (0x1004 + ((n) * 0x40))
35 #define PDROFFCR(n) (0x1008 + ((n) * 0x40))
36 #define PDRESR(n) (0x100C + ((n) * 0x40))
39 #define PWRON_PWROFF BIT(0) /* Power-ON/OFF request */
42 #define PDRESR_ERR BIT(0)
45 #define PDRSR_OFF BIT(0) /* Power-OFF state */
46 #define PDRSR_ON BIT(4) /* Power-ON state */
47 #define PDRSR_OFF_STATE BIT(8) /* Processing Power-OFF sequence */
48 #define PDRSR_ON_STATE BIT(12) /* Processing Power-ON sequence */
50 #define SYSCSR_BUSY GENMASK(1, 0) /* All bit sets is not busy */
52 #define SYSCSR_TIMEOUT 10000
53 #define SYSCSR_DELAY_US 1
55 #define PDRESR_RETRIES 10000
56 #define PDRESR_DELAY_US 1
58 #define SYSCISCR_TIMEOUT 10000
59 #define SYSCISCR_DELAY_US 1
61 #define RCAR_GEN4_PD_ALWAYS_ON 64
62 #define NUM_DOMAINS_EACH_REG BITS_PER_TYPE(u32)
64 static void __iomem
*rcar_gen4_sysc_base
;
65 static DEFINE_SPINLOCK(rcar_gen4_sysc_lock
); /* SMP CPUs + I/O devices */
67 static int rcar_gen4_sysc_pwr_on_off(u8 pdr
, bool on
)
69 unsigned int reg_offs
;
74 reg_offs
= PDRONCR(pdr
);
76 reg_offs
= PDROFFCR(pdr
);
78 /* Wait until SYSC is ready to accept a power request */
79 ret
= readl_poll_timeout_atomic(rcar_gen4_sysc_base
+ SYSCSR
, val
,
80 (val
& SYSCSR_BUSY
) == SYSCSR_BUSY
,
81 SYSCSR_DELAY_US
, SYSCSR_TIMEOUT
);
85 /* Submit power shutoff or power resume request */
86 iowrite32(PWRON_PWROFF
, rcar_gen4_sysc_base
+ reg_offs
);
91 static int clear_irq_flags(unsigned int reg_idx
, unsigned int isr_mask
)
96 iowrite32(isr_mask
, rcar_gen4_sysc_base
+ SYSCISCR(reg_idx
));
98 ret
= readl_poll_timeout_atomic(rcar_gen4_sysc_base
+ SYSCISCR(reg_idx
),
99 val
, !(val
& isr_mask
),
100 SYSCISCR_DELAY_US
, SYSCISCR_TIMEOUT
);
102 pr_err("\n %s : Can not clear IRQ flags in SYSCISCR", __func__
);
109 static int rcar_gen4_sysc_power(u8 pdr
, bool on
)
111 unsigned int isr_mask
;
112 unsigned int reg_idx
, bit_idx
;
119 spin_lock_irqsave(&rcar_gen4_sysc_lock
, flags
);
121 reg_idx
= pdr
/ NUM_DOMAINS_EACH_REG
;
122 bit_idx
= pdr
% NUM_DOMAINS_EACH_REG
;
124 isr_mask
= BIT(bit_idx
);
127 * The interrupt source needs to be enabled, but masked, to prevent the
128 * CPU from receiving it.
130 iowrite32(ioread32(rcar_gen4_sysc_base
+ SYSCIER(reg_idx
)) | isr_mask
,
131 rcar_gen4_sysc_base
+ SYSCIER(reg_idx
));
132 iowrite32(ioread32(rcar_gen4_sysc_base
+ SYSCIMR(reg_idx
)) | isr_mask
,
133 rcar_gen4_sysc_base
+ SYSCIMR(reg_idx
));
135 ret
= clear_irq_flags(reg_idx
, isr_mask
);
139 /* Submit power shutoff or resume request until it was accepted */
140 for (k
= 0; k
< PDRESR_RETRIES
; k
++) {
141 ret
= rcar_gen4_sysc_pwr_on_off(pdr
, on
);
145 status
= ioread32(rcar_gen4_sysc_base
+ PDRESR(pdr
));
146 if (!(status
& PDRESR_ERR
))
149 udelay(PDRESR_DELAY_US
);
152 if (k
== PDRESR_RETRIES
) {
157 /* Wait until the power shutoff or resume request has completed * */
158 ret
= readl_poll_timeout_atomic(rcar_gen4_sysc_base
+ SYSCISCR(reg_idx
),
159 val
, (val
& isr_mask
),
160 SYSCISCR_DELAY_US
, SYSCISCR_TIMEOUT
);
166 /* Clear interrupt flags */
167 ret
= clear_irq_flags(reg_idx
, isr_mask
);
172 spin_unlock_irqrestore(&rcar_gen4_sysc_lock
, flags
);
174 pr_debug("sysc power %s domain %d: %08x -> %d\n", on
? "on" : "off",
175 pdr
, ioread32(rcar_gen4_sysc_base
+ SYSCISCR(reg_idx
)), ret
);
179 static bool rcar_gen4_sysc_power_is_off(u8 pdr
)
183 st
= ioread32(rcar_gen4_sysc_base
+ PDRSR(pdr
));
191 struct rcar_gen4_sysc_pd
{
192 struct generic_pm_domain genpd
;
198 static inline struct rcar_gen4_sysc_pd
*to_rcar_gen4_pd(struct generic_pm_domain
*d
)
200 return container_of(d
, struct rcar_gen4_sysc_pd
, genpd
);
203 static int rcar_gen4_sysc_pd_power_off(struct generic_pm_domain
*genpd
)
205 struct rcar_gen4_sysc_pd
*pd
= to_rcar_gen4_pd(genpd
);
207 pr_debug("%s: %s\n", __func__
, genpd
->name
);
208 return rcar_gen4_sysc_power(pd
->pdr
, false);
211 static int rcar_gen4_sysc_pd_power_on(struct generic_pm_domain
*genpd
)
213 struct rcar_gen4_sysc_pd
*pd
= to_rcar_gen4_pd(genpd
);
215 pr_debug("%s: %s\n", __func__
, genpd
->name
);
216 return rcar_gen4_sysc_power(pd
->pdr
, true);
219 static int __init
rcar_gen4_sysc_pd_setup(struct rcar_gen4_sysc_pd
*pd
)
221 struct generic_pm_domain
*genpd
= &pd
->genpd
;
222 const char *name
= pd
->genpd
.name
;
225 if (pd
->flags
& PD_CPU
) {
227 * This domain contains a CPU core and therefore it should
228 * only be turned off if the CPU is not in use.
230 pr_debug("PM domain %s contains %s\n", name
, "CPU");
231 genpd
->flags
|= GENPD_FLAG_ALWAYS_ON
;
232 } else if (pd
->flags
& PD_SCU
) {
234 * This domain contains an SCU and cache-controller, and
235 * therefore it should only be turned off if the CPU cores are
238 pr_debug("PM domain %s contains %s\n", name
, "SCU");
239 genpd
->flags
|= GENPD_FLAG_ALWAYS_ON
;
240 } else if (pd
->flags
& PD_NO_CR
) {
242 * This domain cannot be turned off.
244 genpd
->flags
|= GENPD_FLAG_ALWAYS_ON
;
247 if (!(pd
->flags
& (PD_CPU
| PD_SCU
))) {
248 /* Enable Clock Domain for I/O devices */
249 genpd
->flags
|= GENPD_FLAG_PM_CLK
| GENPD_FLAG_ACTIVE_WAKEUP
;
250 genpd
->attach_dev
= cpg_mssr_attach_dev
;
251 genpd
->detach_dev
= cpg_mssr_detach_dev
;
254 genpd
->power_off
= rcar_gen4_sysc_pd_power_off
;
255 genpd
->power_on
= rcar_gen4_sysc_pd_power_on
;
257 if (pd
->flags
& (PD_CPU
| PD_NO_CR
)) {
258 /* Skip CPUs (handled by SMP code) and areas without control */
259 pr_debug("%s: Not touching %s\n", __func__
, genpd
->name
);
263 if (!rcar_gen4_sysc_power_is_off(pd
->pdr
)) {
264 pr_debug("%s: %s is already powered\n", __func__
, genpd
->name
);
268 rcar_gen4_sysc_power(pd
->pdr
, true);
271 error
= pm_genpd_init(genpd
, &simple_qos_governor
, false);
273 pr_err("Failed to init PM domain %s: %d\n", name
, error
);
278 static const struct of_device_id rcar_gen4_sysc_matches
[] __initconst
= {
279 #ifdef CONFIG_SYSC_R8A779A0
280 { .compatible
= "renesas,r8a779a0-sysc", .data
= &r8a779a0_sysc_info
},
282 #ifdef CONFIG_SYSC_R8A779F0
283 { .compatible
= "renesas,r8a779f0-sysc", .data
= &r8a779f0_sysc_info
},
285 #ifdef CONFIG_SYSC_R8A779G0
286 { .compatible
= "renesas,r8a779g0-sysc", .data
= &r8a779g0_sysc_info
},
288 #ifdef CONFIG_SYSC_R8A779H0
289 { .compatible
= "renesas,r8a779h0-sysc", .data
= &r8a779h0_sysc_info
},
294 struct rcar_gen4_pm_domains
{
295 struct genpd_onecell_data onecell_data
;
296 struct generic_pm_domain
*domains
[RCAR_GEN4_PD_ALWAYS_ON
+ 1];
299 static struct genpd_onecell_data
*rcar_gen4_sysc_onecell_data
;
301 static int __init
rcar_gen4_sysc_pd_init(void)
303 const struct rcar_gen4_sysc_info
*info
;
304 const struct of_device_id
*match
;
305 struct rcar_gen4_pm_domains
*domains
;
306 struct device_node
*np
;
311 np
= of_find_matching_node_and_match(NULL
, rcar_gen4_sysc_matches
, &match
);
317 base
= of_iomap(np
, 0);
319 pr_warn("%pOF: Cannot map regs\n", np
);
324 rcar_gen4_sysc_base
= base
;
326 domains
= kzalloc(sizeof(*domains
), GFP_KERNEL
);
332 domains
->onecell_data
.domains
= domains
->domains
;
333 domains
->onecell_data
.num_domains
= ARRAY_SIZE(domains
->domains
);
334 rcar_gen4_sysc_onecell_data
= &domains
->onecell_data
;
336 for (i
= 0; i
< info
->num_areas
; i
++) {
337 const struct rcar_gen4_sysc_area
*area
= &info
->areas
[i
];
338 struct rcar_gen4_sysc_pd
*pd
;
342 /* Skip NULLified area */
346 n
= strlen(area
->name
) + 1;
347 pd
= kzalloc(sizeof(*pd
) + n
, GFP_KERNEL
);
353 memcpy(pd
->name
, area
->name
, n
);
354 pd
->genpd
.name
= pd
->name
;
356 pd
->flags
= area
->flags
;
358 error
= rcar_gen4_sysc_pd_setup(pd
);
362 domains
->domains
[area
->pdr
] = &pd
->genpd
;
364 if (area
->parent
< 0)
367 error
= pm_genpd_add_subdomain(domains
->domains
[area
->parent
],
370 pr_warn("Failed to add PM subdomain %s to parent %u\n",
371 area
->name
, area
->parent
);
376 error
= of_genpd_add_provider_onecell(np
, &domains
->onecell_data
);
382 early_initcall(rcar_gen4_sysc_pd_init
);