<p>Tristan Hsieh has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/28837">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mediatek/mt8183: Add DDR driver of software impedance part<br><br>BUG=b:80501386<br>BRANCH=none<br>TEST=Boots correctly on Kukui, and inits DRAM successfully with related<br>     patches.<br><br>Change-Id: I42a33ffb66ffa2f938f85484ffc3a0d3788816b3<br>Signed-off-by: Huayang Duan <huayang.duan@mediatek.com><br>---<br>M src/soc/mediatek/mt8183/Makefile.inc<br>A src/soc/mediatek/mt8183/dramc_pi_basic_api.c<br>M src/soc/mediatek/mt8183/emi.c<br>M src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h<br>4 files changed, 132 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/37/28837/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc</span><br><span>index 3cd845d..e9b5f42 100644</span><br><span>--- a/src/soc/mediatek/mt8183/Makefile.inc</span><br><span>+++ b/src/soc/mediatek/mt8183/Makefile.inc</span><br><span>@@ -21,6 +21,7 @@</span><br><span> verstage-y += ../common/wdt.c</span><br><span> </span><br><span> romstage-y += ../common/cbmem.c emi.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += dramc_pi_basic_api.c</span><br><span> romstage-y += memory.c</span><br><span> romstage-y += ../common/gpio.c gpio.c</span><br><span> romstage-y += ../common/mmu_operations.c mmu_operations.c</span><br><span>diff --git a/src/soc/mediatek/mt8183/dramc_pi_basic_api.c b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c</span><br><span>new file mode 100644</span><br><span>index 0000000..4c95814</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/mediatek/mt8183/dramc_pi_basic_api.c</span><br><span>@@ -0,0 +1,124 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 MediaTek Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <delay.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/emi.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/dramc_register.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/dramc_pi_api.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void sw_imp_cal_vref_sel(u8 term_option, u8 impcal_stage)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 vref_sel = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (term_option == 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+               vref_sel = IMP_LP4X_TERM_VREF_SEL;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (impcal_stage == IMPCAL_STAGE_DRVP)</span><br><span style="color: hsl(120, 100%, 40%);">+                        vref_sel = IMP_DRVP_LP4X_UNTERM_VREF_SEL;</span><br><span style="color: hsl(120, 100%, 40%);">+             else if (impcal_stage == IMPCAL_STAGE_DRVN)</span><br><span style="color: hsl(120, 100%, 40%);">+                   vref_sel = IMP_DRVN_LP4X_UNTERM_VREF_SEL;</span><br><span style="color: hsl(120, 100%, 40%);">+             else</span><br><span style="color: hsl(120, 100%, 40%);">+                  vref_sel = IMP_TRACK_LP4X_UNTERM_VREF_SEL;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   dramc_dbg("[%s] IMP_VREF_SEL 0x%x\n", __func__, vref_sel);</span><br><span style="color: hsl(120, 100%, 40%);">+  clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x3f << 8, vref_sel << 8);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void dramc_sw_impedance(const struct sdram_params *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 broadcast_bak = dramc_get_broadcast();</span><br><span style="color: hsl(120, 100%, 40%);">+    u8 term = 0, ca_term = ODT_OFF, dq_term = ODT_ON;</span><br><span style="color: hsl(120, 100%, 40%);">+     u32 sw_impedance[2][4] = { {0}, {0} };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (term = 0; term < 2; term++)</span><br><span style="color: hsl(120, 100%, 40%);">+           for (u8 i = 0; i < 4; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                 sw_impedance[term][i] = params->impedance[term][i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      sw_impedance[ODT_OFF][2] = sw_impedance[ODT_ON][2];</span><br><span style="color: hsl(120, 100%, 40%);">+   sw_impedance[ODT_OFF][3] = sw_impedance[ODT_ON][3];</span><br><span style="color: hsl(120, 100%, 40%);">+   dramc_set_broadcast(DRAMC_BROADCAST_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0xFF, 0x3);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Set IMP_VREF_SEL value for DRVP */</span><br><span style="color: hsl(120, 100%, 40%);">+ sw_imp_cal_vref_sel(dq_term, IMPCAL_STAGE_DRVP);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* DQ */</span><br><span style="color: hsl(120, 100%, 40%);">+      clrsetbits_le32(&ch[0].ao.shu[0].drving[0], (0x1F << 5) | (0x1F << 0),</span><br><span style="color: hsl(120, 100%, 40%);">+                (sw_impedance[dq_term][0] << 5) |</span><br><span style="color: hsl(120, 100%, 40%);">+               (sw_impedance[dq_term][1] << 0));</span><br><span style="color: hsl(120, 100%, 40%);">+       clrsetbits_le32(&ch[0].ao.shu[0].drving[1],</span><br><span style="color: hsl(120, 100%, 40%);">+               (0x1F << 25)|(0x1F << 20) | (1 << 31),</span><br><span style="color: hsl(120, 100%, 40%);">+              (sw_impedance[dq_term][0] << 25) |</span><br><span style="color: hsl(120, 100%, 40%);">+              (sw_impedance[dq_term][1] << 20) | (!dq_term << 31));</span><br><span style="color: hsl(120, 100%, 40%);">+     clrsetbits_le32(&ch[0].ao.shu[0].drving[2], (0x1F << 5) | (0x1F << 0),</span><br><span style="color: hsl(120, 100%, 40%);">+                (sw_impedance[dq_term][2] << 5) |</span><br><span style="color: hsl(120, 100%, 40%);">+               (sw_impedance[dq_term][3] << 0));</span><br><span style="color: hsl(120, 100%, 40%);">+       clrsetbits_le32(&ch[0].ao.shu[0].drving[3], (0x1F << 25) | (0x1F << 20),</span><br><span style="color: hsl(120, 100%, 40%);">+              (sw_impedance[dq_term][2] << 25) |</span><br><span style="color: hsl(120, 100%, 40%);">+              (sw_impedance[dq_term][3] << 20));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* DQS */</span><br><span style="color: hsl(120, 100%, 40%);">+     for (u8 i = 0; i <= 2; i += 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+           clrsetbits_le32(&ch[0].ao.shu[0].drving[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                       (0x1F << 25) | (0x1F << 20),</span><br><span style="color: hsl(120, 100%, 40%);">+                      (sw_impedance[dq_term][i] << 25) |</span><br><span style="color: hsl(120, 100%, 40%);">+                      (sw_impedance[dq_term][i + 1] << 20));</span><br><span style="color: hsl(120, 100%, 40%);">+          clrsetbits_le32(&ch[0].ao.shu[0].drving[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                       (0x1F << 15) | (0x1F << 10),</span><br><span style="color: hsl(120, 100%, 40%);">+                      (sw_impedance[dq_term][i] << 15) |</span><br><span style="color: hsl(120, 100%, 40%);">+                      (sw_impedance[dq_term][i + 1] << 10));</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* CMD & CLK */</span><br><span style="color: hsl(120, 100%, 40%);">+   for (u8 i = 1; i <= 3; i += 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+           clrsetbits_le32(&ch[0].ao.shu[0].drving[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                       (0x1F << 15) | (0x1F << 10),</span><br><span style="color: hsl(120, 100%, 40%);">+                      (sw_impedance[ca_term][i - 1] << 15) |</span><br><span style="color: hsl(120, 100%, 40%);">+                  (sw_impedance[ca_term][i] << 10));</span><br><span style="color: hsl(120, 100%, 40%);">+              clrsetbits_le32(&ch[0].ao.shu[0].drving[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                       (0x1F << 5) | (0x1F << 0),</span><br><span style="color: hsl(120, 100%, 40%);">+                        (sw_impedance[ca_term][i - 1] << 5) |</span><br><span style="color: hsl(120, 100%, 40%);">+                   (sw_impedance[ca_term][i] << 0));</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* RG_TX_*RCKE_DRVP/RG_TX_*RCKE_DRVN doesn't set, so set 0xA first */</span><br><span style="color: hsl(120, 100%, 40%);">+     clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 17,</span><br><span style="color: hsl(120, 100%, 40%);">+           sw_impedance[ca_term][0] << 17);</span><br><span style="color: hsl(120, 100%, 40%);">+        clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 22,</span><br><span style="color: hsl(120, 100%, 40%);">+           sw_impedance[ca_term][1] << 22);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* DRVP[4:0] = RG_TX_ARCMD_PU_PRE<1:0>, RG_TX_ARCLK_DRVN_PRE<2:0> */</span><br><span style="color: hsl(120, 100%, 40%);">+      clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[3],</span><br><span style="color: hsl(120, 100%, 40%);">+              SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+         (((8 >> 3) & 0x3) << SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE_SHIFT));</span><br><span style="color: hsl(120, 100%, 40%);">+ clrsetbits_le32(&ch[0].phy.shu[0].ca_cmd[0],</span><br><span style="color: hsl(120, 100%, 40%);">+              SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+               ((8 & 0x7) << SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE_SHIFT));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  dramc_set_broadcast(DRAMC_BROADCAST_OFF);</span><br><span style="color: hsl(120, 100%, 40%);">+     clrsetbits_le32(&ch[0].phy.shu[0].ca_dll[1], 0x1F << 16, 0x9 << 16);</span><br><span style="color: hsl(120, 100%, 40%);">+  clrsetbits_le32(&ch[1].phy.shu[0].ca_dll[1], 0x1F << 16, 0x9 << 16);</span><br><span style="color: hsl(120, 100%, 40%);">+  dramc_set_broadcast(DRAMC_BROADCAST_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for (term = 0; term < 2; term++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         dramc_show("term=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                     term, sw_impedance[term][0],</span><br><span style="color: hsl(120, 100%, 40%);">+                  sw_impedance[term][1], sw_impedance[term][3]);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     dramc_set_broadcast(broadcast_bak);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c</span><br><span>index 7008ccc..37997aa 100644</span><br><span>--- a/src/soc/mediatek/mt8183/emi.c</span><br><span>+++ b/src/soc/mediatek/mt8183/emi.c</span><br><span>@@ -287,6 +287,7 @@</span><br><span> </span><br><span>  dramc_set_broadcast(DRAMC_BROADCAST_ON);</span><br><span>     dramc_init_pre_settings();</span><br><span style="color: hsl(120, 100%, 40%);">+    dramc_sw_impedance(params);</span><br><span> </span><br><span>      dramc_init();</span><br><span>        emi_init2(params);</span><br><span>diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h</span><br><span>index e24bd6c..af96316 100644</span><br><span>--- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h</span><br><span>+++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h</span><br><span>@@ -39,6 +39,11 @@</span><br><span> #define DRAMC_BROADCAST_OFF 0x0</span><br><span> #define MAX_BACKUP_REG_CNT 32</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define IMP_LP4X_TERM_VREF_SEL            0x1b</span><br><span style="color: hsl(120, 100%, 40%);">+#define IMP_DRVP_LP4X_UNTERM_VREF_SEL     0x1a</span><br><span style="color: hsl(120, 100%, 40%);">+#define IMP_DRVN_LP4X_UNTERM_VREF_SEL     0x16</span><br><span style="color: hsl(120, 100%, 40%);">+#define IMP_TRACK_LP4X_UNTERM_VREF_SEL    0x1a</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum dram_te_op {</span><br><span>  TE_OP_WRITE_READ_CHECK = 0,</span><br><span>  TE_OP_READ_CHECK</span><br><span>@@ -132,4 +137,5 @@</span><br><span> void dramc_get_rank_size(u64 *dram_rank_size);</span><br><span> void dramc_set_broadcast(u32 onoff);</span><br><span> u32 dramc_get_broadcast(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void dramc_sw_impedance(const struct sdram_params *params);</span><br><span> #endif /* _DRAMC_PI_API_MT8183_H */</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/28837">change 28837</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/28837"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I42a33ffb66ffa2f938f85484ffc3a0d3788816b3 </div>
<div style="display:none"> Gerrit-Change-Number: 28837 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Tristan Hsieh <tristan.shieh@mediatek.com> </div>