Commit 2c4b0c05 authored by Jimmy Brisson's avatar Jimmy Brisson Committed by Julius Werner
Browse files

fix(rk3399/suspend): correct LPDDR4 resume sequence



This change adds 208 bytes to PMUSRAM, pushing the end of text from
0xff3b0de0 to 0xff3b0eb0, which is still shy of the maximum
0xff3b1000.

Further, this skips enabling the watchdog when it's not being used
elsewhere, as you can't turn the watchdog off.

Change-Id: I2e6fa3c7e01f2be6b32ce04ce479edf64e278554
Signed-off-by: default avatarJimmy Brisson <jimmy.brisson@arm.com>
parent c8861f9f
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -49,6 +49,7 @@
__pmusramdata uint32_t dpll_data[PLL_CON_COUNT];
__pmusramdata uint32_t cru_clksel_con6;
__pmusramdata uint8_t pmu_enable_watchdog0;
/*
* Copy @num registers from @src to @dst
......@@ -562,8 +563,14 @@ static __pmusramfunc int dram_switch_to_next_index(
/* LPDDR4 f2 cann't do training, all training will fail */
for (ch = 0; ch < ch_count; ch++) {
mmio_clrsetbits_32(PHY_REG(ch, 896), (0x3 << 8) | 1,
fn << 8);
/*
* Without this disabled for LPDDR4 we end up writing 0's
* in place of real data in an interesting pattern.
*/
if (sdram_params->dramtype != LPDDR4) {
mmio_clrsetbits_32(PHY_REG(ch, 896), (0x3 << 8) | 1,
fn << 8);
}
/* data_training failed */
if (data_training(ch, sdram_params, PI_FULL_TRAINING))
......@@ -748,13 +755,44 @@ void dmc_suspend(void)
phy_regs->phy896[0] &= ~(0x3 << 8);
}
__pmusramfunc void phy_dll_bypass_set(uint32_t ch, uint32_t freq)
{
if (freq <= (125 * 1000 * 1000)) {
/* Set master mode to SW for slices*/
mmio_setbits_32(PHY_REG(ch, 86), 3 << 10);
mmio_setbits_32(PHY_REG(ch, 214), 3 << 10);
mmio_setbits_32(PHY_REG(ch, 342), 3 << 10);
mmio_setbits_32(PHY_REG(ch, 470), 3 << 10);
/* Set master mode to SW for address slices*/
mmio_setbits_32(PHY_REG(ch, 547), 3 << 18);
mmio_setbits_32(PHY_REG(ch, 675), 3 << 18);
mmio_setbits_32(PHY_REG(ch, 803), 3 << 18);
} else {
/* Clear SW master mode for slices*/
mmio_clrbits_32(PHY_REG(ch, 86), 3 << 10);
mmio_clrbits_32(PHY_REG(ch, 214), 3 << 10);
mmio_clrbits_32(PHY_REG(ch, 342), 3 << 10);
mmio_clrbits_32(PHY_REG(ch, 470), 3 << 10);
/* Clear SW master mode for address slices*/
mmio_clrbits_32(PHY_REG(ch, 547), 3 << 18);
mmio_clrbits_32(PHY_REG(ch, 675), 3 << 18);
mmio_clrbits_32(PHY_REG(ch, 803), 3 << 18);
}
}
__pmusramfunc void dmc_resume(void)
{
struct rk3399_sdram_params *sdram_params = &sdram_config;
uint32_t channel_mask = 0;
uint32_t channel;
pmusram_enable_watchdog();
/*
* We can't turn off the watchdog, so if we have not turned it on before
* we should not turn it on here.
*/
if ((pmu_enable_watchdog0 & 0x1) == 0x1) {
pmusram_enable_watchdog();
}
pmu_sgrf_rst_hld_release();
restore_pmu_rsthold();
sram_secure_timer_init();
......@@ -772,6 +810,13 @@ __pmusramfunc void dmc_resume(void)
retry:
for (channel = 0; channel < sdram_params->num_channels; channel++) {
phy_pctrl_reset(channel);
/*
* Without this, LPDDR4 will write 0's in place of real data
* in a strange pattern.
*/
if (sdram_params->dramtype == LPDDR4) {
phy_dll_bypass_set(channel, sdram_params->ddr_freq);
}
pctl_cfg(channel, sdram_params);
}
......@@ -788,8 +833,12 @@ retry:
if (sdram_params->dramtype == LPDDR3)
sram_udelay(10);
/* If traning fail, retry to do it again. */
if (data_training(channel, sdram_params, PI_FULL_TRAINING))
/*
* Training here will always fail for LPDDR4, so skip it
* If traning fail, retry to do it again.
*/
if (sdram_params->dramtype != LPDDR4 &&
data_training(channel, sdram_params, PI_FULL_TRAINING))
goto retry;
set_ddrconfig(sdram_params, channel,
......
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -7,6 +7,7 @@
#ifndef SUSPEND_H
#define SUSPEND_H
#include <stdint.h>
#include <dram.h>
#define KHz (1000)
......@@ -22,5 +23,6 @@
void dmc_suspend(void);
__pmusramfunc void dmc_resume(void);
extern __pmusramdata uint8_t pmu_enable_watchdog0;
#endif /* SUSPEND_H */
/*
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -1324,6 +1324,7 @@ void wdt_register_save(void)
store_wdt0[i] = mmio_read_32(WDT0_BASE + i * 4);
store_wdt1[i] = mmio_read_32(WDT1_BASE + i * 4);
}
pmu_enable_watchdog0 = (uint8_t) store_wdt0[0] & 0x1;
}
void wdt_register_restore(void)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment