aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@microchip.com>2017-03-14 04:38:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-30 03:41:26 -0400
commit2ab97521ce11d92f3ccca61561621214a370e2e5 (patch)
tree35f8cb4cd47937682ee40d4ee79765f063ac7ebc /arch/arm
parentca5477ad190b87ed19838c49ab8208268f47ae2c (diff)
ARM: at91: pm: cpu_idle: switch DDR to power-down mode
commit 60b89f1928af80b546b5c3fd8714a62f6f4b8844 upstream. On some DDR controllers, compatible with the sama5d3 one, the sequence to enter/exit/re-enter the self-refresh mode adds more constrains than what is currently written in the at91_idle driver. An actual access to the DDR chip is needed between exit and re-enter of this mode which is somehow difficult to implement. This sequence can completely hang the SoC. It is particularly experienced on parts which embed a L2 cache if the code run between IDLE calls fits in it... Moreover, as the intention is to enter and exit pretty rapidly from IDLE, the power-down mode is a good candidate. So now we use power-down instead of self-refresh. As we can simplify the code for sama5d3 compatible DDR controllers, we instantiate a new sama5d3_ddr_standby() function. Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> Fixes: 017b5522d5e3 ("ARM: at91: Add new binding for sama5d3-ddramc") Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-at91/pm.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index b4332b727e9c..31dde8b6f2ea 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -289,6 +289,22 @@ static void at91_ddr_standby(void)
289 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); 289 at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
290} 290}
291 291
292static void sama5d3_ddr_standby(void)
293{
294 u32 lpr0;
295 u32 saved_lpr0;
296
297 saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
298 lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
299 lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN;
300
301 at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
302
303 cpu_do_idle();
304
305 at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
306}
307
292/* We manage both DDRAM/SDRAM controllers, we need more than one value to 308/* We manage both DDRAM/SDRAM controllers, we need more than one value to
293 * remember. 309 * remember.
294 */ 310 */
@@ -323,7 +339,7 @@ static const struct of_device_id const ramc_ids[] __initconst = {
323 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, 339 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
324 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, 340 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
325 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, 341 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
326 { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, 342 { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby },
327 { /*sentinel*/ } 343 { /*sentinel*/ }
328}; 344};
329 345