mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-09 03:21:51 +00:00
fsl/sleep: updated the deep sleep framework for QorIQ platforms
With the introducing of generic board and ARM-based cores, current deep sleep framework doesn't work anymore. This patch will convert the current framework to adapt this change. Basically it does: 1. Converts all the Freescale's DDR driver to support deep sleep. 2. Added basic framework support for ARM-based and PPC-based cores separately. Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com> Reviewed-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
da5ce448c7
commit
a7787b7850
8 changed files with 322 additions and 56 deletions
|
@ -37,6 +37,12 @@ endif
|
||||||
|
|
||||||
obj-$(CONFIG_FSL_DIU_CH7301) += diu_ch7301.o
|
obj-$(CONFIG_FSL_DIU_CH7301) += diu_ch7301.o
|
||||||
|
|
||||||
|
ifdef CONFIG_ARM
|
||||||
|
obj-$(CONFIG_DEEP_SLEEP) += arm_sleep.o
|
||||||
|
else
|
||||||
|
obj-$(CONFIG_DEEP_SLEEP) += mpc85xx_sleep.o
|
||||||
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_FSL_DCU_SII9022A) += dcu_sii9022a.o
|
obj-$(CONFIG_FSL_DCU_SII9022A) += dcu_sii9022a.o
|
||||||
|
|
||||||
obj-$(CONFIG_MPC8541CDS) += cds_pci_ft.o
|
obj-$(CONFIG_MPC8541CDS) += cds_pci_ft.o
|
||||||
|
|
95
board/freescale/common/arm_sleep.c
Normal file
95
board/freescale/common/arm_sleep.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#if !defined(CONFIG_ARMV7_NONSEC) || !defined(CONFIG_ARMV7_VIRT)
|
||||||
|
#error " Deep sleep needs non-secure mode support. "
|
||||||
|
#else
|
||||||
|
#include <asm/secure.h>
|
||||||
|
#endif
|
||||||
|
#include <asm/armv7.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_LS102XA)
|
||||||
|
#include <asm/arch/immap_ls102xa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
void __weak board_mem_sleep_setup(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void __weak board_sleep_prepare(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_warm_boot(void)
|
||||||
|
{
|
||||||
|
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||||
|
|
||||||
|
if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsl_dp_disable_console(void)
|
||||||
|
{
|
||||||
|
gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When wakeup from deep sleep, the first 128 bytes space
|
||||||
|
* will be used to do DDR training which corrupts the data
|
||||||
|
* in there. This function will restore them.
|
||||||
|
*/
|
||||||
|
static void dp_ddr_restore(void)
|
||||||
|
{
|
||||||
|
u64 *src, *dst;
|
||||||
|
int i;
|
||||||
|
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||||
|
|
||||||
|
/* get the address of ddr date from SPARECR3 */
|
||||||
|
src = (u64 *)in_le32(&scfg->sparecr[2]);
|
||||||
|
dst = (u64 *)CONFIG_SYS_SDRAM_BASE;
|
||||||
|
|
||||||
|
for (i = 0; i < DDR_BUFF_LEN / 8; i++)
|
||||||
|
*dst++ = *src++;
|
||||||
|
|
||||||
|
flush_dcache_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dp_resume_prepare(void)
|
||||||
|
{
|
||||||
|
dp_ddr_restore();
|
||||||
|
board_sleep_prepare();
|
||||||
|
armv7_init_nonsec();
|
||||||
|
cleanup_before_linux();
|
||||||
|
}
|
||||||
|
|
||||||
|
int fsl_dp_resume(void)
|
||||||
|
{
|
||||||
|
u32 start_addr;
|
||||||
|
void (*kernel_resume)(void);
|
||||||
|
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||||
|
|
||||||
|
if (!is_warm_boot())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dp_resume_prepare();
|
||||||
|
|
||||||
|
/* Get the entry address and jump to kernel */
|
||||||
|
start_addr = in_le32(&scfg->sparecr[1]);
|
||||||
|
debug("Entry address is 0x%08x\n", start_addr);
|
||||||
|
kernel_resume = (void (*)(void))start_addr;
|
||||||
|
secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
88
board/freescale/common/mpc85xx_sleep.c
Normal file
88
board/freescale/common/mpc85xx_sleep.c
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/immap_85xx.h>
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
void __weak board_mem_sleep_setup(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void __weak board_sleep_prepare(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_warm_boot(void)
|
||||||
|
{
|
||||||
|
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||||
|
|
||||||
|
if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsl_dp_disable_console(void)
|
||||||
|
{
|
||||||
|
gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When wakeup from deep sleep, the first 128 bytes space
|
||||||
|
* will be used to do DDR training which corrupts the data
|
||||||
|
* in there. This function will restore them.
|
||||||
|
*/
|
||||||
|
static void dp_ddr_restore(void)
|
||||||
|
{
|
||||||
|
volatile u64 *src, *dst;
|
||||||
|
int i;
|
||||||
|
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG;
|
||||||
|
|
||||||
|
/* get the address of ddr date from SPARECR3 */
|
||||||
|
src = (u64 *)in_be32(&scfg->sparecr[2]);
|
||||||
|
dst = (u64 *)CONFIG_SYS_SDRAM_BASE;
|
||||||
|
|
||||||
|
for (i = 0; i < DDR_BUFF_LEN / 8; i++)
|
||||||
|
*dst++ = *src++;
|
||||||
|
|
||||||
|
flush_dcache();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dp_resume_prepare(void)
|
||||||
|
{
|
||||||
|
dp_ddr_restore();
|
||||||
|
|
||||||
|
board_sleep_prepare();
|
||||||
|
|
||||||
|
l2cache_init();
|
||||||
|
#if defined(CONFIG_RAMBOOT_PBL)
|
||||||
|
disable_cpc_sram();
|
||||||
|
#endif
|
||||||
|
enable_cpc();
|
||||||
|
}
|
||||||
|
|
||||||
|
int fsl_dp_resume(void)
|
||||||
|
{
|
||||||
|
u32 start_addr;
|
||||||
|
void (*kernel_resume)(void);
|
||||||
|
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG;
|
||||||
|
|
||||||
|
if (!is_warm_boot())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dp_resume_prepare();
|
||||||
|
|
||||||
|
/* Get the entry address and jump to kernel */
|
||||||
|
start_addr = in_be32(&scfg->sparecr[1]);
|
||||||
|
debug("Entry address is 0x%08x\n", start_addr);
|
||||||
|
kernel_resume = (void (*)(void))start_addr;
|
||||||
|
kernel_resume();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
21
board/freescale/common/sleep.h
Normal file
21
board/freescale/common/sleep.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SLEEP_H
|
||||||
|
#define __SLEEP_H
|
||||||
|
|
||||||
|
#define DCFG_CCSR_CRSTSR_WDRFR (1 << 3)
|
||||||
|
#define DDR_BUFF_LEN 128
|
||||||
|
|
||||||
|
/* determine if it is a wakeup from deep sleep */
|
||||||
|
bool is_warm_boot(void);
|
||||||
|
|
||||||
|
/* disable console output */
|
||||||
|
void fsl_dp_disable_console(void);
|
||||||
|
|
||||||
|
/* clean up everything and jump to kernel */
|
||||||
|
int fsl_dp_resume(void);
|
||||||
|
#endif
|
|
@ -92,7 +92,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
|
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
|
||||||
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
||||||
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
||||||
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
|
||||||
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
||||||
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
||||||
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
||||||
|
@ -105,9 +104,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
||||||
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
|
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
|
||||||
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
||||||
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
|
|
||||||
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
|
||||||
|
|
||||||
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
|
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
|
||||||
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
||||||
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
|
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
|
||||||
|
@ -128,7 +124,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
|
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
|
||||||
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
|
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
|
||||||
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
||||||
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2,
|
||||||
|
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
|
||||||
|
ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
|
||||||
|
ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
|
||||||
|
|
||||||
|
/* DRAM VRef will not be trained */
|
||||||
|
ddr_out32(&ddr->ddr_cdr2,
|
||||||
|
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
||||||
|
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
|
||||||
|
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
||||||
|
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
||||||
|
}
|
||||||
ddr_out32(&ddr->err_disable, regs->err_disable);
|
ddr_out32(&ddr->err_disable, regs->err_disable);
|
||||||
ddr_out32(&ddr->err_int_en, regs->err_int_en);
|
ddr_out32(&ddr->err_int_en, regs->err_int_en);
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
|
@ -167,8 +180,20 @@ step2:
|
||||||
udelay(500);
|
udelay(500);
|
||||||
asm volatile("dsb sy;isb");
|
asm volatile("dsb sy;isb");
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
/* enter self-refresh */
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
|
||||||
|
temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
|
||||||
|
/* do board specific memory setup */
|
||||||
|
board_mem_sleep_setup();
|
||||||
|
|
||||||
|
temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
|
||||||
/* Let the controller go */
|
/* Let the controller go */
|
||||||
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
|
|
||||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||||
asm volatile("dsb sy;isb");
|
asm volatile("dsb sy;isb");
|
||||||
|
|
||||||
|
@ -211,4 +236,12 @@ step2:
|
||||||
|
|
||||||
if (timeout <= 0)
|
if (timeout <= 0)
|
||||||
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
||||||
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
/* exit self-refresh */
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
|
||||||
|
temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR;
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->dq_map_1, regs->dq_map_1);
|
ddr_out32(&ddr->dq_map_1, regs->dq_map_1);
|
||||||
ddr_out32(&ddr->dq_map_2, regs->dq_map_2);
|
ddr_out32(&ddr->dq_map_2, regs->dq_map_2);
|
||||||
ddr_out32(&ddr->dq_map_3, regs->dq_map_3);
|
ddr_out32(&ddr->dq_map_3, regs->dq_map_3);
|
||||||
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
|
||||||
ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3);
|
ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3);
|
||||||
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
||||||
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
||||||
|
@ -124,8 +123,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
|
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
|
||||||
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
||||||
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
|
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
|
||||||
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
|
|
||||||
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
|
||||||
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
|
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
|
||||||
#ifndef CONFIG_SYS_FSL_DDR_EMU
|
#ifndef CONFIG_SYS_FSL_DDR_EMU
|
||||||
/*
|
/*
|
||||||
|
@ -147,7 +144,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5);
|
ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5);
|
||||||
ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6);
|
ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6);
|
||||||
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
||||||
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2,
|
||||||
|
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
|
||||||
|
ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
|
||||||
|
ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
|
||||||
|
|
||||||
|
/* DRAM VRef will not be trained */
|
||||||
|
ddr_out32(&ddr->ddr_cdr2,
|
||||||
|
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
||||||
|
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
|
||||||
|
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
||||||
|
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
||||||
|
}
|
||||||
ddr_out32(&ddr->err_disable, regs->err_disable);
|
ddr_out32(&ddr->err_disable, regs->err_disable);
|
||||||
ddr_out32(&ddr->err_int_en, regs->err_int_en);
|
ddr_out32(&ddr->err_int_en, regs->err_int_en);
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
|
@ -187,8 +201,20 @@ step2:
|
||||||
mb();
|
mb();
|
||||||
isb();
|
isb();
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
/* enter self-refresh */
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
|
||||||
|
temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
|
||||||
|
/* do board specific memory setup */
|
||||||
|
board_mem_sleep_setup();
|
||||||
|
|
||||||
|
temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
|
||||||
/* Let the controller go */
|
/* Let the controller go */
|
||||||
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
|
|
||||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||||
mb();
|
mb();
|
||||||
isb();
|
isb();
|
||||||
|
@ -233,4 +259,12 @@ step2:
|
||||||
|
|
||||||
if (timeout <= 0)
|
if (timeout <= 0)
|
||||||
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
||||||
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
/* exit self-refresh */
|
||||||
|
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
|
||||||
|
temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR;
|
||||||
|
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
|
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regs has the to-be-set values for DDR controller registers
|
* regs has the to-be-set values for DDR controller registers
|
||||||
* ctrl_num is the DDR controller number
|
* ctrl_num is the DDR controller number
|
||||||
|
@ -44,16 +42,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
u32 save1, save2;
|
u32 save1, save2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
|
||||||
const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
|
||||||
bool sleep_flag = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
|
||||||
if (in_be32(&gur->scrtsr[0]) & (1 << 3))
|
|
||||||
sleep_flag = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (ctrl_num) {
|
switch (ctrl_num) {
|
||||||
case 0:
|
case 0:
|
||||||
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||||
|
@ -130,13 +118,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
|
out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
|
||||||
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
||||||
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
|
||||||
if (sleep_flag)
|
|
||||||
out_be32(&ddr->sdram_cfg_2,
|
|
||||||
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
|
||||||
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
||||||
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
||||||
out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
||||||
|
@ -149,17 +130,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
||||||
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
|
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
|
||||||
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
|
||||||
if (sleep_flag) {
|
|
||||||
out_be32(&ddr->init_addr, 0);
|
|
||||||
out_be32(&ddr->init_ext_addr, (1 << 31));
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
out_be32(&ddr->init_addr, regs->ddr_init_addr);
|
|
||||||
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
|
out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
|
||||||
out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
||||||
out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
|
out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
|
||||||
|
@ -180,7 +150,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||||
out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
|
out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
|
||||||
out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
|
out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
|
||||||
out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
||||||
out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
|
if (is_warm_boot()) {
|
||||||
|
out_be32(&ddr->sdram_cfg_2,
|
||||||
|
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
|
||||||
|
out_be32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
|
||||||
|
out_be32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
|
||||||
|
|
||||||
|
/* DRAM VRef will not be trained */
|
||||||
|
out_be32(&ddr->ddr_cdr2,
|
||||||
|
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
||||||
|
out_be32(&ddr->init_addr, regs->ddr_init_addr);
|
||||||
|
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
||||||
|
out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
||||||
|
}
|
||||||
out_be32(&ddr->err_disable, regs->err_disable);
|
out_be32(&ddr->err_disable, regs->err_disable);
|
||||||
out_be32(&ddr->err_int_en, regs->err_int_en);
|
out_be32(&ddr->err_int_en, regs->err_int_en);
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
|
@ -400,21 +387,17 @@ step2:
|
||||||
asm volatile("sync;isync");
|
asm volatile("sync;isync");
|
||||||
|
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
if (sleep_flag) {
|
if (is_warm_boot()) {
|
||||||
/* enter self-refresh */
|
/* enter self-refresh */
|
||||||
setbits_be32(&ddr->sdram_cfg_2, (1 << 31));
|
setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
|
||||||
/* do board specific memory setup */
|
/* do board specific memory setup */
|
||||||
board_mem_sleep_setup();
|
board_mem_sleep_setup();
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Let the controller go */
|
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
|
||||||
if (sleep_flag)
|
|
||||||
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
|
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
|
||||||
else
|
} else
|
||||||
#endif
|
#endif
|
||||||
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI);
|
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI);
|
||||||
|
|
||||||
|
/* Let the controller go */
|
||||||
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||||
asm volatile("sync;isync");
|
asm volatile("sync;isync");
|
||||||
|
|
||||||
|
@ -566,8 +549,8 @@ step2:
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
|
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
|
||||||
#ifdef CONFIG_DEEP_SLEEP
|
#ifdef CONFIG_DEEP_SLEEP
|
||||||
if (sleep_flag)
|
if (is_warm_boot())
|
||||||
/* exit self-refresh */
|
/* exit self-refresh */
|
||||||
clrbits_be32(&ddr->sdram_cfg_2, (1 << 31));
|
clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,7 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
||||||
#define SDRAM_CFG_2T_EN 0x00008000
|
#define SDRAM_CFG_2T_EN 0x00008000
|
||||||
#define SDRAM_CFG_BI 0x00000001
|
#define SDRAM_CFG_BI 0x00000001
|
||||||
|
|
||||||
|
#define SDRAM_CFG2_FRC_SR 0x80000000
|
||||||
#define SDRAM_CFG2_D_INIT 0x00000010
|
#define SDRAM_CFG2_D_INIT 0x00000010
|
||||||
#define SDRAM_CFG2_ODT_CFG_MASK 0x00600000
|
#define SDRAM_CFG2_ODT_CFG_MASK 0x00600000
|
||||||
#define SDRAM_CFG2_ODT_NEVER 0
|
#define SDRAM_CFG2_ODT_NEVER 0
|
||||||
|
@ -163,6 +164,7 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
||||||
#define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT)
|
#define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT)
|
||||||
#define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK)
|
#define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK)
|
||||||
#define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8))
|
#define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8))
|
||||||
|
#define DDR_CDR2_VREF_TRAIN_EN 0x00000080
|
||||||
|
|
||||||
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
|
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
|
||||||
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
|
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
|
||||||
|
@ -202,6 +204,8 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
||||||
#define DDR_CDR_ODT_120ohm 0x6
|
#define DDR_CDR_ODT_120ohm 0x6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DDR_INIT_ADDR_EXT_UIA (1 << 31)
|
||||||
|
|
||||||
/* Record of register values computed */
|
/* Record of register values computed */
|
||||||
typedef struct fsl_ddr_cfg_regs_s {
|
typedef struct fsl_ddr_cfg_regs_s {
|
||||||
struct {
|
struct {
|
||||||
|
@ -414,9 +418,11 @@ static int __board_need_mem_reset(void)
|
||||||
int board_need_mem_reset(void)
|
int board_need_mem_reset(void)
|
||||||
__attribute__((weak, alias("__board_need_mem_reset")));
|
__attribute__((weak, alias("__board_need_mem_reset")));
|
||||||
|
|
||||||
void __weak board_mem_sleep_setup(void)
|
#if defined(CONFIG_DEEP_SLEEP)
|
||||||
{
|
void board_mem_sleep_setup(void);
|
||||||
}
|
bool is_warm_boot(void);
|
||||||
|
int fsl_dp_resume(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 85xx boards have a common prototype for fixed_sdram so put the
|
* The 85xx boards have a common prototype for fixed_sdram so put the
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue