[coreboot-gerrit] Change in coreboot[master]: mediatek/mt8183: Add DDR driver of runtime config part

Tristan Hsieh (Code Review) gerrit at coreboot.org
Mon Oct 1 06:44:05 CEST 2018


Tristan Hsieh has uploaded this change for review. ( https://review.coreboot.org/28844


Change subject: mediatek/mt8183: Add DDR driver of runtime config part
......................................................................

mediatek/mt8183: Add DDR driver of runtime config part

BUG=b:80501386
BRANCH=none
TEST=Boots correctly on Kukui, and inits DRAM successfully with related
     patches.

Change-Id: Id1e8862ff6feb9628d37fe5300780ff56865a563
Signed-off-by: Huayang Duan <huayang.duan at mediatek.com>
---
M src/soc/mediatek/mt8183/dramc_pi_basic_api.c
M src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
M src/soc/mediatek/mt8183/emi.c
M src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
4 files changed, 228 insertions(+), 2 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/44/28844/1

diff --git a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
index 74eddd5..b172e16 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c
@@ -16,6 +16,7 @@
 #include <arch/io.h>
 #include <delay.h>
 #include <soc/emi.h>
+#include <soc/spm.h>
 #include <soc/dramc_register.h>
 #include <soc/dramc_pi_api.h>
 
@@ -132,3 +133,212 @@
 	dramc_set_broadcast(broadcast_bak);
 }
 
+static void transfer_pll_to_spm_control(void)
+{
+	u8 shu_lev = (read32(&ch[0].ao.shustatus) & 0x00000006) >> 1;
+
+	/* set SPM project code and enable clock enable */
+	clrsetbits_le32(&mtk_spm->poweron_config_set,
+		(0xffff << 16) | (0x1 << 0),
+		(0xb16 << 16) | (0x1 << 0));
+
+	/* set SPM pinmux */
+	clrbits_le32(&mtk_spm->pcm_pwr_io_en, (0xff << 0) | (0xff << 16));
+	setbits_le32(&mtk_spm->dramc_dpy_clk_sw_con_sel, 0xffffffff << 0);
+	setbits_le32(&mtk_spm->dramc_dpy_clk_sw_con_sel2, 0xffffffff << 0);
+
+	setbits_le32(&mtk_spm->spm_power_on_val0, (0x1 << 8) | (0xf << 12));
+	setbits_le32(&mtk_spm->spm_s1_mode_ch, 0x3 << 0);
+
+	shu_lev = (shu_lev == 1) ? 2 : 1;
+	clrsetbits_le32(&mtk_spm->spm_power_on_val0, 0x3 << 28, shu_lev << 28);
+	clrsetbits_le32(&mtk_spm->dramc_dpy_clk_sw_con2,
+		0x3 << 2, shu_lev << 2);
+
+	udelay(1);
+	for (u8 chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) {
+		clrbits_le32(&ch[chn].phy.pll1, 0x1 << 31);
+		clrbits_le32(&ch[chn].phy.pll2, 0x1 << 31);
+	}
+}
+
+static void dramc_rx_input_delay_tracking(u8 chn)
+{
+	/* Enable RX_FIFO macro DIV4 clock CG */
+	write32(&ch[chn].phy.misc_cg_ctrl1, 0xffffffff);
+
+	/* DVS mode to RG mode */
+	for (u8 r = 0; r < 2; r++)
+		for (u8 b = 0; b < 2; b++)
+			clrbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[2], 3 << 30);
+
+	clrsetbits_le32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 19), (0x1 << 9));
+	clrsetbits_le32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 19), (0x1 << 9));
+
+	for (size_t b = 0; b < 2; b++) {
+		/* tracking rising and update rising/falling together */
+		clrbits_le32(&ch[chn].phy.r[0].b[b].rxdvs[2], (0x1 << 29));
+		clrbits_le32(&ch[chn].phy.r[1].b[b].rxdvs[2], (0x1 << 29));
+
+		/* DQS, DQ, DQM (DQ, DQM are tied together now)
+		 * -> controlled using DQM MAX_MIN */
+		clrsetbits_le32(&ch[chn].phy.r[0].b[b].rxdvs[7],
+			(0x3f << 0) | (0x3f << 8) | (0x7f << 16) | (0x7f << 24),
+			(0x0 << 0) | (0x3f << 8) | (0x0 << 16) | (0x7f << 24));
+		clrsetbits_le32(&ch[chn].phy.r[0].b[b].rxdvs[1],
+			(0xffff << 16) | (0xffff << 0),
+			(0x2 << 16) | (0x2 << 0));
+
+		/* DQ/DQS Rx DLY adjustment for tracking mode */
+		clrbits_le32(&ch[chn].phy.r[0].b[b].rxdvs[2],
+			(0x3 << 26) | (0x3 << 24) | (0x3 << 18) | (0x3 << 16));
+
+		/* DQS, DQ, DQM (DQ, DQM are tied together now)
+		 * -> controlled using DQM MAX_MIN */
+		clrsetbits_le32(&ch[chn].phy.r[1].b[b].rxdvs[7],
+			(0x3f << 0) | (0x3f << 8) | (0x7f << 16) | (0x7f << 24),
+			(0x0 << 0) | (0x3f << 8) | (0x0 << 16) | (0x7f << 24));
+		clrsetbits_le32(&ch[chn].phy.r[1].b[b].rxdvs[1],
+			(0xffff << 16) | (0xffff << 0),
+			(0x2 << 16) | (0x2 << 0));
+
+		/* DQ/DQS Rx DLY adjustment for tracking mode */
+		clrbits_le32(&ch[chn].phy.r[1].b[b].rxdvs[2],
+			(0x3 << 26) | (0x3 << 24));
+		clrbits_le32(&ch[chn].phy.r[1].b[b].rxdvs[2],
+			(0x3 << 18) | (0x3 << 16));
+	}
+
+	clrbits_le32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
+
+	/* Rx DLY tracking setting (Static) */
+	clrsetbits_le32(&ch[chn].phy.b0_rxdvs[0],
+		(0x1 << 29) | (0xf << 4) | (0x1 << 0),
+		(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
+	clrsetbits_le32(&ch[chn].phy.b1_rxdvs[0],
+		(0x1 << 29) | (0xf << 4) | (0x1 << 0),
+		(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
+
+	for (u8 b = 0; b < 2; b++) {
+		clrsetbits_le32(&ch[chn].phy.b[b].dq[9],
+			(0x7 << 28) | (0x7 << 24),
+			(0x1 << 28) | (0x0 << 24));
+		setbits_le32(&ch[chn].phy.b[b].dq[5], (0x1 << 31));
+	}
+
+	setbits_le32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 28) | (0x1 << 31));
+	setbits_le32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31));
+	for (u8 rank = RANK_0; rank < RANK_MAX; rank++)
+		for (u8 b = 0; b < 2; b++)
+			clrsetbits_le32(&ch[chn].phy.r[rank].b[b].rxdvs[2],
+				(0x3 << 30) | (0x1 << 28) | (0x1 << 23),
+				(0x2 << 30) | (0x1 << 28) | (0x1 << 23));
+
+}
+
+static void dramc_hw_dqs_gating_tracking(u8 chn)
+{
+	setbits_le32(&ch[chn].ao.stbcal, (0x3 << 26) | (0x1 << 0));
+	clrsetbits_le32(&ch[chn].ao.stbcal1,
+		(0xffff << 16) | (0x1 << 8) | (0x1 << 6),
+		(0x1 << 16) | (0x1 << 8) | (0x0 << 6));
+
+	clrsetbits_le32(&ch[chn].phy.misc_ctrl0,
+		(0x1 << 24) | (0x1f << 11) | (0xf << 0),
+		(0x1 << 24) | (0x0 << 11) | (0x0 << 0));
+
+	clrbits_le32(&ch[chn].phy.b[0].dq[6], (0x1 << 31));
+	clrbits_le32(&ch[chn].phy.b[1].dq[6], (0x1 << 31));
+	clrbits_le32(&ch[chn].phy.ca_cmd[6], (0x1 << 31));
+}
+
+static void dramc_hw_gating_init(void)
+{
+	for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
+		clrbits_le32(&ch[chn].ao.stbcal,
+			(0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
+		setbits_le32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
+		setbits_le32(&ch[chn].phy.misc_ctrl1, (0x1 << 24));
+
+		dramc_hw_dqs_gating_tracking(chn);
+	}
+}
+
+static void dramc_impedance_tracking_enable(void)
+{
+	u8 chn;
+
+	setbits_le32(&ch[0].phy.misc_ctrl0, (0x1 << 10));
+	for (chn = 0; chn < CHANNEL_MAX; chn++) {
+		setbits_le32(&ch[chn].ao.impcal, (0x1 << 31) | (0x1 << 29) |
+			(0x1 << 26) | (0x1 << 17) | (0x7 << 11));
+		clrbits_le32(&ch[chn].ao.impcal, (0x1 << 30));
+		setbits_le32(&ch[chn].phy.misc_ctrl0, (0x1 << 18));
+		setbits_le32(&ch[chn].ao.impcal, (0x1 << 19));
+	}
+	setbits_le32(&ch[0].ao.impcal, (0x1 << 14));
+	setbits_le32(&ch[1].ao.refctrl0, (0x1 << 2));
+	for (chn = 0; chn < CHANNEL_MAX; chn++)
+		setbits_le32(&ch[chn].ao.refctrl0, (0x1 << 3));
+}
+
+void dramc_runtime_config(void)
+{
+	u8 chn = 0, shu = 0, shu_cnt = DRAM_DFS_SHUFFLE_MAX;
+
+	clrbits_le32(&ch[0].ao.refctrl0, (0x1 << 29));
+	clrbits_le32(&ch[1].ao.refctrl0, (0x1 << 29));
+
+	transfer_pll_to_spm_control();
+	setbits_le32(&mtk_spm->spm_power_on_val0, (0x3 << 25));
+
+	dramc_dbg("TX_TRACKING: OFF\n");
+	for (chn = 0; chn < CHANNEL_MAX; chn++)
+		dramc_rx_input_delay_tracking(chn);
+	dramc_dbg("RX_TRACKING: ON\n");
+
+	dramc_hw_gating_init();
+	dramc_hw_gating_onoff(CHANNEL_A, GATING_ON);
+	dramc_dbg("HW_GATING: ON\n");
+
+	for (chn = 0; chn < CHANNEL_MAX; chn++)
+		clrbits_le32(&ch[chn].ao.stbcal2,
+			(0x3 << 4) | (0x3 << 8) | (0x1 << 28));
+	dramc_dbg("HW_GATING DBG: OFF\n");
+
+	/* ZQCS_ENABLE_LP4 */
+	clrbits_le32(&ch[0].ao.spcmdctrl, (0x1 << 30));
+	clrbits_le32(&ch[1].ao.spcmdctrl, (0x1 << 30));
+	dramc_dbg("ZQCS_ENABLE_LP4: OFF\n");
+
+	dramc_enable_phy_dcm(0);
+	dramc_dbg("LOWPOWER_GOLDEN_SETTINGS(DCM): OFF\n");
+
+	for (chn = 0; chn < CHANNEL_MAX; chn++)
+		for (shu = 0; shu < shu_cnt; shu++)
+			clrbits_le32(&ch[chn].ao.shu[shu].dqsg_retry,
+				(0x1 << 1) | (0x3 << 13));
+	dramc_dbg("DUMMY_READ_FOR_DQS_GATING_RETRY: OFF\n");
+
+	write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);
+	write32(&ch[1].phy.misc_spm_ctrl0, 0xfbffefff);
+	write32(&ch[0].phy.misc_spm_ctrl2, 0xffffffef);
+	write32(&ch[1].phy.misc_spm_ctrl2, 0x7fffffef);
+	dramc_dbg("SPM_CONTROL_AFTERK: ON\n");
+
+	dramc_impedance_tracking_enable();
+	dramc_dbg("IMPEDANCE_TRACKING: ON\n");
+
+	for (chn = 0; chn < CHANNEL_MAX; chn++) {
+		clrbits_le32(&ch[chn].ao.spcmdctrl, (0x3 << 28));
+		setbits_le32(&ch[chn].ao.hw_mrr_fun, (0x1 << 0) | (0x1 << 11));
+		dramc_dbg("TEMP_SENSOR: ON\n");
+
+		clrbits_le32(&ch[0].ao.refctrl0, (0x1 << 18));
+		dramc_dbg("PER_BANK_REFRESH: OFF\n");
+
+		setbits_le32(&ch[chn].phy.dvfs_emi_clk, (0x1 << 24));
+		setbits_le32(&ch[chn].ao.dvfsdll, (0x1 << 7));
+	}
+}
+
diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
index 2295f39..f1ce236 100644
--- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
+++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
@@ -241,7 +241,7 @@
 	}
 }
 
-static void dramc_enable_phy_dcm(u8 en)
+void dramc_enable_phy_dcm(u8 en)
 {
 	u32 broadcast_bak = dramc_get_broadcast();
 	u8 shu, shu_cnt = DRAM_DFS_SHUFFLE_MAX;
@@ -309,7 +309,7 @@
 		}
 }
 
-static void dramc_hw_gating_onoff(u8 chn, u8 onoff)
+void dramc_hw_gating_onoff(u8 chn, u8 onoff)
 {
 	clrsetbits_le32(&ch[chn].ao.shuctrl2, 0x3 << 14,
 		(onoff << 14) | (onoff << 15));
diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c
index eb75890..f991932 100644
--- a/src/soc/mediatek/mt8183/emi.c
+++ b/src/soc/mediatek/mt8183/emi.c
@@ -274,6 +274,17 @@
 	setbits_le32(&ch[0].phy.misc_ctrl1, (0x1 << 31));
 }
 
+static void dramc_ac_timing_optimize(void)
+{
+	for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
+		clrsetbits_le32(&ch[chn].ao.shu[0].actim[3],
+			(0xff << 16), (0x64 << 16));
+		clrbits_le32(&ch[chn].ao.shu[0].ac_time_05t, (0x1 << 2));
+		clrsetbits_le32(&ch[chn].ao.shu[0].actim[4],
+			(0x3ff << 0), (0x77 << 0));
+	}
+}
+
 static void dramc_init(void)
 {
 	for (int i = 0; i < ARRAY_SIZE(init_settings); i++)
@@ -297,6 +308,8 @@
 {
 	dramc_apply_pre_calibration_config();
 	dramc_calibrate_all_channels(params);
+	dramc_ac_timing_optimize();
+	dramc_runtime_config();
 }
 
 void mt_set_emi(const struct sdram_params *params)
diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
index a67e16d..e1a0333 100644
--- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
@@ -136,6 +136,7 @@
 };
 
 void dramc_get_rank_size(u64 *dram_rank_size);
+void dramc_runtime_config(void);
 void dramc_set_broadcast(u32 onoff);
 u32 dramc_get_broadcast(void);
 void dramc_sw_impedance(const struct sdram_params *params);
@@ -143,4 +144,6 @@
 void dramc_calibrate_all_channels(const struct sdram_params *params);
 void dramc_save_restore_multi_reg(u8 type, u32 *store_mem,
 		u32 **addr, u32 count);
+void dramc_hw_gating_onoff(u8 chn, u8 onoff);
+void dramc_enable_phy_dcm(u8 bEn);
 #endif /* _DRAMC_PI_API_MT8183_H */

-- 
To view, visit https://review.coreboot.org/28844
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id1e8862ff6feb9628d37fe5300780ff56865a563
Gerrit-Change-Number: 28844
Gerrit-PatchSet: 1
Gerrit-Owner: Tristan Hsieh <tristan.shieh at mediatek.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181001/2f00ee2a/attachment-0001.html>


More information about the coreboot-gerrit mailing list