{ DDRC_FREQ2_INIT3(0), DDRC_FREQ2_INIT4(0), DDRC_FREQ2_INIT6(0), DDRC_FREQ2_INIT7(0) },
};
+#if defined(PLAT_imx8mp)
+static uint32_t lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
+{
+ unsigned int tmp, drate_byte;
+
+ tmp = mmio_read_32(DRC_PERF_MON_MRR0_DAT(0));
+ mmio_write_32(DRC_PERF_MON_MRR0_DAT(0), tmp | 0x1);
+ do {
+ tmp = mmio_read_32(DDRC_MRSTAT(0));
+ } while (tmp & 0x1);
+
+ mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
+ mmio_write_32(DDRC_MRCTRL1(0), (mr_addr << 8));
+ mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4) | BIT(31) | 0x1);
+
+ /* Workaround for SNPS STAR 9001549457 */
+ do {
+ tmp = mmio_read_32(DDRC_MRSTAT(0));
+ } while (tmp & 0x1);
+
+ do {
+ tmp = mmio_read_32(DRC_PERF_MON_MRR0_DAT(0));
+ } while (!(tmp & 0x8));
+ tmp = mmio_read_32(DRC_PERF_MON_MRR1_DAT(0));
+
+ drate_byte = (mmio_read_32(DDRC_DERATEEN(0)) >> 4) & 0xff;
+ tmp = (tmp >> (drate_byte * 8)) & 0xff;
+ mmio_write_32(DRC_PERF_MON_MRR0_DAT(0), 0x4);
+
+ return tmp;
+}
+#endif
+
static void get_mr_values(uint32_t (*mr_value)[8])
{
uint32_t init_val;
mr_value[fsp_index][2*i] = init_val >> 16;
mr_value[fsp_index][2*i + 1] = init_val & 0xFFFF;
}
+
+#if defined(PLAT_imx8mp)
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ mr_value[fsp_index][5] = lpddr4_mr_read(1, MR12); /* read MR12 from DRAM */
+ mr_value[fsp_index][7] = lpddr4_mr_read(1, MR14); /* read MR14 from DRAM */
+ }
+#endif
}
}
/*
- * Copyright 2020-2022 NXP
+ * Copyright 2020-2023 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#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_DDR_IPS_SIZE U(0x1900000)
#define IMX_ROM_BASE U(0x0)
#define IMX_ROM_SIZE U(0x40000)
#define IMX_NS_OCRAM_BASE U(0x900000)