summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacky Bai <ping.bai@nxp.com>2020-01-07 16:44:46 +0800
committerJacky Bai <ping.bai@nxp.com>2020-02-09 20:58:49 +0800
commite73e454d11dab13a87b6068a24509a1f118ac812 (patch)
treebdbef88443b7359053a13ab066877e75e762c9a3
parent059a9519ad1cb49f3c04210d59e89773221704a3 (diff)
plat: imx8mq: Add the dram retention support for imx8mq
Add the dram retention support for i.MX8MQ. As there is no enough ocram space available before entering TF-A, so the timing info need to be copied from dram into ocram. Signed-off-by: Jacky Bai <ping.bai@nxp.com>
-rw-r--r--plat/imx/imx8m/ddr/clock.c2
-rw-r--r--plat/imx/imx8m/ddr/dram.c32
-rw-r--r--plat/imx/imx8m/ddr/dram_retention.c2
-rw-r--r--plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c5
-rw-r--r--plat/imx/imx8m/imx8mq/imx8mq_psci.c3
-rw-r--r--plat/imx/imx8m/imx8mq/include/platform_def.h11
-rw-r--r--plat/imx/imx8m/imx8mq/platform.mk7
7 files changed, 59 insertions, 3 deletions
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
index c462bb45..b724d2f6 100644
--- a/plat/imx/imx8m/ddr/clock.c
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -73,7 +73,7 @@ void dram_pll_init(unsigned int drate)
/* unbypass the PLL */
mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
- while(!(mmio_read_32(HW_DRAM_PLL_CFG0) & (1 << 31)))
+ while(!(mmio_read_32(HW_DRAM_PLL_CFG0) & BIT(31)))
;
}
#else
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
index 917464eb..d3ecf769 100644
--- a/plat/imx/imx8m/ddr/dram.c
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -15,11 +15,19 @@
#define IMX_SIP_DDR_DVFS_GET_FREQ_COUNT 0x10
#define IMX_SIP_DDR_DVFS_GET_FREQ_INFO 0x11
+#define TIMING_CFG_PTR(ptr, old_base, new_base) \
+ ((struct dram_cfg_param *)(((uint64_t)(ptr) & ~(uint64_t)(old_base)) + (uint64_t)(new_base)))
+
struct dram_info dram_info;
/* lock used for DDR DVFS */
spinlock_t dfs_lock;
+#if defined(PLAT_imx8mq)
+/* ocram used to dram timing */
+static uint8_t dram_timing_saved[13 * 1024] __aligned(8);
+#endif
+
static volatile uint32_t wfe_done;
static volatile bool wait_ddrc_hwffc_done = true;
static unsigned int dev_fsp = 0x1;
@@ -30,6 +38,24 @@ static uint32_t fsp_init_reg[3][4] = {
{ DDRC_FREQ2_INIT3(0), DDRC_FREQ2_INIT4(0), DDRC_FREQ2_INIT6(0), DDRC_FREQ2_INIT7(0) },
};
+
+#if defined (PLAT_imx8mq)
+/* copy the dram timing info from DRAM to OCRAM */
+void imx8mq_dram_timing_copy(struct dram_timing_info *from)
+{
+ struct dram_timing_info *info = (struct dram_timing_info *)dram_timing_saved;
+
+ /* copy the whole 13KB content used for dram timing info */
+ memcpy(dram_timing_saved, from, sizeof(dram_timing_saved));
+
+ /* correct the header after copied into ocram */
+ info->ddrc_cfg = TIMING_CFG_PTR(info->ddrc_cfg, from, dram_timing_saved);
+ info->ddrphy_cfg = TIMING_CFG_PTR(info->ddrphy_cfg, from, dram_timing_saved);
+ info->ddrphy_trained_csr = TIMING_CFG_PTR(info->ddrphy_trained_csr, from, dram_timing_saved);
+ info->ddrphy_pie = TIMING_CFG_PTR(info->ddrphy_pie, from, dram_timing_saved);
+}
+#endif
+
static void get_mr_values(uint32_t (*mr_value)[8])
{
uint32_t init_val;
@@ -134,6 +160,12 @@ void dram_info_init(unsigned long dram_timing_base)
dram_info.boot_fsp = current_fsp;
dram_info.current_fsp = current_fsp;
+#if defined(PLAT_imx8mq)
+ imx8mq_dram_timing_copy((struct dram_timing_info *)dram_timing_base);
+
+ dram_timing_base = (unsigned long) dram_timing_saved;
+#endif
+
get_mr_values(dram_info.mr_table);
dram_info.timing_info = (struct dram_timing_info *)dram_timing_base;
diff --git a/plat/imx/imx8m/ddr/dram_retention.c b/plat/imx/imx8m/ddr/dram_retention.c
index b919fecc..2eb1438a 100644
--- a/plat/imx/imx8m/ddr/dram_retention.c
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -21,8 +21,6 @@
#define CCM_SRC_CTRL(n) (CCM_SRC_CTRL_OFFSET + 0x10 * (n))
#define CCM_CCGR(n) (CCM_CCGR_OFFSET + 0x10 * (n))
-#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
-
void dram_enter_retention(void)
{
/* Wait DBGCAM to be empty */
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 27c55454..ec1a9cc0 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -21,6 +21,7 @@
#include <lib/xlat_tables/xlat_tables.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
@@ -33,6 +34,8 @@ static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW), /* ROM map */
MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW), /* GIC map */
+ MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX map */
+ MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS),
{0},
};
@@ -195,6 +198,8 @@ void bl31_platform_setup(void)
/* gpc init */
imx_gpc_init();
+
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
index 04e191ff..78a6ea70 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
@@ -12,6 +12,7 @@
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <dram.h>
#include <gpc.h>
#include <imx8m_psci.h>
#include <plat_imx8.h>
@@ -63,6 +64,7 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
imx_set_sys_lpm(core_id, true);
+ dram_enter_retention();
}
}
@@ -73,6 +75,7 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state)
/* check the system level status */
if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+ dram_exit_retention();
imx_set_sys_lpm(core_id, false);
imx_clear_rbc_count();
}
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 9aa759fd..c7d972ad 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <lib/utils_def.h>
+
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -74,6 +76,9 @@
#define IMX_DDRC_BASE U(0x3d400000)
#define IMX_DDRPHY_BASE U(0x3c000000)
#define IMX_DDR_IPS_BASE U(0x3d000000)
+#define IMX_DDR_IPS_SIZE U(0x1800000)
+#define IMX_DRAM_BASE U(0x40000000)
+#define IMX_DRAM_SIZE U(0xc0000000)
#define IMX_ROM_BASE U(0x00000000)
#define IMX_ROM_SIZE U(0x20000)
@@ -109,6 +114,12 @@
#define SNVS_LPCR_DP_EN BIT(5)
#define SNVS_LPCR_TOP BIT(6)
+#define SAVED_DRAM_TIMING_BASE 0x40000000
+
+#define HW_DRAM_PLL_CFG0 (IMX_ANAMIX_BASE + 0x60)
+#define HW_DRAM_PLL_CFG1 (IMX_ANAMIX_BASE + 0x64)
+#define HW_DRAM_PLL_CFG2 (IMX_ANAMIX_BASE + 0x68)
+#define DRAM_PLL_CTRL HW_DRAM_PLL_CFG0
#define IOMUXC_GPR10 U(0x28)
#define GPR_TZASC_EN BIT(0)
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index c63559a2..4dd659e3 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -8,6 +8,12 @@ PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
-Iplat/imx/imx8m/imx8mq/include
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
drivers/arm/gic/v3/arm_gicv3_common.c \
drivers/arm/gic/v3/gic500.c \
@@ -35,6 +41,7 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES}
XLAT_TABLE_IN_OCRAM_S := 1