summaryrefslogtreecommitdiff
path: root/plat/imx/imx8m/ddr/dram.c
diff options
context:
space:
mode:
Diffstat (limited to 'plat/imx/imx8m/ddr/dram.c')
-rw-r--r--plat/imx/imx8m/ddr/dram.c32
1 files changed, 32 insertions, 0 deletions
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;