device/dram: add DDR4 MRS commands

Change-Id: I9d4f048c859bc89897d50a5a07468c3375aa1dcf
Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/67059
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
diff --git a/src/device/dram/ddr4.c b/src/device/dram/ddr4.c
index 050857e..37bd4e2 100644
--- a/src/device/dram/ddr4.c
+++ b/src/device/dram/ddr4.c
@@ -301,3 +301,225 @@
 
 	return CB_SUCCESS;
 }
+
+/* Returns MRS command */
+static uint32_t ddr4_wr_to_mr0_map(u8 wr)
+{
+	static const unsigned int enc[] = {0, 1, 2, 3, 4, 5, 7, 6, 8};
+	int wr_idx = wr/2 - 5;
+	if (wr_idx < 0 || wr_idx >= ARRAY_SIZE(enc))
+		die("WR index out of bounds: %d (derived from %d)\n", wr_idx, wr);
+
+	return enc[wr_idx] << 9;
+}
+
+/* Returns MRS command */
+static uint32_t ddr4_cas_to_mr0_map(u8 cas)
+{
+	static const unsigned int enc[] = {
+		/*
+		 * The only non-zero bits are at positions (LSB0): 12, 6, 5, 4, 2.
+		 */
+		0x0000,		/* CL = 9 */
+		0x0004,		/* CL = 10 */
+		0x0010,		/* CL = 11 */
+		0x0014,		/* CL = 12 */
+		0x0020,		/* CL = 13 */
+		0x0024,		/* CL = 14 */
+		0x0030,		/* CL = 15 */
+		0x0034,		/* CL = 16 */
+		0x0064,		/* CL = 17 */
+		0x0040,		/* CL = 18 */
+		0x0070,		/* CL = 19 */
+		0x0044,		/* CL = 20 */
+		0x0074,		/* CL = 21 */
+		0x0050,		/* CL = 22 */
+		0x0060,		/* CL = 23 */
+		0x0054,		/* CL = 24 */
+		0x1000,		/* CL = 25 */
+		0x1004,		/* CL = 26 */
+		0x1010,		/* CL = 27 (only 3DS) */
+		0x1014,		/* CL = 28 */
+		0x1020,		/* reserved for CL = 29 */
+		0x1024,		/* CL = 30 */
+		0x1030,		/* reserved for CL = 31 */
+		0x1034,		/* CL = 32 */
+	};
+
+	int cas_idx = cas - 9;
+	if (cas_idx < 0 || cas_idx >= ARRAY_SIZE(enc))
+		die("CAS index out of bounds: %d (derived from %d)\n", cas_idx, cas);
+
+	return enc[cas_idx];
+}
+
+uint32_t ddr4_get_mr0(u8 write_recovery,
+		      enum ddr4_mr0_dll_reset dll_reset,
+		      u8 cas,
+		      enum ddr4_mr0_burst_type burst_type,
+		      enum ddr4_mr0_burst_length burst_length)
+{
+	uint32_t cmd = 0 << 20;
+
+	cmd |= ddr4_wr_to_mr0_map(write_recovery);
+	cmd |= dll_reset << 8;
+	cmd |= DDR4_MR0_MODE_NORMAL << 7;
+	cmd |= ddr4_cas_to_mr0_map(cas);
+	cmd |= burst_type << 3;
+	cmd |= burst_length << 0;
+
+	return cmd;
+}
+
+uint32_t ddr4_get_mr1(enum ddr4_mr1_qoff qoff,
+		      enum ddr4_mr1_tdqs tdqs,
+		      enum ddr4_mr1_rtt_nom rtt_nom,
+		      enum ddr4_mr1_write_leveling write_leveling,
+		      enum ddr4_mr1_odimp output_drive_impedance,
+		      enum ddr4_mr1_additive_latency additive_latency,
+		      enum ddr4_mr1_dll dll_enable)
+{
+	uint32_t cmd = 1 << 20;
+
+	cmd |= qoff << 12;
+	cmd |= tdqs << 11;
+	cmd |= rtt_nom << 8;
+	cmd |= write_leveling << 7;
+	cmd |= output_drive_impedance << 1;
+	cmd |= additive_latency << 3;
+	cmd |= dll_enable << 0;
+
+	return cmd;
+}
+
+/* Returns MRS command */
+static uint32_t ddr4_cwl_to_mr2_map(u8 cwl)
+{
+	/* Encoding is (starting with 0): 9, 10, 11, 12, 14, 16, 18, 20 */
+	if (cwl < 14)
+		cwl -= 9;
+	else
+		cwl = (cwl - 14) / 2 + 4;
+
+	return cwl << 3;
+}
+
+uint32_t ddr4_get_mr2(enum ddr4_mr2_wr_crc wr_crc,
+		      enum ddr4_mr2_rtt_wr rtt_wr,
+		      enum ddr4_mr2_lp_asr self_refresh, u8 cwl)
+{
+	uint32_t cmd = 2 << 20;
+
+	cmd |= wr_crc << 12;
+	cmd |= rtt_wr << 9;
+	cmd |= self_refresh << 6;
+	cmd |= ddr4_cwl_to_mr2_map(cwl);
+
+	return cmd;
+}
+
+uint32_t ddr4_get_mr3(enum ddr4_mr3_mpr_read_format mpr_read_format,
+		      enum ddr4_mr3_wr_cmd_lat_crc_dm command_latency_crc_dm,
+		      enum ddr4_mr3_fine_gran_ref fine_refresh,
+		      enum ddr4_mr3_temp_sensor_readout temp_sensor,
+		      enum ddr4_mr3_pda pda,
+		      enum ddr4_mr3_geardown_mode geardown,
+		      enum ddr4_mr3_mpr_operation mpr_operation,
+		      u8 mpr_page)
+{
+	uint32_t cmd = 3 << 20;
+
+	cmd |= mpr_read_format << 11;
+	cmd |= command_latency_crc_dm << 9;
+	cmd |= fine_refresh << 6;
+	cmd |= temp_sensor << 5;
+	cmd |= pda << 4;
+	cmd |= geardown << 3;
+	cmd |= mpr_operation << 2;
+	cmd |= (mpr_page & 3) << 0;
+
+	return cmd;
+}
+
+uint32_t ddr4_get_mr4(enum ddr4_mr4_hppr hppr,
+		      enum ddr4_mr4_wr_preamble wr_preamble,
+		      enum ddr4_mr4_rd_preamble rd_preamble,
+		      enum ddr4_mr4_rd_preamble_training rd_preamble_train,
+		      enum ddr4_mr4_self_refr_abort self_ref_abrt,
+		      enum ddr4_mr4_cs_to_cmd_latency cs2cmd_lat,
+		      enum ddr4_mr4_sppr sppr,
+		      enum ddr4_mr4_internal_vref_mon int_vref_mon,
+		      enum ddr4_mr4_temp_controlled_refr temp_ctrl_ref,
+		      enum ddr4_mr4_max_pd_mode max_pd)
+{
+	uint32_t cmd = 4 << 20;
+
+	cmd |= hppr << 13;
+	cmd |= wr_preamble << 12;
+	cmd |= rd_preamble << 11;
+	cmd |= rd_preamble_train << 10;
+	cmd |= self_ref_abrt << 9;
+	cmd |= cs2cmd_lat << 6;
+	cmd |= sppr << 5;
+	cmd |= int_vref_mon << 4;
+	cmd |= temp_ctrl_ref << 2;
+	cmd |= max_pd << 1;
+
+	return cmd;
+}
+
+uint32_t ddr4_get_mr5(enum ddr4_mr5_rd_dbi rd_dbi,
+		      enum ddr4_mr5_wr_dbi wr_dbi,
+		      enum ddr4_mr5_data_mask dm,
+		      enum ddr4_mr5_rtt_park rtt_park,
+		      enum ddr4_mr5_odt_pd odt_pd,
+		      enum ddr4_mr5_ca_parity_lat pl)
+{
+	uint32_t cmd = 5 << 20;
+
+	cmd |= rd_dbi << 12;
+	cmd |= wr_dbi << 11;
+	cmd |= dm << 10;
+	cmd |= rtt_park << 6;
+	cmd |= odt_pd << 5;
+	cmd |= pl << 0;
+
+	return cmd;
+}
+
+/* Returns MRS command */
+static uint32_t ddr4_tccd_l_to_mr6_map(u8 tccd_l)
+{
+	if (tccd_l < 4 || tccd_l > 8)
+		die("tCCD_l out of range: %d\n", tccd_l);
+
+	return (tccd_l - 4) << 10;
+}
+
+uint32_t ddr4_get_mr6(u8 tccd_l,
+		      enum ddr4_mr6_vrefdq_training vrefdq_training,
+		      enum ddr4_mr6_vrefdq_training_range range,
+		      u8 vrefdq_value)
+{
+	uint32_t cmd = 6 << 20;
+
+	cmd |= ddr4_tccd_l_to_mr6_map(tccd_l);
+	cmd |= vrefdq_training << 7;
+	cmd |= range << 6;
+	cmd |= vrefdq_value & 0x3F;
+
+	return cmd;
+}
+
+/*
+ * ZQCL: A16 = H, A15 = H, A14 = L, A10 = H, rest either L or H
+ * ZQCS: A16 = H, A15 = H, A14 = L, A10 = L, rest either L or H
+ */
+uint32_t ddr4_get_zqcal_cmd(enum ddr4_zqcal_ls long_short)
+{
+	uint32_t cmd = 1 << 16 | 1 << 15;
+
+	cmd |= long_short << 10;
+
+	return cmd;
+}
diff --git a/src/include/device/dram/ddr4.h b/src/include/device/dram/ddr4.h
index ee7a1ea..6b05288 100644
--- a/src/include/device/dram/ddr4.h
+++ b/src/include/device/dram/ddr4.h
@@ -74,4 +74,307 @@
  */
 uint16_t ddr4_speed_mhz_to_reported_mts(uint16_t speed_mhz);
 
+/**
+ * \brief Representation of an MRS command
+ *
+ * This represents an MRS command as seen by the DIMM. This is not a memory
+ * address that can be read to generate an MRS command. The mapping of CPU
+ * to memory pins is hardware-dependent.
+ * \n
+ * The idea is to generalize the MRS code, and only need a hardware-specific
+ * function to map the MRS bits to CPU address bits. An MRS command can be
+ * sent like:
+ * @code{.c}
+ *	uint32_t addr;
+ *	uint32_t mrs;
+ *	chipset_enable_mrs_command_mode();
+ *	mrs = ddr4_get_mr0(rtt_wr, srt, cas, asr, cwl)
+ *	if (rank_has_mirrorred_pins)
+ *		mrs = ddr4_mrs_mirror_pins(mrs);
+ *	addr = chipset_specific_get_mrs_addr(mrs);
+ *	volatile_read(addr);
+ * @endcode
+ *
+ * The MRS representation has the following structure:
+ *	- cmd[17:0] = Address pins A[13:0]
+ *	- cmd[21:20] = Bank address BA[1:0]
+ *	- cmd[23:22] = Bank group BG[1:0]
+ *
+ * Address pins A[16:14] are always low for MRS commands. A17 is reserved for
+ * future use, cmd[19:18] is left as a placeholder in case it is needed.
+ */
+
+/* Swap A3<->A4, A5<->A6, A7<->A8, A11<->A13, BA0<->BA1, BG0<->BG1 */
+static inline uint32_t ddr4_mrs_mirror_pins(uint32_t mrs_cmd)
+{
+	mrs_cmd = (mrs_cmd & 0x5000A8) << 1 |
+		  (mrs_cmd & 0xA00150) >> 1 |
+		  (mrs_cmd & ~0xF001F8);
+	mrs_cmd = (mrs_cmd & 0x000800) << 2 |
+		  (mrs_cmd & 0x002000) >> 2 |
+		  (mrs_cmd & ~0x002800);
+	return mrs_cmd;
+}
+
+enum ddr4_mr0_mode {
+	DDR4_MR0_MODE_NORMAL = 0,
+	DDR4_MR0_MODE_TEST =   1,
+};
+enum ddr4_mr0_dll_reset {
+	DDR4_MR0_DLL_RESET_NO =  0,
+	DDR4_MR0_DLL_RESET_YES = 1,
+};
+enum ddr4_mr0_burst_type {
+	DDR4_MR0_BURST_TYPE_SEQUENTIAL =  0,
+	DDR4_MR0_BURST_TYPE_INTERLEAVED = 1,
+};
+enum ddr4_mr0_burst_length {
+	DDR4_MR0_BURST_LENGTH_FIXED_8    = 0,
+	DDR4_MR0_BURST_LENGTH_ON_THE_FLY = 1,
+	DDR4_MR0_BURST_LENGTH_FIXED_4    = 2,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr0(u8 write_recovery,
+		      enum ddr4_mr0_dll_reset dll_reset,
+		      u8 cas,
+		      enum ddr4_mr0_burst_type burst_type,
+		      enum ddr4_mr0_burst_length burst_length);
+
+enum ddr4_mr1_qoff {
+	DDR4_MR1_QOFF_ENABLE =  0,
+	DDR4_MR1_QOFF_DISABLE = 1,
+};
+enum ddr4_mr1_tdqs {
+	DDR4_MR1_TDQS_DISABLE = 0,
+	DDR4_MR1_TDQS_ENABLE =  1,
+};
+enum ddr4_mr1_rtt_nom {
+	DDR4_MR1_RTT_NOM_OFF =   0,
+	DDR4_MR1_RTT_NOM_RZQ_4 = 1,
+	DDR4_MR1_RTT_NOM_RZQ_2 = 2,
+	DDR4_MR1_RTT_NOM_RZQ_6 = 3,
+	DDR4_MR1_RTT_NOM_RZQ_1 = 4,
+	DDR4_MR1_RTT_NOM_RZQ_5 = 5,
+	DDR4_MR1_RTT_NOM_RZQ_3 = 6,
+	DDR4_MR1_RTT_NOM_RZQ_7 = 7,
+};
+enum ddr4_mr1_write_leveling {
+	DDR4_MR1_WRLVL_DISABLE = 0,
+	DDR4_MR1_WRLVL_ENABLE =  1,
+};
+enum ddr4_mr1_additive_latency {
+	DDR4_MR1_AL_DISABLE =    0,
+	DDR4_MR1_AL_CL_MINUS_1 = 1,
+	DDR4_MR1_AL_CL_MINUS_2 = 2,
+};
+enum ddr4_mr1_odimp {
+	DDR4_MR1_ODIMP_RZQ_7 = 0,
+	DDR4_MR1_ODIMP_RZQ_5 = 1,
+};
+enum ddr4_mr1_dll {
+	DDR4_MR1_DLL_DISABLE = 0,
+	DDR4_MR1_DLL_ENABLE =  1,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr1(enum ddr4_mr1_qoff qoff,
+		      enum ddr4_mr1_tdqs tdqs,
+		      enum ddr4_mr1_rtt_nom rtt_nom,
+		      enum ddr4_mr1_write_leveling write_leveling,
+		      enum ddr4_mr1_odimp output_drive_impedance,
+		      enum ddr4_mr1_additive_latency additive_latency,
+		      enum ddr4_mr1_dll dll_enable);
+
+enum ddr4_mr2_wr_crc {
+	DDR4_MR2_WR_CRC_DISABLE = 0,
+	DDR4_MR2_WR_CRC_ENABLE =  1,
+};
+enum ddr4_mr2_rtt_wr {
+	DDR4_MR2_RTT_WR_OFF =   0,
+	DDR4_MR2_RTT_WR_RZQ_2 = 1,
+	DDR4_MR2_RTT_WR_RZQ_1 = 2,
+	DDR4_MR2_RTT_WR_HI_Z =  3,
+	DDR4_MR2_RTT_WR_RZQ_3 = 4,
+};
+enum ddr4_mr2_lp_asr {
+	DDR4_MR2_ASR_MANUAL_NORMAL_RANGE =   0,
+	DDR4_MR2_ASR_MANUAL_REDUCED_RANGE =  1,
+	DDR4_MR2_ASR_MANUAL_EXTENDED_RANGE = 2,
+	DDR4_MR2_ASR_AUTO =                  3,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr2(enum ddr4_mr2_wr_crc wr_crc,
+		      enum ddr4_mr2_rtt_wr rtt_wr,
+		      enum ddr4_mr2_lp_asr self_refresh, u8 cwl);
+
+enum ddr4_mr3_mpr_read_format {
+	DDR4_MR3_MPR_SERIAL =    0,
+	DDR4_MR3_MPR_PARALLEL =  1,
+	DDR4_MR3_MPR_STAGGERED = 2,
+};
+enum ddr4_mr3_wr_cmd_lat_crc_dm {
+	DDR4_MR3_CRC_DM_4 = 0,
+	DDR4_MR3_CRC_DM_5 = 1,
+	DDR4_MR3_CRC_DM_6 = 2,
+};
+enum ddr4_mr3_fine_gran_ref {
+	DDR4_MR3_FINE_GRAN_REF_NORMAL       = 0,
+	DDR4_MR3_FINE_GRAN_REF_FIXED_2      = 1,
+	DDR4_MR3_FINE_GRAN_REF_FIXED_4      = 2,
+	/* Two reserved values */
+	DDR4_MR3_FINE_GRAN_REF_ON_THE_FLY_2 = 5,
+	DDR4_MR3_FINE_GRAN_REF_ON_THE_FLY_4 = 6,
+};
+enum ddr4_mr3_temp_sensor_readout {
+	DDR4_MR3_TEMP_SENSOR_DISABLE = 0,
+	DDR4_MR3_TEMP_SENSOR_ENABLE =  1,
+};
+enum ddr4_mr3_pda {
+	DDR4_MR3_PDA_DISABLE = 0,
+	DDR4_MR3_PDA_ENABLE =  1,
+};
+enum ddr4_mr3_geardown_mode {
+	DDR4_MR3_GEARDOWN_1_2_RATE = 0,
+	DDR4_MR3_GEARDOWN_1_4_RATE = 1,
+};
+enum ddr4_mr3_mpr_operation {
+	DDR4_MR3_MPR_NORMAL = 0,
+	DDR4_MR3_MPR_MPR =    1,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr3(enum ddr4_mr3_mpr_read_format mpr_read_format,
+		      enum ddr4_mr3_wr_cmd_lat_crc_dm command_latency_crc_dm,
+		      enum ddr4_mr3_fine_gran_ref fine_refresh,
+		      enum ddr4_mr3_temp_sensor_readout temp_sensor,
+		      enum ddr4_mr3_pda pda,
+		      enum ddr4_mr3_geardown_mode geardown,
+		      enum ddr4_mr3_mpr_operation mpr_operation,
+		      u8 mpr_page);
+
+enum ddr4_mr4_hppr {
+	DDR4_MR4_HPPR_DISABLE = 0,
+	DDR4_MR4_HPPR_ENABLE =  1,
+};
+enum ddr4_mr4_wr_preamble {
+	DDR4_MR4_WR_PREAMBLE_1 = 0,
+	DDR4_MR4_WR_PREAMBLE_2 = 1,
+};
+enum ddr4_mr4_rd_preamble {
+	DDR4_MR4_RD_PREAMBLE_1 = 0,
+	DDR4_MR4_RD_PREAMBLE_2 = 1,
+};
+enum ddr4_mr4_rd_preamble_training {
+	DDR4_MR4_RD_PREAMBLE_TRAINING_DISABLE = 0,
+	DDR4_MR4_RD_PREAMBLE_TRAINING_ENABLE =  1,
+};
+enum ddr4_mr4_self_refr_abort {
+	DDR4_MR4_SELF_REFRESH_ABORT_DISABLE = 0,
+	DDR4_MR4_SELF_REFRESH_ABORT_ENABLE =  1,
+};
+enum ddr4_mr4_cs_to_cmd_latency {
+	DDR4_MR4_CS_TO_CMD_LAT_DISABLE = 0,
+	DDR4_MR4_CS_TO_CMD_LAT_3 =       1,
+	DDR4_MR4_CS_TO_CMD_LAT_4 =       2,
+	DDR4_MR4_CS_TO_CMD_LAT_5 =       3,
+	DDR4_MR4_CS_TO_CMD_LAT_6 =       4,
+	DDR4_MR4_CS_TO_CMD_LAT_8 =       5,
+};
+enum ddr4_mr4_sppr {
+	DDR4_MR4_SPPR_DISABLE = 0,
+	DDR4_MR4_SPPR_ENABLE =  1,
+};
+enum ddr4_mr4_internal_vref_mon {
+	DDR4_MR4_INTERNAL_VREF_MON_DISABLE = 0,
+	DDR4_MR4_INTERNAL_VREF_MON_ENABLE =  1,
+};
+enum ddr4_mr4_temp_controlled_refr {
+	DDR4_MR4_TEMP_CONTROLLED_REFR_DISABLE =  0,
+	DDR4_MR4_TEMP_CONTROLLED_REFR_NORMAL =   2,
+	DDR4_MR4_TEMP_CONTROLLED_REFR_EXTENDED = 3,
+};
+enum ddr4_mr4_max_pd_mode {
+	DDR4_MR4_MAX_PD_MODE_DISABLE = 0,
+	DDR4_MR4_MAX_PD_MODE_ENABLE =  1,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr4(enum ddr4_mr4_hppr hppr,
+		      enum ddr4_mr4_wr_preamble wr_preamble,
+		      enum ddr4_mr4_rd_preamble rd_preamble,
+		      enum ddr4_mr4_rd_preamble_training rd_preamble_train,
+		      enum ddr4_mr4_self_refr_abort self_ref_abrt,
+		      enum ddr4_mr4_cs_to_cmd_latency cs2cmd_lat,
+		      enum ddr4_mr4_sppr sppr,
+		      enum ddr4_mr4_internal_vref_mon int_vref_mon,
+		      enum ddr4_mr4_temp_controlled_refr temp_ctrl_ref,
+		      enum ddr4_mr4_max_pd_mode max_pd);
+
+enum ddr4_mr5_rd_dbi {
+	DDR4_MR5_RD_DBI_DISABLE = 0,
+	DDR4_MR5_RD_DBI_ENABLE =  1,
+};
+enum ddr4_mr5_wr_dbi {
+	DDR4_MR5_WR_DBI_DISABLE = 0,
+	DDR4_MR5_WR_DBI_ENABLE =  1,
+};
+enum ddr4_mr5_data_mask {
+	DDR4_MR5_DATA_MASK_DISABLE = 0,
+	DDR4_MR5_DATA_MASK_ENABLE =  1,
+};
+enum ddr4_mr5_rtt_park {
+	DDR4_MR5_RTT_PARK_OFF =   0,
+	DDR4_MR5_RTT_PARK_RZQ_4 = 1,
+	DDR4_MR5_RTT_PARK_RZQ_2 = 2,
+	DDR4_MR5_RTT_PARK_RZQ_6 = 3,
+	DDR4_MR5_RTT_PARK_RZQ_1 = 4,
+	DDR4_MR5_RTT_PARK_RZQ_5 = 5,
+	DDR4_MR5_RTT_PARK_RZQ_3 = 6,
+	DDR4_MR5_RTT_PARK_RZQ_7 = 7,
+};
+enum ddr4_mr5_odt_pd {
+	DDR4_MR5_ODT_PD_ACTIVADED =   0,
+	DDR4_MR5_ODT_PD_DEACTIVADED = 1,
+};
+enum ddr4_mr5_ca_parity_lat {
+	DDR4_MR5_CA_PARITY_LAT_DISABLE = 0,
+	DDR4_MR5_CA_PARITY_LAT_4 =       1, /* 1600-2133 MT/s */
+	DDR4_MR5_CA_PARITY_LAT_5 =       2, /* 2400-2666 MT/s */
+	DDR4_MR5_CA_PARITY_LAT_6 =       3, /* 2933-3200 MT/s */
+	DDR4_MR5_CA_PARITY_LAT_8 =       4, /* RFU */
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr5(enum ddr4_mr5_rd_dbi rd_dbi,
+		      enum ddr4_mr5_wr_dbi wr_dbi,
+		      enum ddr4_mr5_data_mask dm,
+		      enum ddr4_mr5_rtt_park rtt_park,
+		      enum ddr4_mr5_odt_pd odt_pd,
+		      enum ddr4_mr5_ca_parity_lat pl);
+
+enum ddr4_mr6_vrefdq_training {
+	DDR4_MR6_VREFDQ_TRAINING_DISABLE = 0,
+	DDR4_MR6_VREFDQ_TRAINING_ENABLE =  1,
+};
+enum ddr4_mr6_vrefdq_training_range {
+	DDR4_MR6_VREFDQ_TRAINING_RANGE_1 = 0, /* 60% to 92.50% in 0.65% steps */
+	DDR4_MR6_VREFDQ_TRAINING_RANGE_2 = 1, /* 40% to 77.50% in 0.65% steps */
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_mr6(u8 tccd_l,
+		      enum ddr4_mr6_vrefdq_training vrefdq_training,
+		      enum ddr4_mr6_vrefdq_training_range range,
+		      u8 vrefdq_value);
+
+enum ddr4_zqcal_ls {
+	DDR4_ZQCAL_SHORT = 0,
+	DDR4_ZQCAL_LONG =  1,
+};
+
+/* Returns MRS command */
+uint32_t ddr4_get_zqcal_cmd(enum ddr4_zqcal_ls long_short);
+
 #endif /* DEVICE_DRAM_DDR4L_H */