feat(imx8m): update the ddr4 dvfs flow to include ddr3l support
the DDR3L & DDR4 can share same piece of code for DDR frequency scaling.
So update the ddr4 dvfs flow to support DDR3L too.
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Reviewed-by: Anson Huang <anson.huang@nxp.com>
Change-Id: Ifc6981f05ed8a4e399adad97690197a9680f554d
diff --git a/plat/imx/imx8m/ddr/ddr4_dvfs.c b/plat/imx/imx8m/ddr/ddr4_dvfs.c
index 3ee68e4..d58a0cc 100644
--- a/plat/imx/imx8m/ddr/ddr4_dvfs.c
+++ b/plat/imx/imx8m/ddr/ddr4_dvfs.c
@@ -9,7 +9,8 @@
#include <dram.h>
-void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type, uint32_t rank)
+void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type,
+ uint32_t rank, uint32_t dram_type)
{
uint32_t val, mr_mirror, data_mirror;
@@ -28,9 +29,15 @@
val = mmio_read_32(DDRC_DIMMCTL(0));
if ((val & 0x2) && (rank == 0x2)) {
mr_mirror = (mr & 0x4) | ((mr & 0x1) << 1) | ((mr & 0x2) >> 1); /* BA0, BA1 swap */
- data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+ if (dram_type == DDRC_DDR4) {
+ data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
- ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+ ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+ } else {
+ data_mirror = (data & 0xfe07) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+ ((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
+ ((data & 0x100) >> 1);
+ }
} else {
mr_mirror = mr;
data_mirror = data;
@@ -56,6 +63,7 @@
void dram_cfg_all_mr(struct dram_info *info, uint32_t pstate)
{
uint32_t num_rank = info->num_rank;
+ uint32_t dram_type = info->dram_type;
/*
* 15. Perform MRS commands as required to re-program
* timing registers in the SDRAM for the new frequency
@@ -64,9 +72,9 @@
for (int i = 1; i <= num_rank; i++) {
for (int j = 0; j < 6; j++) {
- ddr4_mr_write(j, info->mr_table[pstate][j], 0, i);
+ ddr4_mr_write(j, info->mr_table[pstate][j], 0, i, dram_type);
}
- ddr4_mr_write(6, info->mr_table[pstate][7], 0, i);
+ ddr4_mr_write(6, info->mr_table[pstate][7], 0, i, dram_type);
}
}
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
index 0b0a527..53605cd 100644
--- a/plat/imx/imx8m/ddr/dram.c
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -163,8 +163,18 @@
if (rc != 0) {
panic();
}
-}
+ if (dram_info.dram_type == DDRC_LPDDR4 && current_fsp != 0x0) {
+ /* flush the L1/L2 cache */
+ dcsw_op_all(DCCSW);
+ lpddr4_swffc(&dram_info, dev_fsp, 0x0);
+ dev_fsp = (~dev_fsp) & 0x1;
+ } else if (current_fsp != 0x0) {
+ /* flush the L1/L2 cache */
+ dcsw_op_all(DCCSW);
+ ddr4_swffc(&dram_info, 0x0);
+ }
+}
/*
* For each freq return the following info:
@@ -248,7 +258,7 @@
if (dram_info.dram_type == DDRC_LPDDR4) {
lpddr4_swffc(&dram_info, dev_fsp, fsp_index);
dev_fsp = (~dev_fsp) & 0x1;
- } else if (dram_info.dram_type == DDRC_DDR4) {
+ } else {
ddr4_swffc(&dram_info, fsp_index);
}