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

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


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


Change subject: mediatek/mt8183: Add DDR driver of pre-calibration part
......................................................................

mediatek/mt8183: Add DDR driver of pre-calibration part

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

Change-Id: If462126df31468ef55ec52e2061b9f98d3015f61
Signed-off-by: Huayang Duan <huayang.duan at mediatek.com>
---
M src/soc/mediatek/mt8183/Makefile.inc
A 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, 213 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/38/28838/1

diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc
index e9b5f42..ec2a9c0 100644
--- a/src/soc/mediatek/mt8183/Makefile.inc
+++ b/src/soc/mediatek/mt8183/Makefile.inc
@@ -22,6 +22,7 @@
 
 romstage-y += ../common/cbmem.c emi.c
 romstage-y += dramc_pi_basic_api.c
+romstage-y += dramc_pi_calibration_api.c
 romstage-y += memory.c
 romstage-y += ../common/gpio.c gpio.c
 romstage-y += ../common/mmu_operations.c mmu_operations.c
diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
new file mode 100644
index 0000000..c5ec9c7
--- /dev/null
+++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <assert.h>
+#include <delay.h>
+#include <arch/io.h>
+#include <soc/emi.h>
+#include <soc/dramc_register.h>
+#include <soc/dramc_pi_api.h>
+
+static void dramc_read_dbi_onoff(u8 onoff)
+{
+	for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+		for (u8 b = 0; b < 2; b++)
+			clrsetbits_le32(&ch[chn].phy.shu[0].b[b].dq[7],
+				0x1 << SHU1_BX_DQ7_R_DMDQMDBI_SHU_SHIFT,
+				onoff << SHU1_BX_DQ7_R_DMDQMDBI_SHU_SHIFT);
+}
+
+static void dramc_write_dbi_onoff(u8 onoff)
+{
+	for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+		clrsetbits_le32(&ch[chn].ao.shu[0].wodt,
+			0x1 << SHU1_WODT_DBIWR_SHIFT,
+			onoff << SHU1_WODT_DBIWR_SHIFT);
+}
+
+static void enable_dramc_phy_dcm_2_channel(u8 chn, u8 en)
+{
+	u8 shu, shu_cnt = DRAM_DFS_SHUFFLE_MAX;
+
+	if (!en) {
+		clrsetbits_le32(&ch[chn].phy.misc_cg_ctrl0,
+			(0x1 << 20) | (0x1 << 19) | 0x3FF << 8,
+			(0x0 << 20) | (0x1 << 19) | 0x3FF << 8);
+
+		for (shu = 0; shu < shu_cnt; shu++) {
+			setbits_le32(&ch[chn].phy.shu[shu].b[0].dq[8],
+				0x1FFF << 19);
+			setbits_le32(&ch[chn].phy.shu[shu].b[1].dq[8],
+				0x1FFF << 19);
+			clrbits_le32(&ch[chn].phy.shu[shu].ca_cmd[8],
+				0x1FFF << 19);
+		}
+		clrbits_le32(&ch[chn].phy.misc_cg_ctrl5,
+			(0x7 << 16) | (0x7 << 20));
+	}
+}
+
+static void dramc_enable_phy_dcm(u8 en)
+{
+	u32 broadcast_bak = dramc_get_broadcast();
+	u8 shu, shu_cnt = DRAM_DFS_SHUFFLE_MAX;
+	u8 chn = 0;
+
+	dramc_set_broadcast(DRAMC_BROADCAST_OFF);
+
+	for (chn = 0; chn < CHANNEL_MAX ; chn++) {
+		clrbits_le32(&ch[chn].phy.b[0].dll_fine_tune[1], 0x1 << 20);
+		clrbits_le32(&ch[chn].phy.b[1].dll_fine_tune[1], 0x1 << 20);
+		clrbits_le32(&ch[chn].phy.ca_dll_fine_tune[1], 0x1 << 20);
+
+		for (shu = 0; shu < shu_cnt; shu++) {
+			setbits_le32(&ch[chn].phy.shu[shu].b[0].dll[0],
+				0x1 << 0);
+			setbits_le32(&ch[chn].phy.shu[shu].b[1].dll[0],
+				0x1 << 0);
+			setbits_le32(&ch[chn].phy.shu[shu].ca_dll[0],
+				0x1 << 0);
+		}
+
+		clrsetbits_le32(&ch[chn].ao.dramc_pd_ctrl,
+			(0x1 << 0) | (0x1 << 1) | (0x1 << 2) |
+			(0x1 << 5) | (0x1 << 26) | (0x1 << 30) | (0x1 << 31),
+			((en ? 0x1 : 0) << 0) | ((en ? 0x1 : 0) << 1) |
+			((en ? 0x1 : 0) << 2) | ((en ? 0 : 0x1) << 5) |
+			((en ? 0 : 0x1) << 26) | ((en ? 0x1 : 0) << 30) |
+			((en ? 0x1 : 0) << 31));
+
+		/* DCM on :CHANNEL_EMI free run ; DCM off :mem_dcm */
+		assert(en == 0 || en == 1);
+		write32(&ch[chn].phy.misc_cg_ctrl2, 0x8060033E | (0x40 << en));
+		write32(&ch[chn].phy.misc_cg_ctrl2, 0x8060033F | (0x40 << en));
+		write32(&ch[chn].phy.misc_cg_ctrl2, 0x8060033E | (0x40 << en));
+
+		clrsetbits_le32(&ch[chn].phy.misc_ctrl3, 0x3 << 26,
+			(en ? 0 : 0x3) << 26);
+		for (shu = 0; shu < shu_cnt; shu++) {
+			clrsetbits_le32(&ch[chn].phy.shu[shu].b[0].dq[7],
+				0x7 << 17, (en ? 0x7 : 0) << 17);
+			clrsetbits_le32(&ch[chn].phy.shu[shu].b[1].dq[7],
+				0x7 << 17, (en ? 0x7 : 0) << 17);
+			clrsetbits_le32(&ch[chn].phy.shu[shu].ca_cmd[7],
+				0x7 << 17, (en ? 0x7 : 0) << 17);
+		}
+	}
+	enable_dramc_phy_dcm_2_channel(chn, en);
+	dramc_set_broadcast(broadcast_bak);
+}
+
+static void reset_delay_chain_before_calibration(void)
+{
+	for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
+		for (u8 rank = 0; rank < RANK_MAX; rank++) {
+			clrbits_le32(&ch[chn].phy.shu[0].rk[rank].ca_cmd[0],
+				0xffffff << 0);
+			clrbits_le32(&ch[chn].phy.shu[0].rk[rank].b[0].dq[0],
+				0xfffffff << 0);
+			clrbits_le32(&ch[chn].phy.shu[0].rk[rank].b[1].dq[0],
+				0xfffffff << 0);
+			clrbits_le32(&ch[chn].phy.shu[0].rk[rank].b[0].dq[1],
+				0xf << 0);
+			clrbits_le32(&ch[chn].phy.shu[0].rk[rank].b[1].dq[1],
+				0xf << 0);
+		}
+}
+
+static void dramc_hw_gating_onoff(u8 chn, u8 onoff)
+{
+	clrsetbits_le32(&ch[chn].ao.shuctrl2, 0x3 << 14,
+		(onoff << 14) | (onoff << 15));
+	clrsetbits_le32(&ch[chn].ao.stbcal2, 0x1 << 28, onoff << 28);
+	clrsetbits_le32(&ch[chn].ao.stbcal, 0x1 << 24, onoff << 24);
+	clrsetbits_le32(&ch[chn].ao.stbcal, 0x1 << 22, onoff << 22);
+}
+
+static void dramc_rx_input_delay_tracking_init_by_freq(u8 chn)
+{
+	u8 delay = 3;
+	clrsetbits_le32(&ch[chn].phy.shu[0].b[0].dq[5], 0x7 << 20, delay << 20);
+	clrsetbits_le32(&ch[chn].phy.shu[0].b[1].dq[5], 0x7 << 20, delay << 20);
+	clrsetbits_le32(&ch[chn].phy.shu[0].b[0].dq[7],
+		(0x1 << 12) | (0x1 << 13), (0x0 << 12) | (0x0 << 13));
+	clrsetbits_le32(&ch[chn].phy.shu[0].b[1].dq[7],
+		(0x1 << 12) | (0x1 << 13), (0x0 << 12) | (0x0 << 13));
+}
+
+void dramc_apply_pre_calibration_config(void)
+{
+	u8 shu = 0;
+
+	dramc_enable_phy_dcm(0);
+	reset_delay_chain_before_calibration();
+
+	setbits_le32(&ch[0].ao.shu[0].conf[3], 0x1ff << 16);
+	setbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 24);
+	clrsetbits_le32(&ch[0].ao.shu[0].scintv, 0x1f << 1, 0x1b << 1);
+
+	for (shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+		setbits_le32(&ch[0].ao.shu[shu].conf[3], 0x1ff << 0);
+
+	clrbits_le32(&ch[0].ao.dramctrl, 0x1 << 18);
+	clrbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 31);
+	clrbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 30);
+	clrbits_le32(&ch[0].ao.dqsoscr, 0x1 << 26);
+	clrbits_le32(&ch[0].ao.dqsoscr, 0x1 << 25);
+
+	dramc_write_dbi_onoff(DBI_OFF);
+	dramc_read_dbi_onoff(DBI_OFF);
+
+	for (int chn = 0; chn < CHANNEL_MAX; chn++) {
+		setbits_le32(&ch[chn].ao.spcmdctrl, 0x1 << 29);
+		setbits_le32(&ch[chn].ao.dqsoscr, 0x1 << 24);
+		for (shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
+			setbits_le32(&ch[chn].ao.shu[shu].scintv, 0x1 << 30);
+
+		clrbits_le32(&ch[chn].ao.dummy_rd, (0x1 << 7) | (0x7 << 20));
+		dramc_hw_gating_onoff(chn, GATING_OFF);
+		clrbits_le32(&ch[chn].ao.stbcal2, 0x1 << 28);
+
+		setbits_le32(&ch[chn].phy.misc_ctrl1,
+			(0x1 << 7) | (0x1 << 11));
+		clrbits_le32(&ch[chn].ao.refctrl0, 0x1 << 18);
+		clrbits_le32(&ch[chn].ao.mrs, 0x3 << 24);
+		setbits_le32(&ch[chn].ao.mpc_option, 0x1 << 17);
+		clrsetbits_le32(&ch[chn].phy.b[0].dq[6], 0x3 << 0, 0x1 << 0);
+		clrsetbits_le32(&ch[chn].phy.b[1].dq[6], 0x3 << 0, 0x1 << 0);
+		clrsetbits_le32(&ch[chn].phy.ca_cmd[6], 0x3 << 0, 0x1 << 0);
+		setbits_le32(&ch[chn].ao.dummy_rd, 0x1 << 25);
+		setbits_le32(&ch[chn].ao.drsctrl, 0x1 << 0);
+		clrbits_le32(&ch[chn].ao.shu[1].drving[1], 0x1 << 31);
+
+		dramc_rx_input_delay_tracking_init_by_freq(chn);
+	}
+
+	for (size_t r = 0; r < 2; r++) {
+		for (size_t b = 0; b < 2; b++)
+			clrbits_le32(&ch[0].phy.r[r].b[b].rxdvs[2],
+				(0x1 << 28) | (0x1 << 23) | (0x3 << 30));
+		clrbits_le32(&ch[0].phy.r0_ca_rxdvs[2], 0x3 << 30);
+	}
+}
+
diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c
index 37997aa..ba913a2 100644
--- a/src/soc/mediatek/mt8183/emi.c
+++ b/src/soc/mediatek/mt8183/emi.c
@@ -293,7 +293,13 @@
 	emi_init2(params);
 }
 
+static void do_calib(const struct sdram_params *params)
+{
+	dramc_apply_pre_calibration_config();
+}
+
 void mt_set_emi(const struct sdram_params *params)
 {
 	init_dram(params);
+	do_calib(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 af96316..ed9eb81 100644
--- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h
@@ -138,4 +138,5 @@
 void dramc_set_broadcast(u32 onoff);
 u32 dramc_get_broadcast(void);
 void dramc_sw_impedance(const struct sdram_params *params);
+void dramc_apply_pre_calibration_config(void);
 #endif /* _DRAMC_PI_API_MT8183_H */

-- 
To view, visit https://review.coreboot.org/28838
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: If462126df31468ef55ec52e2061b9f98d3015f61
Gerrit-Change-Number: 28838
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/24872550/attachment-0001.html>


More information about the coreboot-gerrit mailing list