aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Brisson <jimmy.brisson@arm.com>2020-06-29 12:21:23 -0500
committerJulius Werner <jwerner@chromium.org>2021-07-19 23:06:33 +0200
commit2c4b0c05c6546e24eb7209ffb3bb465d4feed164 (patch)
tree8c48b2ed97d748bfb772a547b0a24e27f5e5343d
parentc8861f9f424046d878762403e85fa72c24befd89 (diff)
downloadtrusted-firmware-a-2c4b0c05c6546e24eb7209ffb3bb465d4feed164.tar.gz
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: Jimmy Brisson <jimmy.brisson@arm.com>
-rw-r--r--plat/rockchip/rk3399/drivers/dram/suspend.c61
-rw-r--r--plat/rockchip/rk3399/drivers/dram/suspend.h4
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu.c3
3 files changed, 60 insertions, 8 deletions
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c
index 7f9fad10e2..a8b1c32d5a 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.c
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.c
@@ -1,5 +1,5 @@
/*
- * 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,
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.h b/plat/rockchip/rk3399/drivers/dram/suspend.h
index b99a9262f4..13899444fb 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.h
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.h
@@ -1,5 +1,5 @@
/*
- * 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 */
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index faee6787dd..3084c4f2fd 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -1,5 +1,5 @@
/*
- * 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)