feat(imx8m): add dram retention flow for imx8m family

Add the dram retention flow for i.MX8M SoC family.

Change-Id: Ifb8ba5b2f6f002133cf47c07fef73df29c51c890
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
new file mode 100644
index 0000000..6841b2d
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <dram.h>
+
+struct dram_info dram_info;
+
+/* Restore the ddrc configs */
+void dram_umctl2_init(struct dram_timing_info *timing)
+{
+	struct dram_cfg_param *ddrc_cfg = timing->ddrc_cfg;
+	unsigned int i;
+
+	for (i = 0U; i < timing->ddrc_cfg_num; i++) {
+		mmio_write_32(ddrc_cfg->reg, ddrc_cfg->val);
+		ddrc_cfg++;
+	}
+
+	/* set the default fsp to P0 */
+	mmio_write_32(DDRC_MSTR2(0), 0x0);
+}
+
+/* Restore the dram PHY config */
+void dram_phy_init(struct dram_timing_info *timing)
+{
+	struct dram_cfg_param *cfg = timing->ddrphy_cfg;
+	unsigned int i;
+
+	/* Restore the PHY init config */
+	cfg = timing->ddrphy_cfg;
+	for (i = 0U; i < timing->ddrphy_cfg_num; i++) {
+		dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+		cfg++;
+	}
+
+	/* Restore the DDR PHY CSRs */
+	cfg = timing->ddrphy_trained_csr;
+	for (i = 0U; i < timing->ddrphy_trained_csr_num; i++) {
+		dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+		cfg++;
+	}
+
+	/* Load the PIE image */
+	cfg = timing->ddrphy_pie;
+	for (i = 0U; i < timing->ddrphy_pie_num; i++) {
+		dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+		cfg++;
+	}
+}
+
+void dram_info_init(unsigned long dram_timing_base)
+{
+	uint32_t ddrc_mstr, current_fsp;
+
+	/* Get the dram type & rank */
+	ddrc_mstr = mmio_read_32(DDRC_MSTR(0));
+
+	dram_info.dram_type = ddrc_mstr & DDR_TYPE_MASK;
+	dram_info.num_rank = (ddrc_mstr >> 24) & ACTIVE_RANK_MASK;
+
+	/* Get current fsp info */
+	current_fsp = mmio_read_32(DDRC_DFIMISC(0)) & 0xf;
+	dram_info.boot_fsp = current_fsp;
+	dram_info.current_fsp = current_fsp;
+
+	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
new file mode 100644
index 0000000..73eb8c4
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <lib/mmio.h>
+
+#include <dram.h>
+#include <platform_def.h>
+
+#define SRC_DDR1_RCR		(IMX_SRC_BASE + 0x1000)
+#define SRC_DDR2_RCR		(IMX_SRC_BASE + 0x1004)
+
+#define PU_PGC_UP_TRG		0xf8
+#define PU_PGC_DN_TRG		0x104
+#define GPC_PU_PWRHSK		(IMX_GPC_BASE + 0x01FC)
+#define CCM_SRC_CTRL_OFFSET     (IMX_CCM_BASE + 0x800)
+#define CCM_CCGR_OFFSET         (IMX_CCM_BASE + 0x4000)
+#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)
+
+#define DBGCAM_EMPTY		0x36000000
+
+void dram_enter_retention(void)
+{
+	/* Wait DBGCAM to be empty */
+	while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) {
+		;
+	}
+
+	/* Block AXI ports from taking anymore transactions */
+	mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+	/* Wait until all AXI ports are idle */
+	while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
+		;
+	}
+
+	/* Enter self refresh */
+	mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+
+	/* LPDDR4 & DDR4/DDR3L need to check different status */
+	if (dram_info.dram_type == DDRC_LPDDR4) {
+		while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) {
+			;
+		}
+	} else {
+		while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) {
+			;
+		}
+	}
+
+	mmio_write_32(DDRC_DFIMISC(0), 0x0);
+	mmio_write_32(DDRC_SWCTL(0), 0x0);
+	mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+	mmio_write_32(DDRC_DFIMISC(0), 0x1f20);
+
+	while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
+		;
+	}
+
+	mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+	/* wait DFISTAT.dfi_init_complete to 1 */
+	while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+		;
+	}
+
+	mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+	/* should check PhyInLP3 pub reg */
+	dwc_ddrphy_apb_wr(0xd0000, 0x0);
+	if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+		INFO("PhyInLP3 = 1\n");
+	}
+	dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+#if defined(PLAT_imx8mq)
+	/* pwrdnreqn_async adbm/adbs of ddr */
+	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1));
+	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) {
+		;
+	}
+	mmio_setbits_32(GPC_PU_PWRHSK, BIT(1));
+#else
+	/* pwrdnreqn_async adbm/adbs of ddr */
+	mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2));
+	while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) {
+		;
+	}
+	mmio_setbits_32(GPC_PU_PWRHSK, BIT(2));
+#endif
+	/* remove PowerOk */
+	mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
+
+	mmio_write_32(CCM_CCGR(5), 0);
+	mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+	/* enable the phy iso */
+	mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1);
+	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5));
+
+	VERBOSE("dram enter retention\n");
+}
+
+void dram_exit_retention(void)
+{
+	VERBOSE("dram exit retention\n");
+	/* assert all reset */
+#if defined(PLAT_imx8mq)
+	mmio_write_32(SRC_DDR2_RCR, 0x8F000003);
+	mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+	mmio_write_32(SRC_DDR2_RCR, 0x8F000000);
+#else
+	mmio_write_32(SRC_DDR1_RCR, 0x8F00001F);
+	mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+#endif
+	mmio_write_32(CCM_CCGR(5), 2);
+	mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+	/* disable iso */
+	mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
+	mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
+
+	/* wait dram pll locked */
+	while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
+		;
+	}
+
+	/* ddrc re-init */
+	dram_umctl2_init(dram_info.timing_info);
+
+	/*
+	 * Skips the DRAM init routine and starts up in selfrefresh mode
+	 * Program INIT0.skip_dram_init = 2'b11
+	 */
+	mmio_setbits_32(DDRC_INIT0(0), 0xc0000000);
+	/* Keeps the controller in self-refresh mode */
+	mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+	mmio_write_32(DDRC_DBG1(0), 0x0);
+	mmio_write_32(SRC_DDR1_RCR, 0x8F000004);
+	mmio_write_32(SRC_DDR1_RCR, 0x8F000000);
+
+	/* before write Dynamic reg, sw_done should be 0 */
+	mmio_write_32(DDRC_SWCTL(0), 0x0);
+	if (dram_info.dram_type == DDRC_LPDDR4) {
+		mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */
+	}
+	mmio_write_32(DDRC_DFIMISC(0), 0x0);
+
+	/* dram phy re-init */
+	dram_phy_init(dram_info.timing_info);
+
+	/* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
+	dwc_ddrphy_apb_wr(0xd0000, 0x0);
+	while (dwc_ddrphy_apb_rd(0x20097)) {
+		;
+	}
+	dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+	/* before write Dynamic reg, sw_done should be 0 */
+	mmio_write_32(DDRC_SWCTL(0), 0x0);
+	mmio_write_32(DDRC_DFIMISC(0), 0x20);
+	/* wait DFISTAT.dfi_init_complete to 1 */
+	while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+		;
+	}
+
+	/* clear DFIMISC.dfi_init_start */
+	mmio_write_32(DDRC_DFIMISC(0), 0x0);
+	/* set DFIMISC.dfi_init_complete_en */
+	mmio_write_32(DDRC_DFIMISC(0), 0x1);
+
+	/* set SWCTL.sw_done to enable quasi-dynamic register programming */
+	mmio_write_32(DDRC_SWCTL(0), 0x1);
+	/* wait SWSTAT.sw_done_ack to 1 */
+	while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
+		;
+	}
+
+	mmio_write_32(DDRC_PWRCTL(0), 0x88);
+	/* wait STAT to normal state */
+	while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) {
+		;
+	}
+
+	mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+	 /* dis_auto-refresh is set to 0 */
+	mmio_write_32(DDRC_RFSHCTL3(0), 0x0);
+
+	/* should check PhyInLP3 pub reg */
+	dwc_ddrphy_apb_wr(0xd0000, 0x0);
+	if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+		VERBOSE("PHYInLP3 = 0\n");
+	}
+	dwc_ddrphy_apb_wr(0xd0000, 0x1);
+}
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 57e5c51..d443c3d 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -19,6 +19,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
+#include <dram.h>
 #include <gpc.h>
 #include <imx_aipstz.h>
 #include <imx_uart.h>
@@ -203,6 +204,9 @@
 	/* select the CKIL source to 32K OSC */
 	mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
 
+	/* Init the dram info */
+	dram_info_init(SAVED_DRAM_TIMING_BASE);
+
 	plat_gic_driver_init();
 	plat_gic_init();
 
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 73fbd87..ded31ca 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -15,6 +15,9 @@
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
+IMX_DRAM_SOURCES	:=	plat/imx/imx8m/ddr/dram.c		\
+				plat/imx/imx8m/ddr/dram_retention.c
+
 IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_gicv3.c		\
 				plat/common/plat_psci_common.c		\
@@ -38,6 +41,7 @@
 				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_TABLES_LIB_SRCS}
 
diff --git a/plat/imx/imx8m/include/ddrc.h b/plat/imx/imx8m/include/ddrc.h
new file mode 100644
index 0000000..55af3ff
--- /dev/null
+++ b/plat/imx/imx8m/include/ddrc.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_DDRC_H
+#define IMX_DDRC_H
+
+#define DDRC_IPS_BASE_ADDR(X)	(0x3d400000 + ((X) * 0x2000000))
+#define DDRC_DDR_SS_GPR0        0x3d000000
+
+/* DWC ddr umctl2 REGs offset*/
+/**********************/
+#define DDRC_MSTR(X)             (DDRC_IPS_BASE_ADDR(X) + 0x00)
+#define DDRC_STAT(X)             (DDRC_IPS_BASE_ADDR(X) + 0x04)
+#define DDRC_MSTR1(X)            (DDRC_IPS_BASE_ADDR(X) + 0x08)
+#define DDRC_MRCTRL0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x10)
+#define DDRC_MRCTRL1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x14)
+#define DDRC_MRSTAT(X)           (DDRC_IPS_BASE_ADDR(X) + 0x18)
+#define DDRC_MRCTRL2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1c)
+#define DDRC_DERATEEN(X)         (DDRC_IPS_BASE_ADDR(X) + 0x20)
+#define DDRC_DERATEINT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x24)
+#define DDRC_MSTR2(X)            (DDRC_IPS_BASE_ADDR(X) + 0x28)
+#define DDRC_PWRCTL(X)           (DDRC_IPS_BASE_ADDR(X) + 0x30)
+#define DDRC_PWRTMG(X)           (DDRC_IPS_BASE_ADDR(X) + 0x34)
+#define DDRC_HWLPCTL(X)          (DDRC_IPS_BASE_ADDR(X) + 0x38)
+#define DDRC_HWFFCCTL(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3c)
+#define DDRC_HWFFCSTAT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x40)
+#define DDRC_RFSHCTL0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x50)
+#define DDRC_RFSHCTL1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x54)
+#define DDRC_RFSHCTL2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x58)
+#define DDRC_RFSHCTL3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x60)
+#define DDRC_RFSHTMG(X)          (DDRC_IPS_BASE_ADDR(X) + 0x64)
+#define DDRC_ECCCFG0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x70)
+#define DDRC_ECCCFG1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x74)
+#define DDRC_ECCSTAT(X)          (DDRC_IPS_BASE_ADDR(X) + 0x78)
+#define DDRC_ECCCLR(X)           (DDRC_IPS_BASE_ADDR(X) + 0x7c)
+#define DDRC_ECCERRCNT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x80)
+#define DDRC_ECCCADDR0(X)        (DDRC_IPS_BASE_ADDR(X) + 0x84)
+#define DDRC_ECCCADDR1(X)        (DDRC_IPS_BASE_ADDR(X) + 0x88)
+#define DDRC_ECCCSYN0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x8c)
+#define DDRC_ECCCSYN1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x90)
+#define DDRC_ECCCSYN2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x94)
+#define DDRC_ECCBITMASK0(X)      (DDRC_IPS_BASE_ADDR(X) + 0x98)
+#define DDRC_ECCBITMASK1(X)      (DDRC_IPS_BASE_ADDR(X) + 0x9c)
+#define DDRC_ECCBITMASK2(X)      (DDRC_IPS_BASE_ADDR(X) + 0xa0)
+#define DDRC_ECCUADDR0(X)        (DDRC_IPS_BASE_ADDR(X) + 0xa4)
+#define DDRC_ECCUADDR1(X)        (DDRC_IPS_BASE_ADDR(X) + 0xa8)
+#define DDRC_ECCUSYN0(X)         (DDRC_IPS_BASE_ADDR(X) + 0xac)
+#define DDRC_ECCUSYN1(X)         (DDRC_IPS_BASE_ADDR(X) + 0xb0)
+#define DDRC_ECCUSYN2(X)         (DDRC_IPS_BASE_ADDR(X) + 0xb4)
+#define DDRC_ECCPOISONADDR0(X)   (DDRC_IPS_BASE_ADDR(X) + 0xb8)
+#define DDRC_ECCPOISONADDR1(X)   (DDRC_IPS_BASE_ADDR(X) + 0xbc)
+#define DDRC_CRCPARCTL0(X)       (DDRC_IPS_BASE_ADDR(X) + 0xc0)
+#define DDRC_CRCPARCTL1(X)       (DDRC_IPS_BASE_ADDR(X) + 0xc4)
+#define DDRC_CRCPARCTL2(X)       (DDRC_IPS_BASE_ADDR(X) + 0xc8)
+#define DDRC_CRCPARSTAT(X)       (DDRC_IPS_BASE_ADDR(X) + 0xcc)
+#define DDRC_INIT0(X)            (DDRC_IPS_BASE_ADDR(X) + 0xd0)
+#define DDRC_INIT1(X)            (DDRC_IPS_BASE_ADDR(X) + 0xd4)
+#define DDRC_INIT2(X)            (DDRC_IPS_BASE_ADDR(X) + 0xd8)
+#define DDRC_INIT3(X)            (DDRC_IPS_BASE_ADDR(X) + 0xdc)
+#define DDRC_INIT4(X)            (DDRC_IPS_BASE_ADDR(X) + 0xe0)
+#define DDRC_INIT5(X)            (DDRC_IPS_BASE_ADDR(X) + 0xe4)
+#define DDRC_INIT6(X)            (DDRC_IPS_BASE_ADDR(X) + 0xe8)
+#define DDRC_INIT7(X)            (DDRC_IPS_BASE_ADDR(X) + 0xec)
+#define DDRC_DIMMCTL(X)          (DDRC_IPS_BASE_ADDR(X) + 0xf0)
+#define DDRC_RANKCTL(X)          (DDRC_IPS_BASE_ADDR(X) + 0xf4)
+#define DDRC_DRAMTMG0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x100)
+#define DDRC_DRAMTMG1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x104)
+#define DDRC_DRAMTMG2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x108)
+#define DDRC_DRAMTMG3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x10c)
+#define DDRC_DRAMTMG4(X)         (DDRC_IPS_BASE_ADDR(X) + 0x110)
+#define DDRC_DRAMTMG5(X)         (DDRC_IPS_BASE_ADDR(X) + 0x114)
+#define DDRC_DRAMTMG6(X)         (DDRC_IPS_BASE_ADDR(X) + 0x118)
+#define DDRC_DRAMTMG7(X)         (DDRC_IPS_BASE_ADDR(X) + 0x11c)
+#define DDRC_DRAMTMG8(X)         (DDRC_IPS_BASE_ADDR(X) + 0x120)
+#define DDRC_DRAMTMG9(X)         (DDRC_IPS_BASE_ADDR(X) + 0x124)
+#define DDRC_DRAMTMG10(X)        (DDRC_IPS_BASE_ADDR(X) + 0x128)
+#define DDRC_DRAMTMG11(X)        (DDRC_IPS_BASE_ADDR(X) + 0x12c)
+#define DDRC_DRAMTMG12(X)        (DDRC_IPS_BASE_ADDR(X) + 0x130)
+#define DDRC_DRAMTMG13(X)        (DDRC_IPS_BASE_ADDR(X) + 0x134)
+#define DDRC_DRAMTMG14(X)        (DDRC_IPS_BASE_ADDR(X) + 0x138)
+#define DDRC_DRAMTMG15(X)        (DDRC_IPS_BASE_ADDR(X) + 0x13C)
+#define DDRC_DRAMTMG16(X)        (DDRC_IPS_BASE_ADDR(X) + 0x140)
+#define DDRC_DRAMTMG17(X)        (DDRC_IPS_BASE_ADDR(X) + 0x144)
+
+#define DDRC_ZQCTL0(X)           (DDRC_IPS_BASE_ADDR(X) + 0x180)
+#define DDRC_ZQCTL1(X)           (DDRC_IPS_BASE_ADDR(X) + 0x184)
+#define DDRC_ZQCTL2(X)           (DDRC_IPS_BASE_ADDR(X) + 0x188)
+#define DDRC_ZQSTAT(X)           (DDRC_IPS_BASE_ADDR(X) + 0x18c)
+#define DDRC_DFITMG0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x190)
+#define DDRC_DFITMG1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x194)
+#define DDRC_DFILPCFG0(X)        (DDRC_IPS_BASE_ADDR(X) + 0x198)
+#define DDRC_DFILPCFG1(X)        (DDRC_IPS_BASE_ADDR(X) + 0x19c)
+#define DDRC_DFIUPD0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1a0)
+#define DDRC_DFIUPD1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1a4)
+#define DDRC_DFIUPD2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1a8)
+#define DDRC_DFIMISC(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1b0)
+#define DDRC_DFITMG2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1b4)
+#define DDRC_DFITMG3(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1b8)
+#define DDRC_DFISTAT(X)          (DDRC_IPS_BASE_ADDR(X) + 0x1bc)
+
+#define DDRC_DBICTL(X)           (DDRC_IPS_BASE_ADDR(X) + 0x1c0)
+#define DDRC_DFIPHYMSTR(X)       (DDRC_IPS_BASE_ADDR(X) + 0x1c4)
+#define DDRC_TRAINCTL0(X)        (DDRC_IPS_BASE_ADDR(X) + 0x1d0)
+#define DDRC_TRAINCTL1(X)        (DDRC_IPS_BASE_ADDR(X) + 0x1d4)
+#define DDRC_TRAINCTL2(X)        (DDRC_IPS_BASE_ADDR(X) + 0x1d8)
+#define DDRC_TRAINSTAT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x1dc)
+#define DDRC_ADDRMAP0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x200)
+#define DDRC_ADDRMAP1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x204)
+#define DDRC_ADDRMAP2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x208)
+#define DDRC_ADDRMAP3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x20c)
+#define DDRC_ADDRMAP4(X)         (DDRC_IPS_BASE_ADDR(X) + 0x210)
+#define DDRC_ADDRMAP5(X)         (DDRC_IPS_BASE_ADDR(X) + 0x214)
+#define DDRC_ADDRMAP6(X)         (DDRC_IPS_BASE_ADDR(X) + 0x218)
+#define DDRC_ADDRMAP7(X)         (DDRC_IPS_BASE_ADDR(X) + 0x21c)
+#define DDRC_ADDRMAP8(X)         (DDRC_IPS_BASE_ADDR(X) + 0x220)
+#define DDRC_ADDRMAP9(X)         (DDRC_IPS_BASE_ADDR(X) + 0x224)
+#define DDRC_ADDRMAP10(X)        (DDRC_IPS_BASE_ADDR(X) + 0x228)
+#define DDRC_ADDRMAP11(X)        (DDRC_IPS_BASE_ADDR(X) + 0x22c)
+
+#define DDRC_ODTCFG(X)           (DDRC_IPS_BASE_ADDR(X) + 0x240)
+#define DDRC_ODTMAP(X)           (DDRC_IPS_BASE_ADDR(X) + 0x244)
+#define DDRC_SCHED(X)            (DDRC_IPS_BASE_ADDR(X) + 0x250)
+#define DDRC_SCHED1(X)           (DDRC_IPS_BASE_ADDR(X) + 0x254)
+#define DDRC_PERFHPR1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x25c)
+#define DDRC_PERFLPR1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x264)
+#define DDRC_PERFWR1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x26c)
+#define DDRC_PERFVPR1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x274)
+
+#define DDRC_PERFVPW1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x278)
+
+#define DDRC_DQMAP0(X)           (DDRC_IPS_BASE_ADDR(X) + 0x280)
+#define DDRC_DQMAP1(X)           (DDRC_IPS_BASE_ADDR(X) + 0x284)
+#define DDRC_DQMAP2(X)           (DDRC_IPS_BASE_ADDR(X) + 0x288)
+#define DDRC_DQMAP3(X)           (DDRC_IPS_BASE_ADDR(X) + 0x28c)
+#define DDRC_DQMAP4(X)           (DDRC_IPS_BASE_ADDR(X) + 0x290)
+#define DDRC_DQMAP5(X)           (DDRC_IPS_BASE_ADDR(X) + 0x294)
+#define DDRC_DBG0(X)             (DDRC_IPS_BASE_ADDR(X) + 0x300)
+#define DDRC_DBG1(X)             (DDRC_IPS_BASE_ADDR(X) + 0x304)
+#define DDRC_DBGCAM(X)           (DDRC_IPS_BASE_ADDR(X) + 0x308)
+#define DDRC_DBGCMD(X)           (DDRC_IPS_BASE_ADDR(X) + 0x30c)
+#define DDRC_DBGSTAT(X)          (DDRC_IPS_BASE_ADDR(X) + 0x310)
+
+#define DDRC_SWCTL(X)            (DDRC_IPS_BASE_ADDR(X) + 0x320)
+#define DDRC_SWSTAT(X)           (DDRC_IPS_BASE_ADDR(X) + 0x324)
+#define DDRC_OCPARCFG0(X)        (DDRC_IPS_BASE_ADDR(X) + 0x330)
+#define DDRC_OCPARCFG1(X)        (DDRC_IPS_BASE_ADDR(X) + 0x334)
+#define DDRC_OCPARCFG2(X)        (DDRC_IPS_BASE_ADDR(X) + 0x338)
+#define DDRC_OCPARCFG3(X)        (DDRC_IPS_BASE_ADDR(X) + 0x33c)
+#define DDRC_OCPARSTAT0(X)       (DDRC_IPS_BASE_ADDR(X) + 0x340)
+#define DDRC_OCPARSTAT1(X)       (DDRC_IPS_BASE_ADDR(X) + 0x344)
+#define DDRC_OCPARWLOG0(X)       (DDRC_IPS_BASE_ADDR(X) + 0x348)
+#define DDRC_OCPARWLOG1(X)       (DDRC_IPS_BASE_ADDR(X) + 0x34c)
+#define DDRC_OCPARWLOG2(X)       (DDRC_IPS_BASE_ADDR(X) + 0x350)
+#define DDRC_OCPARAWLOG0(X)      (DDRC_IPS_BASE_ADDR(X) + 0x354)
+#define DDRC_OCPARAWLOG1(X)      (DDRC_IPS_BASE_ADDR(X) + 0x358)
+#define DDRC_OCPARRLOG0(X)       (DDRC_IPS_BASE_ADDR(X) + 0x35c)
+#define DDRC_OCPARRLOG1(X)       (DDRC_IPS_BASE_ADDR(X) + 0x360)
+#define DDRC_OCPARARLOG0(X)      (DDRC_IPS_BASE_ADDR(X) + 0x364)
+#define DDRC_OCPARARLOG1(X)      (DDRC_IPS_BASE_ADDR(X) + 0x368)
+#define DDRC_POISONCFG(X)        (DDRC_IPS_BASE_ADDR(X) + 0x36C)
+#define DDRC_POISONSTAT(X)       (DDRC_IPS_BASE_ADDR(X) + 0x370)
+#define DDRC_ADVECCINDEX(X)      (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ADVECCSTAT(X)       (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT0(X)    (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT1(X)    (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT2(X)    (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_HIFCTL(X)           (DDRC_IPS_BASE_ADDR(X) + 0x3)
+
+#define DDRC_PSTAT(X)            (DDRC_IPS_BASE_ADDR(X) + 0x3fc)
+#define DDRC_PCCFG(X)            (DDRC_IPS_BASE_ADDR(X) + 0x400)
+#define DDRC_PCFGR_0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x404)
+#define DDRC_PCFGR_1(X)          (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x404)
+#define DDRC_PCFGR_2(X)          (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x404)
+#define DDRC_PCFGR_3(X)          (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x404)
+#define DDRC_PCFGW_0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x408)
+#define DDRC_PCFGW_1(X)          (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x408)
+#define DDRC_PCFGW_2(X)          (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x408)
+#define DDRC_PCFGW_3(X)          (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x408)
+#define DDRC_PCFGC_0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x40c)
+#define DDRC_PCFGIDMASKCH(X)     (DDRC_IPS_BASE_ADDR(X) + 0x410)
+#define DDRC_PCFGIDVALUECH(X)    (DDRC_IPS_BASE_ADDR(X) + 0x414)
+#define DDRC_PCTRL_0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x490)
+#define DDRC_PCTRL_1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x490 + 1 * 0xb0)
+#define DDRC_PCTRL_2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x490 + 2 * 0xb0)
+#define DDRC_PCTRL_3(X)          (DDRC_IPS_BASE_ADDR(X) + 0x490 + 3 * 0xb0)
+#define DDRC_PCFGQOS0_0(X)       (DDRC_IPS_BASE_ADDR(X) + 0x494)
+#define DDRC_PCFGQOS1_0(X)       (DDRC_IPS_BASE_ADDR(X) + 0x498)
+#define DDRC_PCFGWQOS0_0(X)      (DDRC_IPS_BASE_ADDR(X) + 0x49c)
+#define DDRC_PCFGWQOS1_0(X)      (DDRC_IPS_BASE_ADDR(X) + 0x4a0)
+#define DDRC_SARBASE0(X)         (DDRC_IPS_BASE_ADDR(X) + 0xf04)
+#define DDRC_SARSIZE0(X)         (DDRC_IPS_BASE_ADDR(X) + 0xf08)
+#define DDRC_SBRCTL(X)           (DDRC_IPS_BASE_ADDR(X) + 0xf24)
+#define DDRC_SBRSTAT(X)          (DDRC_IPS_BASE_ADDR(X) + 0xf28)
+#define DDRC_SBRWDATA0(X)        (DDRC_IPS_BASE_ADDR(X) + 0xf2c)
+#define DDRC_SBRWDATA1(X)        (DDRC_IPS_BASE_ADDR(X) + 0xf30)
+#define DDRC_PDCH(X)             (DDRC_IPS_BASE_ADDR(X) + 0xf34)
+
+/* SHADOW registers */
+#define DDRC_FREQ1_DERATEEN(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2020)
+#define DDRC_FREQ1_DERATEINT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2024)
+#define DDRC_FREQ1_RFSHCTL0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2050)
+#define DDRC_FREQ1_RFSHTMG(X)          (DDRC_IPS_BASE_ADDR(X) + 0x2064)
+#define DDRC_FREQ1_INIT3(X)            (DDRC_IPS_BASE_ADDR(X) + 0x20dc)
+#define DDRC_FREQ1_INIT4(X)            (DDRC_IPS_BASE_ADDR(X) + 0x20e0)
+#define DDRC_FREQ1_INIT6(X)            (DDRC_IPS_BASE_ADDR(X) + 0x20e8)
+#define DDRC_FREQ1_INIT7(X)            (DDRC_IPS_BASE_ADDR(X) + 0x20ec)
+#define DDRC_FREQ1_DRAMTMG0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2100)
+#define DDRC_FREQ1_DRAMTMG1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2104)
+#define DDRC_FREQ1_DRAMTMG2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2108)
+#define DDRC_FREQ1_DRAMTMG3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x210c)
+#define DDRC_FREQ1_DRAMTMG4(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2110)
+#define DDRC_FREQ1_DRAMTMG5(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2114)
+#define DDRC_FREQ1_DRAMTMG6(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2118)
+#define DDRC_FREQ1_DRAMTMG7(X)         (DDRC_IPS_BASE_ADDR(X) + 0x211c)
+#define DDRC_FREQ1_DRAMTMG8(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2120)
+#define DDRC_FREQ1_DRAMTMG9(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2124)
+#define DDRC_FREQ1_DRAMTMG10(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2128)
+#define DDRC_FREQ1_DRAMTMG11(X)        (DDRC_IPS_BASE_ADDR(X) + 0x212c)
+#define DDRC_FREQ1_DRAMTMG12(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2130)
+#define DDRC_FREQ1_DRAMTMG13(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2134)
+#define DDRC_FREQ1_DRAMTMG14(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2138)
+#define DDRC_FREQ1_DRAMTMG15(X)        (DDRC_IPS_BASE_ADDR(X) + 0x213C)
+#define DDRC_FREQ1_DRAMTMG16(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2140)
+#define DDRC_FREQ1_DRAMTMG17(X)        (DDRC_IPS_BASE_ADDR(X) + 0x2144)
+#define DDRC_FREQ1_ZQCTL0(X)           (DDRC_IPS_BASE_ADDR(X) + 0x2180)
+#define DDRC_FREQ1_DFITMG0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_FREQ1_DFITMG1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_FREQ1_DFITMG2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_FREQ1_DFITMG3(X)          (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_FREQ1_ODTCFG(X)           (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DDRC_FREQ2_DERATEEN(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3020)
+#define DDRC_FREQ2_DERATEINT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3024)
+#define DDRC_FREQ2_RFSHCTL0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3050)
+#define DDRC_FREQ2_RFSHTMG(X)          (DDRC_IPS_BASE_ADDR(X) + 0x3064)
+#define DDRC_FREQ2_INIT3(X)            (DDRC_IPS_BASE_ADDR(X) + 0x30dc)
+#define DDRC_FREQ2_INIT4(X)            (DDRC_IPS_BASE_ADDR(X) + 0x30e0)
+#define DDRC_FREQ2_INIT6(X)            (DDRC_IPS_BASE_ADDR(X) + 0x30e8)
+#define DDRC_FREQ2_INIT7(X)            (DDRC_IPS_BASE_ADDR(X) + 0x30ec)
+#define DDRC_FREQ2_DRAMTMG0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3100)
+#define DDRC_FREQ2_DRAMTMG1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3104)
+#define DDRC_FREQ2_DRAMTMG2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3108)
+#define DDRC_FREQ2_DRAMTMG3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x310c)
+#define DDRC_FREQ2_DRAMTMG4(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3110)
+#define DDRC_FREQ2_DRAMTMG5(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3114)
+#define DDRC_FREQ2_DRAMTMG6(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3118)
+#define DDRC_FREQ2_DRAMTMG7(X)         (DDRC_IPS_BASE_ADDR(X) + 0x311c)
+#define DDRC_FREQ2_DRAMTMG8(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3120)
+#define DDRC_FREQ2_DRAMTMG9(X)         (DDRC_IPS_BASE_ADDR(X) + 0x3124)
+#define DDRC_FREQ2_DRAMTMG10(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3128)
+#define DDRC_FREQ2_DRAMTMG11(X)        (DDRC_IPS_BASE_ADDR(X) + 0x312c)
+#define DDRC_FREQ2_DRAMTMG12(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3130)
+#define DDRC_FREQ2_DRAMTMG13(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3134)
+#define DDRC_FREQ2_DRAMTMG14(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3138)
+#define DDRC_FREQ2_DRAMTMG15(X)        (DDRC_IPS_BASE_ADDR(X) + 0x313C)
+#define DDRC_FREQ2_DRAMTMG16(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3140)
+#define DDRC_FREQ2_DRAMTMG17(X)        (DDRC_IPS_BASE_ADDR(X) + 0x3144)
+#define DDRC_FREQ2_ZQCTL0(X)           (DDRC_IPS_BASE_ADDR(X) + 0x3180)
+#define DDRC_FREQ2_DFITMG0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x3190)
+#define DDRC_FREQ2_DFITMG1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x3194)
+#define DDRC_FREQ2_DFITMG2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x31b4)
+#define DDRC_FREQ2_DFITMG3(X)          (DDRC_IPS_BASE_ADDR(X) + 0x31b8)
+#define DDRC_FREQ2_ODTCFG(X)           (DDRC_IPS_BASE_ADDR(X) + 0x3240)
+
+#define DDRC_FREQ3_DERATEEN(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4020)
+#define DDRC_FREQ3_DERATEINT(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4024)
+#define DDRC_FREQ3_RFSHCTL0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4050)
+#define DDRC_FREQ3_RFSHTMG(X)          (DDRC_IPS_BASE_ADDR(X) + 0x4064)
+#define DDRC_FREQ3_INIT3(X)            (DDRC_IPS_BASE_ADDR(X) + 0x40dc)
+#define DDRC_FREQ3_INIT4(X)            (DDRC_IPS_BASE_ADDR(X) + 0x40e0)
+#define DDRC_FREQ3_INIT6(X)            (DDRC_IPS_BASE_ADDR(X) + 0x40e8)
+#define DDRC_FREQ3_INIT7(X)            (DDRC_IPS_BASE_ADDR(X) + 0x40ec)
+#define DDRC_FREQ3_DRAMTMG0(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4100)
+#define DDRC_FREQ3_DRAMTMG1(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4104)
+#define DDRC_FREQ3_DRAMTMG2(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4108)
+#define DDRC_FREQ3_DRAMTMG3(X)         (DDRC_IPS_BASE_ADDR(X) + 0x410c)
+#define DDRC_FREQ3_DRAMTMG4(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4110)
+#define DDRC_FREQ3_DRAMTMG5(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4114)
+#define DDRC_FREQ3_DRAMTMG6(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4118)
+#define DDRC_FREQ3_DRAMTMG7(X)         (DDRC_IPS_BASE_ADDR(X) + 0x411c)
+#define DDRC_FREQ3_DRAMTMG8(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4120)
+#define DDRC_FREQ3_DRAMTMG9(X)         (DDRC_IPS_BASE_ADDR(X) + 0x4124)
+#define DDRC_FREQ3_DRAMTMG10(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4128)
+#define DDRC_FREQ3_DRAMTMG11(X)        (DDRC_IPS_BASE_ADDR(X) + 0x412c)
+#define DDRC_FREQ3_DRAMTMG12(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4130)
+#define DDRC_FREQ3_DRAMTMG13(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4134)
+#define DDRC_FREQ3_DRAMTMG14(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4138)
+#define DDRC_FREQ3_DRAMTMG15(X)        (DDRC_IPS_BASE_ADDR(X) + 0x413C)
+#define DDRC_FREQ3_DRAMTMG16(X)        (DDRC_IPS_BASE_ADDR(X) + 0x4140)
+
+#define DDRC_FREQ3_ZQCTL0(X)           (DDRC_IPS_BASE_ADDR(X) + 0x4180)
+#define DDRC_FREQ3_DFITMG0(X)          (DDRC_IPS_BASE_ADDR(X) + 0x4190)
+#define DDRC_FREQ3_DFITMG1(X)          (DDRC_IPS_BASE_ADDR(X) + 0x4194)
+#define DDRC_FREQ3_DFITMG2(X)          (DDRC_IPS_BASE_ADDR(X) + 0x41b4)
+#define DDRC_FREQ3_DFITMG3(X)          (DDRC_IPS_BASE_ADDR(X) + 0x41b8)
+#define DDRC_FREQ3_ODTCFG(X)           (DDRC_IPS_BASE_ADDR(X) + 0x4240)
+#define DDRC_DFITMG0_SHADOW(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_DFITMG1_SHADOW(X)         (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_DFITMG2_SHADOW(X)         (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_DFITMG3_SHADOW(X)         (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_ODTCFG_SHADOW(X)          (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DRC_PERF_MON_BASE_ADDR(X)	(0x3d800000 + ((X) * 0x2000000))
+#define DRC_PERF_MON_CNT0_CTL(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x0)
+#define DRC_PERF_MON_CNT1_CTL(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x4)
+#define DRC_PERF_MON_CNT2_CTL(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x8)
+#define DRC_PERF_MON_CNT3_CTL(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0xC)
+#define DRC_PERF_MON_CNT0_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x20)
+#define DRC_PERF_MON_CNT1_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x24)
+#define DRC_PERF_MON_CNT2_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x28)
+#define DRC_PERF_MON_CNT3_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x2C)
+#define DRC_PERF_MON_DPCR_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x30)
+#define DRC_PERF_MON_MRR0_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x40)
+#define DRC_PERF_MON_MRR1_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x44)
+#define DRC_PERF_MON_MRR2_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x48)
+#define DRC_PERF_MON_MRR3_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x4C)
+#define DRC_PERF_MON_MRR4_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x50)
+#define DRC_PERF_MON_MRR5_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x54)
+#define DRC_PERF_MON_MRR6_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x58)
+#define DRC_PERF_MON_MRR7_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x5C)
+#define DRC_PERF_MON_MRR8_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x60)
+#define DRC_PERF_MON_MRR9_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x64)
+#define DRC_PERF_MON_MRR10_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x68)
+#define DRC_PERF_MON_MRR11_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x6C)
+#define DRC_PERF_MON_MRR12_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x70)
+#define DRC_PERF_MON_MRR13_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x74)
+#define DRC_PERF_MON_MRR14_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x78)
+#define DRC_PERF_MON_MRR15_DAT(X)	(DRC_PERF_MON_BASE_ADDR(X) + 0x7C)
+
+#define dwc_ddrphy_apb_rd(addr)		mmio_read_32(IMX_DDRPHY_BASE + 4 * (addr))
+#define dwc_ddrphy_apb_wr(addr, val)	mmio_write_32(IMX_DDRPHY_BASE + 4 * (addr), val)
+
+#endif /*IMX_DDRC_H */
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
new file mode 100644
index 0000000..3b81801
--- /dev/null
+++ b/plat/imx/imx8m/include/dram.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRAM_H
+#define DRAM_H
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+#include <ddrc.h>
+#include <platform_def.h>
+
+#define DDRC_LPDDR4		BIT(5)
+#define DDRC_DDR4		BIT(4)
+#define DDRC_DDR3L		BIT(0)
+#define DDR_TYPE_MASK		U(0x3f)
+#define ACTIVE_RANK_MASK	U(0x3)
+
+/* reg & config param */
+struct dram_cfg_param {
+	unsigned int reg;
+	unsigned int val;
+};
+
+struct dram_timing_info {
+	/* umctl2 config */
+	struct dram_cfg_param *ddrc_cfg;
+	unsigned int ddrc_cfg_num;
+	/* ddrphy config */
+	struct dram_cfg_param *ddrphy_cfg;
+	unsigned int ddrphy_cfg_num;
+	/* ddr fsp train info */
+	struct dram_fsp_msg *fsp_msg;
+	unsigned int fsp_msg_num;
+	/* ddr phy trained CSR */
+	struct dram_cfg_param *ddrphy_trained_csr;
+	unsigned int ddrphy_trained_csr_num;
+	/* ddr phy PIE */
+	struct dram_cfg_param *ddrphy_pie;
+	unsigned int ddrphy_pie_num;
+	/* initialized fsp table */
+	unsigned int fsp_table[4];
+};
+
+struct dram_info {
+	int dram_type;
+	unsigned int num_rank;
+	int current_fsp;
+	int boot_fsp;
+	struct dram_timing_info *timing_info;
+};
+
+extern struct dram_info dram_info;
+
+void dram_info_init(unsigned long dram_timing_base);
+void dram_umctl2_init(struct dram_timing_info *timing);
+void dram_phy_init(struct dram_timing_info *timing);
+
+/* dram retention */
+void dram_enter_retention(void);
+void dram_exit_retention(void);
+
+#endif /* DRAM_H */