Lines Matching +full:turned +full:- +full:off
1 // SPDX-License-Identifier: GPL-2.0
3 * R-Car SYSC Power management support
6 * Copyright (C) 2015-2017 Glider bvba
19 #include <linux/soc/renesas/rcar-sysc.h>
21 #include "rcar-sysc.h"
37 * Use WFI to power off, CPG/APMU to resume ARM cores on R-Car Gen2
38 * Use PSCI on R-Car Gen3
57 #define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
91 return -EAGAIN; in rcar_sysc_pwr_on_off()
93 /* Power-off delay quirk */ in rcar_sysc_pwr_on_off()
94 if (!on && (pd->flags & PD_OFF_DELAY)) in rcar_sysc_pwr_on_off()
98 iowrite32(BIT(pd->chan_bit), rcar_sysc_base + pd->chan_offs + reg_offs); in rcar_sysc_pwr_on_off()
105 unsigned int isr_mask = BIT(pd->isr_bit); in rcar_sysc_power()
106 unsigned int chan_mask = BIT(pd->chan_bit); in rcar_sysc_power()
138 status = ioread32(rcar_sysc_base + pd->chan_offs + PWRER_OFFS); in rcar_sysc_power()
146 ret = -EIO; in rcar_sysc_power()
155 ret = -EIO; in rcar_sysc_power()
165 pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", in rcar_sysc_power()
166 pd->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret); in rcar_sysc_power()
174 st = ioread32(rcar_sysc_base + pd->chan_offs + PWRSR_OFFS); in rcar_sysc_power_is_off()
175 if (st & BIT(pd->chan_bit)) in rcar_sysc_power_is_off()
190 pr_debug("%s: %s\n", __func__, genpd->name); in rcar_sysc_pd_power_off()
198 pr_debug("%s: %s\n", __func__, genpd->name); in rcar_sysc_pd_power_on()
206 struct generic_pm_domain *genpd = &pd->genpd; in rcar_sysc_pd_setup()
207 const char *name = pd->genpd.name; in rcar_sysc_pd_setup()
210 if (pd->flags & PD_CPU) { in rcar_sysc_pd_setup()
213 * only be turned off if the CPU is not in use. in rcar_sysc_pd_setup()
216 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
217 } else if (pd->flags & PD_SCU) { in rcar_sysc_pd_setup()
219 * This domain contains an SCU and cache-controller, and in rcar_sysc_pd_setup()
220 * therefore it should only be turned off if the CPU cores are in rcar_sysc_pd_setup()
224 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
225 } else if (pd->flags & PD_NO_CR) { in rcar_sysc_pd_setup()
227 * This domain cannot be turned off. in rcar_sysc_pd_setup()
229 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
232 if (!(pd->flags & (PD_CPU | PD_SCU))) { in rcar_sysc_pd_setup()
234 genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; in rcar_sysc_pd_setup()
236 genpd->attach_dev = cpg_mstp_attach_dev; in rcar_sysc_pd_setup()
237 genpd->detach_dev = cpg_mstp_detach_dev; in rcar_sysc_pd_setup()
239 genpd->attach_dev = cpg_mssr_attach_dev; in rcar_sysc_pd_setup()
240 genpd->detach_dev = cpg_mssr_detach_dev; in rcar_sysc_pd_setup()
244 genpd->power_off = rcar_sysc_pd_power_off; in rcar_sysc_pd_setup()
245 genpd->power_on = rcar_sysc_pd_power_on; in rcar_sysc_pd_setup()
247 if (pd->flags & (PD_CPU | PD_NO_CR)) { in rcar_sysc_pd_setup()
249 pr_debug("%s: Not touching %s\n", __func__, genpd->name); in rcar_sysc_pd_setup()
254 pr_debug("%s: %s is already powered\n", __func__, genpd->name); in rcar_sysc_pd_setup()
270 { .compatible = "renesas,r8a7742-sysc", .data = &r8a7742_sysc_info },
273 { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
275 { .compatible = "renesas,r8a7744-sysc", .data = &r8a7743_sysc_info },
278 { .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
281 { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info },
284 { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info },
287 { .compatible = "renesas,r8a774b1-sysc", .data = &r8a774b1_sysc_info },
290 { .compatible = "renesas,r8a774c0-sysc", .data = &r8a774c0_sysc_info },
293 { .compatible = "renesas,r8a774e1-sysc", .data = &r8a774e1_sysc_info },
296 { .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
299 { .compatible = "renesas,r8a7790-sysc", .data = &r8a7790_sysc_info },
302 { .compatible = "renesas,r8a7791-sysc", .data = &r8a7791_sysc_info },
303 /* R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. */
304 { .compatible = "renesas,r8a7793-sysc", .data = &r8a7791_sysc_info },
307 { .compatible = "renesas,r8a7792-sysc", .data = &r8a7792_sysc_info },
310 { .compatible = "renesas,r8a7794-sysc", .data = &r8a7794_sysc_info },
313 { .compatible = "renesas,r8a7795-sysc", .data = &r8a7795_sysc_info },
316 { .compatible = "renesas,r8a7796-sysc", .data = &r8a77960_sysc_info },
319 { .compatible = "renesas,r8a77961-sysc", .data = &r8a77961_sysc_info },
322 { .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
325 { .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info },
328 { .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info },
331 { .compatible = "renesas,r8a77990-sysc", .data = &r8a77990_sysc_info },
334 { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
358 return -ENODEV; in rcar_sysc_pd_init()
360 info = match->data; in rcar_sysc_pd_init()
362 if (info->init) { in rcar_sysc_pd_init()
363 error = info->init(); in rcar_sysc_pd_init()
369 "renesas,cpg-mstp-clocks"); in rcar_sysc_pd_init()
374 error = -ENOMEM; in rcar_sysc_pd_init()
381 rcar_sysc_extmask_offs = info->extmask_offs; in rcar_sysc_pd_init()
382 rcar_sysc_extmask_val = info->extmask_val; in rcar_sysc_pd_init()
386 error = -ENOMEM; in rcar_sysc_pd_init()
390 domains->onecell_data.domains = domains->domains; in rcar_sysc_pd_init()
391 domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains); in rcar_sysc_pd_init()
392 rcar_sysc_onecell_data = &domains->onecell_data; in rcar_sysc_pd_init()
394 for (i = 0; i < info->num_areas; i++) { in rcar_sysc_pd_init()
395 const struct rcar_sysc_area *area = &info->areas[i]; in rcar_sysc_pd_init()
399 if (!area->name) { in rcar_sysc_pd_init()
404 n = strlen(area->name) + 1; in rcar_sysc_pd_init()
407 error = -ENOMEM; in rcar_sysc_pd_init()
411 memcpy(pd->name, area->name, n); in rcar_sysc_pd_init()
412 pd->genpd.name = pd->name; in rcar_sysc_pd_init()
413 pd->chan_offs = area->chan_offs; in rcar_sysc_pd_init()
414 pd->chan_bit = area->chan_bit; in rcar_sysc_pd_init()
415 pd->isr_bit = area->isr_bit; in rcar_sysc_pd_init()
416 pd->flags = area->flags; in rcar_sysc_pd_init()
422 domains->domains[area->isr_bit] = &pd->genpd; in rcar_sysc_pd_init()
424 if (area->parent < 0) in rcar_sysc_pd_init()
427 error = pm_genpd_add_subdomain(domains->domains[area->parent], in rcar_sysc_pd_init()
428 &pd->genpd); in rcar_sysc_pd_init()
431 area->name, area->parent); in rcar_sysc_pd_init()
436 error = of_genpd_add_provider_onecell(np, &domains->onecell_data); in rcar_sysc_pd_init()
454 return -ENODEV; in rcar_sysc_power_cpu()
456 for (i = 0; i < rcar_sysc_onecell_data->num_domains; i++) { in rcar_sysc_power_cpu()
457 genpd = rcar_sysc_onecell_data->domains[i]; in rcar_sysc_power_cpu()
462 if (!(pd->flags & PD_CPU) || pd->chan_bit != idx) in rcar_sysc_power_cpu()
468 return -ENOENT; in rcar_sysc_power_cpu()