mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
128 lines
4.2 KiB
Diff
128 lines
4.2 KiB
Diff
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.
|
|
|
|
Unofficial patch made from:
|
|
|
|
Change-Id: I2e6fa3c7e01f2be6b32ce04ce479edf64e278554
|
|
Signed-off-by: Jimmy Brisson <jimmy.brisson@arm.com>
|
|
---
|
|
plat/rockchip/rk3399/drivers/dram/suspend.c | 57 ++++++++++++++++++---
|
|
1 file changed, 51 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c
|
|
index 7f9fad1..dc2c16b 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
|
|
*/
|
|
@@ -562,8 +562,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))
|
|
@@ -660,6 +666,7 @@ __pmusramfunc static void pmusram_restore_pll(int pll_id, uint32_t *src)
|
|
;
|
|
}
|
|
|
|
+__attribute__((unused))
|
|
__pmusramfunc static void pmusram_enable_watchdog(void)
|
|
{
|
|
/* Make the watchdog use the first global reset. */
|
|
@@ -748,13 +755,40 @@ 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();
|
|
+ /*
|
|
+ * Note: I would love to enable the watchdog, but as it turns out,
|
|
+ * resume with LPDDR4 crashes, because of the watchdog ATM.
|
|
+ */
|
|
pmu_sgrf_rst_hld_release();
|
|
restore_pmu_rsthold();
|
|
sram_secure_timer_init();
|
|
@@ -772,6 +806,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 +829,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,
|
|
--
|
|
Created with Armbian build tools https://github.com/armbian/build
|
|
|