Lines Matching +full:r8a7791 +full:- +full:apmu
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 */
88 return -EAGAIN; in rcar_sysc_pwr_on_off()
91 iowrite32(BIT(sysc_ch->chan_bit), in rcar_sysc_pwr_on_off()
92 rcar_sysc_base + sysc_ch->chan_offs + reg_offs); in rcar_sysc_pwr_on_off()
99 unsigned int isr_mask = BIT(sysc_ch->isr_bit); in rcar_sysc_power()
100 unsigned int chan_mask = BIT(sysc_ch->chan_bit); in rcar_sysc_power()
133 sysc_ch->chan_offs + PWRER_OFFS); in rcar_sysc_power()
141 ret = -EIO; in rcar_sysc_power()
150 ret = -EIO; in rcar_sysc_power()
160 pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off", in rcar_sysc_power()
161 sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret); in rcar_sysc_power()
169 st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS); in rcar_sysc_power_is_off()
170 if (st & BIT(sysc_ch->chan_bit)) in rcar_sysc_power_is_off()
192 pr_debug("%s: %s\n", __func__, genpd->name); in rcar_sysc_pd_power_off()
193 return rcar_sysc_power(&pd->ch, false); in rcar_sysc_pd_power_off()
200 pr_debug("%s: %s\n", __func__, genpd->name); in rcar_sysc_pd_power_on()
201 return rcar_sysc_power(&pd->ch, true); in rcar_sysc_pd_power_on()
208 struct generic_pm_domain *genpd = &pd->genpd; in rcar_sysc_pd_setup()
209 const char *name = pd->genpd.name; in rcar_sysc_pd_setup()
212 if (pd->flags & PD_CPU) { in rcar_sysc_pd_setup()
218 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
219 } else if (pd->flags & PD_SCU) { in rcar_sysc_pd_setup()
221 * This domain contains an SCU and cache-controller, and in rcar_sysc_pd_setup()
226 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
227 } else if (pd->flags & PD_NO_CR) { in rcar_sysc_pd_setup()
231 genpd->flags |= GENPD_FLAG_ALWAYS_ON; in rcar_sysc_pd_setup()
234 if (!(pd->flags & (PD_CPU | PD_SCU))) { in rcar_sysc_pd_setup()
236 genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; in rcar_sysc_pd_setup()
238 genpd->attach_dev = cpg_mstp_attach_dev; in rcar_sysc_pd_setup()
239 genpd->detach_dev = cpg_mstp_detach_dev; in rcar_sysc_pd_setup()
241 genpd->attach_dev = cpg_mssr_attach_dev; in rcar_sysc_pd_setup()
242 genpd->detach_dev = cpg_mssr_detach_dev; in rcar_sysc_pd_setup()
246 genpd->power_off = rcar_sysc_pd_power_off; in rcar_sysc_pd_setup()
247 genpd->power_on = rcar_sysc_pd_power_on; in rcar_sysc_pd_setup()
249 if (pd->flags & (PD_CPU | PD_NO_CR)) { in rcar_sysc_pd_setup()
251 pr_debug("%s: Not touching %s\n", __func__, genpd->name); in rcar_sysc_pd_setup()
255 if (!rcar_sysc_power_is_off(&pd->ch)) { in rcar_sysc_pd_setup()
256 pr_debug("%s: %s is already powered\n", __func__, genpd->name); in rcar_sysc_pd_setup()
260 rcar_sysc_power(&pd->ch, true); in rcar_sysc_pd_setup()
272 { .compatible = "renesas,r8a7742-sysc", .data = &r8a7742_sysc_info },
275 { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
277 { .compatible = "renesas,r8a7744-sysc", .data = &r8a7743_sysc_info },
280 { .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
283 { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info },
286 { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info },
289 { .compatible = "renesas,r8a774b1-sysc", .data = &r8a774b1_sysc_info },
292 { .compatible = "renesas,r8a774c0-sysc", .data = &r8a774c0_sysc_info },
295 { .compatible = "renesas,r8a774e1-sysc", .data = &r8a774e1_sysc_info },
298 { .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
301 { .compatible = "renesas,r8a7790-sysc", .data = &r8a7790_sysc_info },
304 { .compatible = "renesas,r8a7791-sysc", .data = &r8a7791_sysc_info },
305 /* R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. */
306 { .compatible = "renesas,r8a7793-sysc", .data = &r8a7791_sysc_info },
309 { .compatible = "renesas,r8a7792-sysc", .data = &r8a7792_sysc_info },
312 { .compatible = "renesas,r8a7794-sysc", .data = &r8a7794_sysc_info },
315 { .compatible = "renesas,r8a7795-sysc", .data = &r8a7795_sysc_info },
318 { .compatible = "renesas,r8a7796-sysc", .data = &r8a77960_sysc_info },
321 { .compatible = "renesas,r8a77961-sysc", .data = &r8a77961_sysc_info },
324 { .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
327 { .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info },
330 { .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info },
333 { .compatible = "renesas,r8a77990-sysc", .data = &r8a77990_sysc_info },
336 { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
360 return -ENODEV; in rcar_sysc_pd_init()
362 info = match->data; in rcar_sysc_pd_init()
364 if (info->init) { in rcar_sysc_pd_init()
365 error = info->init(); in rcar_sysc_pd_init()
371 "renesas,cpg-mstp-clocks"); in rcar_sysc_pd_init()
376 error = -ENOMEM; in rcar_sysc_pd_init()
383 rcar_sysc_extmask_offs = info->extmask_offs; in rcar_sysc_pd_init()
384 rcar_sysc_extmask_val = info->extmask_val; in rcar_sysc_pd_init()
388 error = -ENOMEM; in rcar_sysc_pd_init()
392 domains->onecell_data.domains = domains->domains; in rcar_sysc_pd_init()
393 domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains); in rcar_sysc_pd_init()
394 rcar_sysc_onecell_data = &domains->onecell_data; in rcar_sysc_pd_init()
396 for (i = 0; i < info->num_areas; i++) { in rcar_sysc_pd_init()
397 const struct rcar_sysc_area *area = &info->areas[i]; in rcar_sysc_pd_init()
401 if (!area->name) { in rcar_sysc_pd_init()
406 n = strlen(area->name) + 1; in rcar_sysc_pd_init()
409 error = -ENOMEM; in rcar_sysc_pd_init()
413 memcpy(pd->name, area->name, n); in rcar_sysc_pd_init()
414 pd->genpd.name = pd->name; in rcar_sysc_pd_init()
415 pd->ch.chan_offs = area->chan_offs; in rcar_sysc_pd_init()
416 pd->ch.chan_bit = area->chan_bit; in rcar_sysc_pd_init()
417 pd->ch.isr_bit = area->isr_bit; in rcar_sysc_pd_init()
418 pd->flags = area->flags; in rcar_sysc_pd_init()
424 domains->domains[area->isr_bit] = &pd->genpd; in rcar_sysc_pd_init()
426 if (area->parent < 0) in rcar_sysc_pd_init()
429 error = pm_genpd_add_subdomain(domains->domains[area->parent], in rcar_sysc_pd_init()
430 &pd->genpd); in rcar_sysc_pd_init()
433 area->name, area->parent); in rcar_sysc_pd_init()
438 error = of_genpd_add_provider_onecell(np, &domains->onecell_data); in rcar_sysc_pd_init()
468 return -ENODEV; in rcar_sysc_power_cpu()
470 for (i = 0; i < rcar_sysc_onecell_data->num_domains; i++) { in rcar_sysc_power_cpu()
471 genpd = rcar_sysc_onecell_data->domains[i]; in rcar_sysc_power_cpu()
476 if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx) in rcar_sysc_power_cpu()
479 return rcar_sysc_power(&pd->ch, on); in rcar_sysc_power_cpu()
482 return -ENOENT; in rcar_sysc_power_cpu()