diff options
author | Claudiu Beznea <claudiu.beznea@microchip.com> | 2022-01-13 17:48:54 +0300 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@microchip.com> | 2022-02-25 14:36:25 +0300 |
commit | 9584e7263e9ebcd94b184dc3efc847355a624220 (patch) | |
tree | 9c1c07f2a65d6329d072f7fcfe0965b865f282d6 /arch/arm/mach-at91 | |
parent | 9a0775c9cd3d89d1fe957a137131681a33f5736b (diff) | |
download | linux-9584e7263e9ebcd94b184dc3efc847355a624220.tar.xz |
ARM: at91: PM: add cpu idle support for sama7g5
Add CPU idle support for SAMA7G5. Support will make use of PMC_CPU_RATIO
register to divide the CPU clock by 16 before switching it to idle and
use automatic self-refresh option of DDR controller.
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Link: https://lore.kernel.org/r/20220113144900.906370-5-claudiu.beznea@microchip.com
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r-- | arch/arm/mach-at91/pm.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index dd6f4ce3f766..0fd609e26615 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void) at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); } +static void sama7g5_standby(void) +{ + int pwrtmg, ratio; + + pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL); + ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO); + + /* + * Place RAM into self-refresh after a maximum idle clocks. The maximum + * idle clocks is configured by bootloader in + * UDDRC_PWRMGT.SELFREF_TO_X32. + */ + writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN, + soc_pm.data.ramc[0] + UDDRC_PWRCTL); + /* Divide CPU clock by 16. */ + writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO); + + cpu_do_idle(); + + /* Restore previous configuration. */ + writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO); + writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL); +} + struct ramc_info { void (*idle)(void); unsigned int memctrl; @@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = { { .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC}, { .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, { .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, + { .idle = sama7g5_standby, }, }; static const struct of_device_id ramc_ids[] __initconst = { @@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = { { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] }, { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] }, { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] }, - { .compatible = "microchip,sama7g5-uddrc", }, + { .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], }, { /*sentinel*/ } }; |