blob: 8a5d319b293f5d8232d7e3548c5490c7265925b5 [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Huayang Duane19d61b2018-09-26 14:51:51 +08002
Huayang Duan73780152019-08-19 14:06:31 +08003#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Huayang Duanb8f65ad2019-04-11 19:27:39 +08005#include <delay.h>
Huayang Duane19d61b2018-09-26 14:51:51 +08006#include <soc/emi.h>
7#include <soc/dramc_pi_api.h>
Huayang Duan0e6cb832020-05-31 11:49:25 +08008#include <soc/dramc_param.h>
Huayang Duane19d61b2018-09-26 14:51:51 +08009#include <soc/dramc_register.h>
10#include <soc/infracfg.h>
Huayang Duan73780152019-08-19 14:06:31 +080011#include <string.h>
12#include <timer.h>
Huayang Duane19d61b2018-09-26 14:51:51 +080013
Huayang Duan63ee1602020-06-01 16:30:27 +080014void dramc_cke_fix_onoff(enum cke_type option, u8 chn)
Huayang Duane19d61b2018-09-26 14:51:51 +080015{
Huayang Duan73780152019-08-19 14:06:31 +080016 u8 on = 0, off = 0;
Huayang Duanb8f65ad2019-04-11 19:27:39 +080017
Huayang Duan73780152019-08-19 14:06:31 +080018 /* if CKE is dynamic, set both CKE fix On and Off as 0 */
19 if (option != CKE_DYNAMIC) {
20 on = option;
Huayang Duan63ee1602020-06-01 16:30:27 +080021 off = 1 - option;
Huayang Duanb8f65ad2019-04-11 19:27:39 +080022 }
Huayang Duan73780152019-08-19 14:06:31 +080023
Huayang Duan63ee1602020-06-01 16:30:27 +080024 SET32_BITFIELDS(&ch[chn].ao.ckectrl,
25 CKECTRL_CKEFIXON, on,
26 CKECTRL_CKEFIXOFF, off);
Huayang Duan73780152019-08-19 14:06:31 +080027}
28
Huayang Duancea735c2019-09-24 14:07:11 +080029static void dvfs_settings(u8 freq_group)
30{
31 u8 dll_idle;
32
33 switch (freq_group) {
34 case LP4X_DDR1600:
35 dll_idle = 0x18;
36 break;
37 case LP4X_DDR2400:
38 dll_idle = 0x10;
39 break;
40 case LP4X_DDR3200:
41 dll_idle = 0xc;
42 break;
43 case LP4X_DDR3600:
44 dll_idle = 0xa;
45 break;
46 default:
47 die("Invalid DDR frequency group %u\n", freq_group);
48 return;
49 }
50
51 dll_idle = dll_idle << 1;
52 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
Julius Werner55009af2019-12-02 22:03:27 -080053 setbits32(&ch[chn].ao.dvfsdll, 0x1 << 5);
54 setbits32(&ch[chn].phy.dvfs_emi_clk, 0x1 << 29);
Huayang Duancac990f2020-06-08 17:40:55 +080055 clrsetbits32(&ch[chn].ao.shuctrl2, 0x7f, dll_idle);
Huayang Duancea735c2019-09-24 14:07:11 +080056
Huayang Duancac990f2020-06-08 17:40:55 +080057 setbits32(&ch[chn].phy.misc_ctrl0, 0x3 << 19);
Julius Werner55009af2019-12-02 22:03:27 -080058 setbits32(&ch[chn].phy.dvfs_emi_clk, 0x1 << 24);
59 setbits32(&ch[chn].ao.dvfsdll, 0x1 << 7);
Huayang Duancea735c2019-09-24 14:07:11 +080060 }
61}
62
Huayang Duan73780152019-08-19 14:06:31 +080063static void ddr_phy_pll_setting(u8 chn, u8 freq_group)
64{
65 u8 cap_sel, mid_cap_sel;
66 u8 vth_sel = 0x2;
67 u8 ca_dll_mode[2];
68 u32 sdm_pcw, delta;
69
70 switch (freq_group) {
71 case LP4X_DDR1600:
72 mid_cap_sel = 0x0;
73 cap_sel = 0x3;
74 sdm_pcw = 0x7b00;
75 delta = 0;
76 break;
77 case LP4X_DDR2400:
78 mid_cap_sel = 0x3;
79 cap_sel = 0x0;
80 sdm_pcw = 0x5c00;
81 delta = 0;
82 break;
83 case LP4X_DDR3200:
84 mid_cap_sel = 0x2;
85 cap_sel = 0x0;
86 sdm_pcw = 0x7b00;
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +080087 delta = 0xc03;
Huayang Duan73780152019-08-19 14:06:31 +080088 break;
89 case LP4X_DDR3600:
90 mid_cap_sel = 0x1;
91 cap_sel = 0x0;
92 sdm_pcw = 0x8a00;
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +080093 delta = 0xd96;
Huayang Duan73780152019-08-19 14:06:31 +080094 break;
95 default:
96 die("Invalid DDR frequency group %u\n", freq_group);
97 return;
98 }
99
100 if (freq_group == LP4X_DDR1600)
101 ca_dll_mode[CHANNEL_A] = DLL_SLAVE;
102 else
103 ca_dll_mode[CHANNEL_A] = DLL_MASTER;
104 ca_dll_mode[CHANNEL_B] = DLL_SLAVE;
105
Julius Werner55009af2019-12-02 22:03:27 -0800106 clrbits32(&ch[chn].phy.shu[0].pll[4], 0xffff);
107 clrbits32(&ch[chn].phy.shu[0].pll[6], 0xffff);
108 setbits32(&ch[chn].phy.misc_shu_opt, (chn + 1) << 18);
109 clrsetbits32(&ch[chn].phy.ckmux_sel, 0x3 << 18 | 0x3 << 16, 0x0);
110 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[0], 0x3 << 18, 0x1 << 18);
Huayang Duan73780152019-08-19 14:06:31 +0800111
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800112 SET32_BITFIELDS(&ch[chn].ao.dvfsdll, DVFSDLL_R_BYPASS_1ST_DLL_SHU1,
113 ca_dll_mode[chn] == DLL_SLAVE);
Huayang Duan73780152019-08-19 14:06:31 +0800114
115 bool is_master = (ca_dll_mode[chn] == DLL_MASTER);
116 u8 phdet_out = is_master ? 0x0 : 0x1;
117 u8 phdet_in = is_master ? 0x0 : 0x1;
118 u8 gain = is_master ? 0x6 : 0x7;
119 u8 idle_cnt = is_master ? 0x9 : 0x7;
120 u8 fast_psjp = is_master ? 0x1 : 0x0;
121
Julius Werner55009af2019-12-02 22:03:27 -0800122 clrsetbits32(&ch[chn].phy.shu[0].ca_dll[0],
Huayang Duan73780152019-08-19 14:06:31 +0800123 (0x1 << 31) | (0x1 << 30) | (0xf << 20) | (0xf << 16) |
124 (0xf << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 4),
125 (phdet_out << 31) | (phdet_in << 30) |
126 (gain << 20) | (idle_cnt << 16) |
127 (0x8 << 12) |
128 (0x1 << 10) | (0x1 << 9) | (fast_psjp << 4));
129
130 u8 pd_ck_sel = is_master ? 0x1 : 0x0;
131 u8 fastpj_ck_sel = is_master ? 0x0 : 0x1;
132
Julius Werner55009af2019-12-02 22:03:27 -0800133 clrsetbits32(&ch[chn].phy.shu[0].ca_dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800134 (0x1 << 2) | (0x1 << 0),
135 (pd_ck_sel << 2) | (fastpj_ck_sel << 0));
136
Julius Werner55009af2019-12-02 22:03:27 -0800137 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[6],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800138 0x1 << 7, (is_master ? 0x1 : 0x0) << 7);
Huayang Duan73780152019-08-19 14:06:31 +0800139
140 struct reg_value regs_bak[] = {
141 {&ch[chn].phy.b[0].dq[7]},
142 {&ch[chn].phy.b[1].dq[7]},
143 {&ch[chn].phy.ca_cmd[7]},
144 };
145
146 for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++)
147 regs_bak[i].value = read32(regs_bak[i].addr);
148
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800149 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -0800150 setbits32(&ch[chn].phy.b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800151 0x1 << 6 | 0x1 << 4 | 0x1 << 2 | 0x1 << 0);
Julius Werner55009af2019-12-02 22:03:27 -0800152 setbits32(&ch[chn].phy.ca_cmd[7], 0x1 << 6 | 0x1 << 4 | 0x1 << 2 | 0x1 << 0);
153 setbits32(&ch[chn].phy.ca_cmd[2], 0x1 << 21);
Huayang Duan73780152019-08-19 14:06:31 +0800154
155 /* 26M */
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800156 SET32_BITFIELDS(&ch[chn].phy.misc_cg_ctrl0, MISC_CG_CTRL0_CLK_MEM_SEL, 0);
Huayang Duan73780152019-08-19 14:06:31 +0800157
158 /* MID FINE_TUNE */
Julius Werner55009af2019-12-02 22:03:27 -0800159 clrbits32(&ch[chn].phy.shu[0].b[0].dq[6], (0x1 << 26) | (0x1 << 27));
160 clrbits32(&ch[chn].phy.shu[0].b[1].dq[6], (0x1 << 26) | (0x1 << 27));
161 clrbits32(&ch[chn].phy.shu[0].ca_cmd[6], (0x1 << 26) | (0x1 << 27));
162 clrbits32(&ch[chn].phy.pll4, (0x1 << 16) | (0x1 << 22));
Huayang Duan73780152019-08-19 14:06:31 +0800163
164 /* PLL */
Julius Werner55009af2019-12-02 22:03:27 -0800165 clrbits32(&ch[chn].phy.pll1, 0x1 << 31);
166 clrbits32(&ch[chn].phy.pll2, 0x1 << 31);
Huayang Duan73780152019-08-19 14:06:31 +0800167
168 /* DLL */
Julius Werner55009af2019-12-02 22:03:27 -0800169 clrbits32(&ch[chn].phy.ca_dll_fine_tune[2], 0x1 << 0);
170 clrbits32(&ch[chn].phy.b[0].dll_fine_tune[2], 0x1 << 0);
171 clrbits32(&ch[chn].phy.b[1].dll_fine_tune[2], 0x1 << 0);
172 setbits32(&ch[chn].phy.b[0].dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800173 (0x1 << 10) | (0x1 << 11) | (0x1 << 13) | (0x1 << 14) |
174 (0x1 << 15) | (0x1 << 17) | (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800175 setbits32(&ch[chn].phy.b[1].dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800176 (0x1 << 10) | (0x1 << 11) | (0x1 << 13) | (0x1 << 14) |
177 (0x1 << 15) | (0x1 << 17) | (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800178 setbits32(&ch[chn].phy.ca_dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800179 (0x1 << 10) | (0x1 << 11) | (0x1 << 13) | (0x1 << 15) |
180 (0x1 << 16) | (0x1 << 17) | (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
181
182 /* RESETB */
Julius Werner55009af2019-12-02 22:03:27 -0800183 clrbits32(&ch[chn].phy.ca_dll_fine_tune[0], 0x1 << 3);
184 clrbits32(&ch[chn].phy.b[0].dll_fine_tune[0], 0x1 << 3);
185 clrbits32(&ch[chn].phy.b[1].dll_fine_tune[0], 0x1 << 3);
Huayang Duan73780152019-08-19 14:06:31 +0800186
187 udelay(1);
188
189 /* MPLL 52M */
Julius Werner55009af2019-12-02 22:03:27 -0800190 clrsetbits32(&ch[chn].phy.shu[0].pll[8],
Huayang Duan73780152019-08-19 14:06:31 +0800191 (0x7 << 0) | (0x3 << 18), (0x0 << 0) | (0x1 << 18));
Julius Werner55009af2019-12-02 22:03:27 -0800192 clrsetbits32(&ch[chn].phy.shu[0].pll[10],
Huayang Duan73780152019-08-19 14:06:31 +0800193 (0x7 << 0) | (0x3 << 18), (0x0 << 0) | (0x1 << 18));
Julius Werner55009af2019-12-02 22:03:27 -0800194 clrsetbits32(&ch[chn].phy.shu[0].pll[5],
Huayang Duan73780152019-08-19 14:06:31 +0800195 (0xffff << 16) | 0x1 << 0, sdm_pcw << 16);
Julius Werner55009af2019-12-02 22:03:27 -0800196 clrsetbits32(&ch[chn].phy.shu[0].pll[7],
Huayang Duan73780152019-08-19 14:06:31 +0800197 (0xffff << 16) | 0x1 << 0, sdm_pcw << 16);
198
Julius Werner55009af2019-12-02 22:03:27 -0800199 setbits32(&ch[chn].phy.ca_dll_fine_tune[0], 0x1 << 1);
200 setbits32(&ch[chn].phy.b[0].dll_fine_tune[0], 0x1 << 1);
201 setbits32(&ch[chn].phy.b[1].dll_fine_tune[0], 0x1 << 1);
Huayang Duan73780152019-08-19 14:06:31 +0800202
Julius Werner55009af2019-12-02 22:03:27 -0800203 clrbits32(&ch[chn].phy.ca_dll_fine_tune[1], 0x1 << 11);
204 clrbits32(&ch[chn].phy.b[0].dll_fine_tune[1], 0x1 << 19);
205 clrbits32(&ch[chn].phy.b[1].dll_fine_tune[1], 0x1 << 19);
Huayang Duan73780152019-08-19 14:06:31 +0800206
Julius Werner55009af2019-12-02 22:03:27 -0800207 clrsetbits32(&ch[chn].phy.shu[0].b[0].dq[6],
Huayang Duan73780152019-08-19 14:06:31 +0800208 (0x3 << 22) | (0x3 << 24) | (0x3 << 28),
209 (mid_cap_sel << 22) | (vth_sel << 24) | (cap_sel << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800210 clrsetbits32(&ch[chn].phy.shu[0].b[1].dq[6],
Huayang Duan73780152019-08-19 14:06:31 +0800211 (0x3 << 22) | (0x3 << 24) | (0x3 << 28),
212 (mid_cap_sel << 22) | (vth_sel << 24) | (cap_sel << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800213 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[6],
Huayang Duan73780152019-08-19 14:06:31 +0800214 (0x3 << 22) | (0x3 << 24) | (0x3 << 28),
215 (mid_cap_sel << 22) | (vth_sel << 24) | (cap_sel << 28));
216
217 /* RESETB */
Julius Werner55009af2019-12-02 22:03:27 -0800218 setbits32(&ch[chn].phy.ca_dll_fine_tune[0], 0x1 << 3);
219 setbits32(&ch[chn].phy.b[0].dll_fine_tune[0], 0x1 << 3);
220 setbits32(&ch[chn].phy.b[1].dll_fine_tune[0], 0x1 << 3);
Huayang Duan73780152019-08-19 14:06:31 +0800221 udelay(1);
222
223 /* PLL EN */
Julius Werner55009af2019-12-02 22:03:27 -0800224 setbits32(&ch[chn].phy.pll1, 0x1 << 31);
225 setbits32(&ch[chn].phy.pll2, 0x1 << 31);
Huayang Duan73780152019-08-19 14:06:31 +0800226 udelay(100);
227
228 /* MIDPI Init 1 */
Julius Werner55009af2019-12-02 22:03:27 -0800229 setbits32(&ch[chn].phy.pll4, (0x1 << 16) | (0x1 << 22));
Huayang Duan73780152019-08-19 14:06:31 +0800230 udelay(1);
231
232 /* MIDPI Init 2 */
233 u8 midpi_en;
234 u8 midpi_ckdiv4_en;
235
236 if (freq_group > LP4X_DDR1600) {
237 midpi_en = 0x1;
238 midpi_ckdiv4_en = 0x0;
239 } else {
240 midpi_en = 0x0;
241 midpi_ckdiv4_en = 0x1;
242 }
243
244 u32 dq6_clear = (0x1 << 26) | (0x1 << 27);
245 u32 dq6_set = (midpi_en << 26) | (midpi_ckdiv4_en << 27);
246
Julius Werner55009af2019-12-02 22:03:27 -0800247 clrsetbits32(&ch[chn].phy.shu[0].b[0].dq[6], dq6_clear, dq6_set);
248 clrsetbits32(&ch[chn].phy.shu[0].b[1].dq[6], dq6_clear, dq6_set);
249 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[6], dq6_clear, dq6_set);
Huayang Duan73780152019-08-19 14:06:31 +0800250
251 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -0800252 clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[3], 0x1 << 19,
Huayang Duan73780152019-08-19 14:06:31 +0800253 (0x1 << 13) | (0x1 << 15) | (0x1 << 16) | (0x1 << 17) |
254 ((chn ? 0 : 1) << 19));
Julius Werner55009af2019-12-02 22:03:27 -0800255 setbits32(&ch[chn].phy.b[0].dll_fine_tune[3],
Huayang Duan73780152019-08-19 14:06:31 +0800256 (0x1 << 11) | (0x1 << 13) | (0x1 << 14) | (0x1 << 15) |
257 (0x1 << 17));
Julius Werner55009af2019-12-02 22:03:27 -0800258 setbits32(&ch[chn].phy.b[1].dll_fine_tune[3],
Huayang Duan73780152019-08-19 14:06:31 +0800259 (0x1 << 11) | (0x1 << 13) | (0x1 << 14) | (0x1 << 15) |
260 (0x1 << 17));
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800261
Julius Werner55009af2019-12-02 22:03:27 -0800262 clrbits32(&ch[chn].phy.ca_dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800263 (0x1 << 10) | (0x1 << 13) |
264 (0x1 << 15) | (0x1 << 16) | (0x1 << 17) |
265 (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800266 clrbits32(&ch[chn].phy.b[0].dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800267 (0x1 << 10) | (0x1 << 13) | (0x1 << 14) |
268 (0x1 << 15) | (0x1 << 17) |
269 (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800270 clrbits32(&ch[chn].phy.b[1].dll_fine_tune[2],
Huayang Duan73780152019-08-19 14:06:31 +0800271 (0x1 << 10) | (0x1 << 13) |
272 (0x1 << 14) | (0x1 << 15) | (0x1 << 17) |
273 (0x1 << 19) | (0x1 << 27) | (0x1 << 31));
274
Julius Werner55009af2019-12-02 22:03:27 -0800275 setbits32(&ch[chn].phy.ca_dll_fine_tune[2], 0x1 << 11);
276 clrbits32(&ch[chn].phy.b[0].dll_fine_tune[2], 0x1 << 11);
277 clrbits32(&ch[chn].phy.b[1].dll_fine_tune[2], 0x1 << 11);
Huayang Duan73780152019-08-19 14:06:31 +0800278 udelay(2);
279
Julius Werner55009af2019-12-02 22:03:27 -0800280 setbits32(&ch[chn].phy.misc_cg_ctrl0, 0x1 << 4);
Huayang Duan73780152019-08-19 14:06:31 +0800281 udelay(1);
282
283 /* DLL */
Julius Werner55009af2019-12-02 22:03:27 -0800284 setbits32(&ch[chn].phy.ca_dll_fine_tune[2], 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800285 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -0800286 setbits32(&ch[chn].phy.b[0].dll_fine_tune[2], 0x1 << 0);
287 setbits32(&ch[chn].phy.b[1].dll_fine_tune[2], 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800288 udelay(1);
289
Julius Werner55009af2019-12-02 22:03:27 -0800290 clrbits32(&ch[chn].phy.ca_cmd[2], 0x1 << 21);
Huayang Duan73780152019-08-19 14:06:31 +0800291 for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++)
292 write32(regs_bak[i].addr, regs_bak[i].value);
293
Huayang Duan63ee1602020-06-01 16:30:27 +0800294 dramc_cke_fix_onoff(CKE_DYNAMIC, CHANNEL_A);
295 dramc_cke_fix_onoff(CKE_DYNAMIC, CHANNEL_B);
Huayang Duan73780152019-08-19 14:06:31 +0800296
297 if (freq_group == LP4X_DDR3200 || freq_group == LP4X_DDR3600) {
Julius Werner55009af2019-12-02 22:03:27 -0800298 setbits32(&ch[chn].phy.shu[0].pll[5], 0x1 << 0);
299 setbits32(&ch[chn].phy.shu[0].pll[7], 0x1 << 0);
300 setbits32(&ch[chn].phy.shu[0].pll[14], 0x1 << 1);
301 setbits32(&ch[chn].phy.shu[0].pll20, 0x1 << 1);
302 clrsetbits32(&ch[chn].phy.shu[0].pll[14],
303 0xffff << 16, 0x0208 << 16);
304 clrsetbits32(&ch[chn].phy.shu[0].pll20,
305 0xffff << 16, 0x0208 << 16);
306 clrsetbits32(&ch[chn].phy.shu[0].pll[15],
307 0xffffffff << 0, delta << 16);
308 clrsetbits32(&ch[chn].phy.shu[0].pll21,
309 0xffffffff << 0, delta << 16);
Huayang Duan73780152019-08-19 14:06:31 +0800310 }
311}
312
313static void dramc_gating_mode(u8 mode)
314{
315 u8 vref_sel = 0, burst = 0;
316
317 if (mode) {
318 vref_sel = 2;
319 burst = 1;
320 }
321
322 for (u8 b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -0800323 clrsetbits32(&ch[0].phy.b[b].dq[6], 0x3 << 14, vref_sel << 14);
324 setbits32(&ch[0].phy.b[b].dq[9], 0x1 << 5);
Huayang Duan73780152019-08-19 14:06:31 +0800325 }
326
Julius Werner55009af2019-12-02 22:03:27 -0800327 clrsetbits32(&ch[0].ao.stbcal1, 0x1 << 5, burst << 5);
328 setbits32(&ch[0].ao.stbcal, 0x1 << 30);
Huayang Duan73780152019-08-19 14:06:31 +0800329
330 for (u8 b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -0800331 clrbits32(&ch[0].phy.b[b].dq[9], (0x1 << 4) | (0x1 << 0));
Huayang Duan73780152019-08-19 14:06:31 +0800332 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -0800333 setbits32(&ch[0].phy.b[b].dq[9], (0x1 << 4) | (0x1 << 0));
Huayang Duan73780152019-08-19 14:06:31 +0800334 }
335}
336
337static void update_initial_settings(u8 freq_group)
338{
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800339 u8 operate_fsp = get_freq_fsq(freq_group);
Huayang Duan73780152019-08-19 14:06:31 +0800340 u16 rx_vref = 0x16;
341
342 if (operate_fsp == FSP_1)
343 rx_vref = 0xb;
344
345 if (operate_fsp == FSP_1) {
Julius Werner55009af2019-12-02 22:03:27 -0800346 setbits32(&ch[0].ao.shu[0].odtctrl, 0x1 << 0);
347 setbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
348 setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
Huayang Duan73780152019-08-19 14:06:31 +0800349 } else {
Julius Werner55009af2019-12-02 22:03:27 -0800350 clrbits32(&ch[0].ao.shu[0].odtctrl, 0x1 << 0);
351 clrbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
352 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
Huayang Duan73780152019-08-19 14:06:31 +0800353 }
354
355 for (size_t b = 0; b < 2; b++)
356 for (size_t r = 0; r < 2; r++)
Julius Werner55009af2019-12-02 22:03:27 -0800357 clrbits32(&ch[0].phy.r[r].b[b].rxdvs[2],
Huayang Duan73780152019-08-19 14:06:31 +0800358 (0x1 << 23) | (0x1 << 28) | (0x3 << 30));
Julius Werner55009af2019-12-02 22:03:27 -0800359 clrbits32(&ch[0].phy.shu[0].ca_cmd[7], 0xf << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800360
Julius Werner55009af2019-12-02 22:03:27 -0800361 setbits32(&ch[0].phy.ca_cmd[3], 0x1 << 10);
362 setbits32(&ch[0].phy.ca_cmd[10], 0x1 << 5);
363 clrsetbits32(&ch[0].phy.ca_cmd[6], 0x3 << 14, 0x1 << 14);
364 setbits32(&ch[0].phy.b[0].dq[3], 0x7 << 5);
365 setbits32(&ch[0].phy.b[1].dq[3], 0x7 << 5);
366 setbits32(&ch[0].phy.ca_cmd[3], (0x1 << 5) | (0x1 << 7));
367 clrbits32(&ch[0].phy.b[0].dq[3], 0x1 << 1);
368 clrbits32(&ch[0].phy.b[1].dq[3], 0x1 << 1);
369 setbits32(&ch[0].phy.b[0].dq[5], 0x1 << 31);
370 setbits32(&ch[0].phy.b[1].dq[5], 0x1 << 31);
371 setbits32(&ch[0].phy.ca_cmd[5], 0x1 << 31);
Huayang Duan73780152019-08-19 14:06:31 +0800372
Julius Werner55009af2019-12-02 22:03:27 -0800373 clrsetbits32(&ch[0].phy.ca_cmd[6], 0xf << 16, 0x3 << 16);
374 clrsetbits32(&ch[0].phy.misc_imp_ctrl0, (0x1 << 5) | (0x1 << 6),
Huayang Duan73780152019-08-19 14:06:31 +0800375 (0x1 << 5) | (0x0 << 6));
Julius Werner55009af2019-12-02 22:03:27 -0800376 setbits32(&ch[0].phy.b[0].dq[6], 0x1 << 9);
377 setbits32(&ch[0].phy.b[1].dq[6], 0x1 << 9);
378 setbits32(&ch[0].phy.ca_cmd[6], 0x1 << 9);
379 clrsetbits32(&ch[0].phy.b[0].dq[6], 0x3 << 0, 0x1 << 0);
380 clrsetbits32(&ch[0].phy.b[1].dq[6], 0x1 << 0, 0x1 << 0);
381 clrsetbits32(&ch[0].phy.ca_cmd[6], 0x3 << 0, 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800382
Julius Werner55009af2019-12-02 22:03:27 -0800383 setbits32(&ch[0].phy.ca_cmd[6], 0x1 << 6);
384 setbits32(&ch[0].phy.b[0].dq[6], 0x1 << 3);
385 setbits32(&ch[0].phy.b[1].dq[6], 0x1 << 3);
386 setbits32(&ch[0].phy.ca_cmd[6], 0x1 << 3);
387 setbits32(&ch[0].phy.b[0].dq[6], 0x1 << 5);
388 setbits32(&ch[0].phy.b[1].dq[6], 0x1 << 5);
389 setbits32(&ch[0].phy.ca_cmd[6], 0x1 << 5);
Huayang Duan73780152019-08-19 14:06:31 +0800390
391 for (u8 b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -0800392 clrsetbits32(&ch[0].phy.shu[0].b[b].dq[5], 0x3f << 0, rx_vref << 0);
393 clrsetbits32(&ch[0].phy.b[b].dq[5], 0x3f << 8, rx_vref << 8);
Huayang Duan73780152019-08-19 14:06:31 +0800394 }
395
Julius Werner55009af2019-12-02 22:03:27 -0800396 setbits32(&ch[0].phy.b[0].dq[8], (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
397 setbits32(&ch[0].phy.b[1].dq[8], (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
398 setbits32(&ch[0].phy.ca_cmd[9], (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
Huayang Duan73780152019-08-19 14:06:31 +0800399 dramc_gating_mode(1);
400
Julius Werner55009af2019-12-02 22:03:27 -0800401 setbits32(&ch[0].phy.ca_cmd[8], 0x1 << 19);
402 clrbits32(&ch[0].phy.ca_cmd[8], 0x1 << 18);
403 clrsetbits32(&ch[0].ao.shu[0].misc, 0xf << 0, 0x2 << 0);
404 clrsetbits32(&ch[0].ao.shu[0].dqsg, (0x3f << 20) | (0x1 << 16),
Huayang Duan73780152019-08-19 14:06:31 +0800405 (0x2a << 20) | (0x1 << 16));
406
Julius Werner55009af2019-12-02 22:03:27 -0800407 clrbits32(&ch[0].phy.shu[0].b[0].dq[5], 0x3f << 8);
408 clrbits32(&ch[0].phy.shu[0].b[1].dq[5], 0x3f << 8);
409 clrbits32(&ch[0].phy.shu[0].ca_cmd[5], 0x3f << 8);
Huayang Duan73780152019-08-19 14:06:31 +0800410
411 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800412 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
Julius Werner55009af2019-12-02 22:03:27 -0800413 clrbits32(&ch[chn].phy.shu[0].b[0].dq[6], 0x3f << 0);
414 clrbits32(&ch[chn].phy.shu[0].b[1].dq[6], 0x3f << 0);
415 clrbits32(&ch[chn].phy.shu[0].ca_cmd[6], 0x3f << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800416 }
417 dramc_set_broadcast(DRAMC_BROADCAST_ON);
418
419 /* IMP Tracking Init Settings */
Julius Werner55009af2019-12-02 22:03:27 -0800420 clrsetbits32(&ch[0].ao.shu[0].impcal1,
Huayang Duan73780152019-08-19 14:06:31 +0800421 (0x7 << 0) | (0x7 << 17) | (0xff << 20) | (0xf << 28),
422 (0x4 << 0) | (0x4 << 17) | (0x10 << 20) | (0x8 << 28));
423
Julius Werner55009af2019-12-02 22:03:27 -0800424 setbits32(&ch[0].ao.srefctrl, 0xf << 12);
425 setbits32(&ch[0].ao.pre_tdqsck[0], 0x1 << 17);
426 setbits32(&ch[0].ao.shu[0].misc, 0xf << 12);
427 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[8],
Huayang Duan73780152019-08-19 14:06:31 +0800428 (0xffff << 0) | (0x1 << 15) | (0x3ff << 22),
429 (0x7fff << 0) | (0x0 << 15) | (0x3ff << 22));
Julius Werner55009af2019-12-02 22:03:27 -0800430 clrsetbits32(&ch[0].phy.shu[0].b[1].dq[8],
Huayang Duan73780152019-08-19 14:06:31 +0800431 (0xffff << 0) | (0x1 << 15) | (0x3ff << 22),
432 (0x7fff << 0) | (0x0 << 15) | (0x3ff << 22));
Julius Werner55009af2019-12-02 22:03:27 -0800433 clrsetbits32(&ch[0].phy.shu[0].ca_cmd[8],
Huayang Duan73780152019-08-19 14:06:31 +0800434 (0xffff << 0) | (0x1 << 15) | (0x3ff << 22),
435 (0x7fff << 0) | (0x0 << 15) | (0x3ff << 22));
Julius Werner55009af2019-12-02 22:03:27 -0800436 setbits32(&ch[0].phy.misc_ctrl3, 0x1 << 26);
437 clrbits32(&ch[0].phy.shu[0].b[0].dq[7], (0xf << 8) | (0x1 << 12) | (0x1 << 13));
438 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], (0xf << 8) | (0x1 << 12) | (0x1 << 13));
439 clrsetbits32(&ch[0].ao.clkar, (0xffff << 0) | (0x1 << 15),
Huayang Duan73780152019-08-19 14:06:31 +0800440 (0x7fff << 0) | (0x1 << 15));
441
Julius Werner55009af2019-12-02 22:03:27 -0800442 clrbits32(&ch[0].ao.shu[0].dqsg_retry, 0x1 << 29);
443 clrbits32(&ch[0].ao.write_lev, 0x1 << 2);
444 setbits32(&ch[0].ao.dummy_rd, 0x1 << 24);
445 clrbits32(&ch[0].ao.stbcal2, (0x1 << 0) | (0x1 << 1));
446 setbits32(&ch[0].ao.eyescan, (0x1 << 8) | (0x1 << 9) | (0x1 << 10));
447 setbits32(&ch[0].ao.shu[0].odtctrl, (0x1 << 2) | (0x1 << 3));
Huayang Duan73780152019-08-19 14:06:31 +0800448
Julius Werner55009af2019-12-02 22:03:27 -0800449 setbits32(&ch[0].phy.shu[0].b[0].dll[0], 0x1 << 0);
450 setbits32(&ch[0].phy.shu[0].b[1].dll[0], 0x1 << 0);
451 setbits32(&ch[0].phy.ca_dll_fine_tune[1], 0x1 << 21);
Huayang Duan73780152019-08-19 14:06:31 +0800452
Julius Werner55009af2019-12-02 22:03:27 -0800453 setbits32(&ch[0].ao.perfctl0, (0x1 << 15) | (0x1 << 19) | (0x1 << 26));
454 setbits32(&ch[0].ao.srefctrl, 0x1 << 22);
455 clrsetbits32(&ch[0].ao.shuctrl1, 0xff << 0, 0x1a << 0);
456 setbits32(&ch[0].phy.b[0].dq[6], (0x1 << 7) | (0x1 << 12));
457 setbits32(&ch[0].phy.b[1].dq[6], (0x1 << 7) | (0x1 << 12));
458 setbits32(&ch[0].phy.ca_cmd[6], (0x1 << 7) | (0x1 << 12));
459 setbits32(&ch[0].ao.stbcal2, 0x1 << 16);
460 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800461 (0x7 << 29) | (0x1 << 28) | (0x7 << 25) | (0x1 << 24),
462 (0x0 << 29) | (0x1 << 28) | (0x1 << 25) | (0x1 << 24));
Julius Werner55009af2019-12-02 22:03:27 -0800463 clrsetbits32(&ch[0].phy.shu[0].b[1].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800464 (0x7 << 29) | (0x1 << 28) | (0x7 << 25) | (0x1 << 24),
465 (0x0 << 29) | (0x1 << 28) | (0x1 << 25) | (0x1 << 24));
466
467 /* Disable RODT tracking */
Julius Werner55009af2019-12-02 22:03:27 -0800468 clrbits32(&ch[0].ao.shu[0].rodtenstb, 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800469
470 /* Rx Gating tracking settings */
Julius Werner55009af2019-12-02 22:03:27 -0800471 clrsetbits32(&ch[0].ao.shu[0].dqsg,
Huayang Duan73780152019-08-19 14:06:31 +0800472 (0x1 << 11) | (0xf << 12), (0x1 << 11) | (0x9 << 12));
Julius Werner55009af2019-12-02 22:03:27 -0800473 clrbits32(&ch[0].ao.shu[0].rk[0].dqscal, (0x1 << 7) | (0x1 << 15));
474 clrbits32(&ch[0].ao.shu[0].rk[1].dqscal, (0x1 << 7) | (0x1 << 15));
475 clrsetbits32(&ch[0].ao.shu[0].stbcal,
Huayang Duan73780152019-08-19 14:06:31 +0800476 (0x7 << 4) | (0x1 << 8), (0x1 << 4) | (0x1 << 8));
477
Julius Werner55009af2019-12-02 22:03:27 -0800478 clrsetbits32(&ch[0].phy.b[0].dq[9], 0xff << 8, 0x4 << 8);
479 clrsetbits32(&ch[0].phy.b[1].dq[9], 0xff << 8, 0x4 << 8);
480 clrbits32(&ch[0].phy.ca_cmd[10], 0xff << 8);
Huayang Duan73780152019-08-19 14:06:31 +0800481
Julius Werner55009af2019-12-02 22:03:27 -0800482 setbits32(&ch[0].phy.shu[0].b[0].dq[8], 0x1 << 24);
483 setbits32(&ch[0].phy.shu[0].b[1].dq[8], 0x1 << 24);
Huayang Duan73780152019-08-19 14:06:31 +0800484
485 /* Enable WDQS */
Julius Werner55009af2019-12-02 22:03:27 -0800486 clrsetbits32(&ch[0].phy.shu[0].b[0].dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800487 (0x1 << 10) | (0x1 << 16) | (0x1 << 17),
488 (0x1 << 10) | (!operate_fsp << 16) | (0x1 << 17));
Julius Werner55009af2019-12-02 22:03:27 -0800489 clrsetbits32(&ch[0].phy.shu[0].b[1].dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800490 (0x1 << 10) | (0x1 << 16) | (0x1 << 17),
491 (0x1 << 10) | (!operate_fsp << 16) | (0x1 << 17));
Julius Werner55009af2019-12-02 22:03:27 -0800492 setbits32(&ch[0].ao.shu[0].odtctrl, (0x1 << 0) | (0x1 << 30) | (0x1 << 31));
493 setbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
494 setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
495 setbits32(&ch[0].ao.drsctrl, 0x1 << 19);
496 setbits32(&ch[0].ao.refctrl0, 0x1 << 28);
497 setbits32(&ch[0].ao.zqcs, 0x1 << 19);
498 setbits32(&ch[0].ao.dummy_rd, 0x3 << 26);
499 setbits32(&ch[0].ao.shuctrl2, 0x1 << 8);
500 clrsetbits32(&ch[0].ao.shuctrl3, 0xff << 24, 0xb << 24);
501 setbits32(&ch[0].phy.misc_ctrl3, 0x1 << 27);
502 setbits32(&ch[0].phy.b[0].dll_fine_tune[1], 0x3 << 20);
503 setbits32(&ch[0].phy.b[1].dll_fine_tune[1], 0x3 << 20);
504 setbits32(&ch[0].phy.ca_dll_fine_tune[1], 0x1 << 20);
505 clrbits32(&ch[0].phy.misc_ctrl0, 0x1 << 27);
506 setbits32(&ch[0].phy.misc_rxdvs[2], 0x1 << 8);
507 setbits32(&ch[0].ao.clkctrl, 0x1 << 7);
508 setbits32(&ch[0].ao.refctrl1, 0x1 << 7);
509 clrsetbits32(&ch[0].ao.shuctrl, (0x1 << 2) | (0x3 << 6) | (0x3 << 26),
Huayang Duan73780152019-08-19 14:06:31 +0800510 (0x0 << 2) | (0x3 << 6) | (0x3 << 26));
Julius Werner55009af2019-12-02 22:03:27 -0800511 setbits32(&ch[0].ao.shuctrl2, (0x1 << 31) | (0x3 << 10));
512 clrbits32(&ch[0].ao.stbcal2, 0xf << 4);
513 clrbits32(&ch[0].ao.pre_tdqsck[0], 0x3 << 19);
Huayang Duan73780152019-08-19 14:06:31 +0800514
Julius Werner55009af2019-12-02 22:03:27 -0800515 setbits32(&ch[0].ao.ckectrl, 0x1 << 22);
516 clrsetbits32(&ch[0].phy.ca_tx_mck, (0x1 << 31) | (0x1f << 21) | (0x1f << 26),
Huayang Duan73780152019-08-19 14:06:31 +0800517 (0x1 << 31) | (0xa << 21) | (0xa << 26));
Julius Werner55009af2019-12-02 22:03:27 -0800518 setbits32(&ch[0].ao.ckectrl, 0x1 << 23);
519 clrbits32(&ch[0].ao.shu[0].rodtenstb, 0x1 << 31);
Huayang Duan63ee1602020-06-01 16:30:27 +0800520
521 /* CA prebit shift and delay */
522 SET32_BITFIELDS(&ch[0].ao.shu[0].selph_ca7,
523 SHU_SELPH_CA7_DLY_RA0, 0x0,
524 SHU_SELPH_CA7_DLY_RA1, 0x0,
525 SHU_SELPH_CA7_DLY_RA2, 0x0,
526 SHU_SELPH_CA7_DLY_RA3, 0x0,
527 SHU_SELPH_CA7_DLY_RA4, 0x0,
528 SHU_SELPH_CA7_DLY_RA5, 0x0);
529 SET32_BITFIELDS(&ch[0].phy.shu[0].rk[0].ca_cmd[9],
530 SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD, 0x20);
531 SET32_BITFIELDS(&ch[0].phy.shu[0].rk[1].ca_cmd[9],
532 SHU1_R1_CA_CMD9_RG_RK1_ARPI_CMD, 0x20);
Huayang Duan73780152019-08-19 14:06:31 +0800533}
534
535static void dramc_power_on_sequence(void)
536{
537 for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800538 clrbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 13);
Huayang Duan73780152019-08-19 14:06:31 +0800539
Huayang Duan63ee1602020-06-01 16:30:27 +0800540 dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_A);
541 dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_B);
Huayang Duan73780152019-08-19 14:06:31 +0800542
543 udelay(200);
544 for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800545 setbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 13);
Huayang Duan73780152019-08-19 14:06:31 +0800546
547 for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800548 setbits32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26);
Huayang Duan73780152019-08-19 14:06:31 +0800549
550 udelay(2000);
Huayang Duan63ee1602020-06-01 16:30:27 +0800551 dramc_cke_fix_onoff(CKE_FIXON, CHANNEL_A);
552 dramc_cke_fix_onoff(CKE_FIXON, CHANNEL_B);
Huayang Duan73780152019-08-19 14:06:31 +0800553 udelay(2);
554}
555
556static void ddr_phy_reserved_rg_setting(u8 freq_group)
557{
558 u32 hyst_sel = 0, midpi_cap_sel = 0, lp3_sel = 0;
559
560 if (get_freq_fsq(freq_group) == FSP_0) {
561 hyst_sel = 1;
562 midpi_cap_sel = 1;
563 }
564
565 if (freq_group == LP4X_DDR1600)
566 lp3_sel = 1;
567
568 /* fine tune */
569 for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800570 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[6], 0xffff << 6,
Huayang Duan73780152019-08-19 14:06:31 +0800571 (0x1 << 6) | ((!chn) << 7) | (hyst_sel << 8) |
572 (midpi_cap_sel << 9) | (0x1 << 10) | (0x3 << 17) | (lp3_sel << 20));
573
574 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
Julius Werner55009af2019-12-02 22:03:27 -0800575 clrsetbits32(&ch[chn].phy.shu[0].ca_dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800576 (0xf << 9) | (0x1f << 16) | (0x7ff << 21),
577 (0x1 << 8) | (0x7 << 13) | (0x4 << 16));
578
579 for (u8 b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -0800580 clrsetbits32(&ch[chn].phy.shu[0].b[b].dq[6],
Huayang Duan73780152019-08-19 14:06:31 +0800581 (0x1f << 6) | (0x3f << 11) | (0x7 << 19),
582 (0x1 << 6) | (hyst_sel << 8) | (midpi_cap_sel << 9)
583 | (0x1 << 10) | (0x3 << 17) | (lp3_sel << 20));
584
Julius Werner55009af2019-12-02 22:03:27 -0800585 clrsetbits32(&ch[chn].phy.shu[0].b[b].dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800586 (0x3 << 8) | (0x3 << 11) | (0x7 << 14) | (0x3fff << 18),
587 (0x1 << 10) | (0x1 << 13) | (0x1 << 17));
588 }
589 }
590}
591
592static void dramc_duty_set_clk_delay(u8 chn, s8 clkDelay)
593{
594 u8 dly, dlyb, revb0, revb1;
595
596 dly = (clkDelay < 0) ? -clkDelay : 0;
597 dlyb = (clkDelay < 0) ? 0 : clkDelay;
598 revb0 = dly ? 1 : 0;
599 revb1 = dlyb ? 1 : 0;
600
601 for (u8 r = 0; r < RANK_MAX; r++) {
Julius Werner55009af2019-12-02 22:03:27 -0800602 clrsetbits32(&ch[chn].phy.shu[0].rk[r].ca_cmd[1],
Huayang Duan73780152019-08-19 14:06:31 +0800603 (0xf << 24) | (0xf << 28), (dly << 24) | (dly << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800604 clrsetbits32(&ch[chn].phy.shu[0].rk[r].ca_cmd[0],
Huayang Duan73780152019-08-19 14:06:31 +0800605 (0xf << 24) | (0xf << 28), (dlyb << 24) | (dlyb << 28));
606 }
Julius Werner55009af2019-12-02 22:03:27 -0800607 clrsetbits32(&ch[chn].phy.shu[0].ca_cmd[3],
Huayang Duan73780152019-08-19 14:06:31 +0800608 (0x3 << 8), (revb0 << 8) | (revb1 << 9));
609}
610
611static void dramc_duty_set_dqs_delay(u8 chn, const s8 *s_dqsDelay)
612{
613 u8 dly, dlyb, revb0, revb1;
614 s8 dqsDelay;
615
616 for (u8 r = 0; r < RANK_MAX; r++)
617 for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) {
618 dqsDelay = s_dqsDelay[dqs];
619
620 dly = (dqsDelay < 0) ? -dqsDelay : 0;
621 dlyb = (dqsDelay < 0) ? 0 : dqsDelay;
622 revb0 = dly ? 1 : 0;
623 revb1 = dlyb ? 1 : 0;
Julius Werner55009af2019-12-02 22:03:27 -0800624 clrsetbits32(&ch[chn].phy.shu[0].rk[r].b[dqs].dq[1],
Huayang Duan73780152019-08-19 14:06:31 +0800625 (0xf << 24) | (0xf << 28) | (0xf << 16) | (0xf << 20),
626 (dly << 24) | (dly << 28) | (dlyb << 16) | (dlyb << 20));
627 }
Julius Werner55009af2019-12-02 22:03:27 -0800628 clrsetbits32(&ch[chn].phy.shu[0].b[0].dll[1],
Huayang Duan73780152019-08-19 14:06:31 +0800629 0x3 << 8, (revb0 << 8) | (revb1 << 9));
630}
631
632static void dramc_duty_calibration(const struct sdram_params *params, u8 freq_group)
633{
Huayang Duan846be442019-08-30 18:01:19 +0800634 switch (params->source) {
635 case DRAMC_PARAM_SOURCE_SDRAM_CONFIG:
636 break;
637 case DRAMC_PARAM_SOURCE_FLASH:
638 dramc_dbg("bypass duty calibration\n");
639
640 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
641 dramc_duty_set_clk_delay(chn, params->duty_clk_delay[chn]);
642 dramc_duty_set_dqs_delay(chn, params->duty_dqs_delay[chn]);
643 }
644 return;
645 default:
646 die("Invalid DRAM param source %u\n", params->source);
647 return;
648 }
649
Huayang Duan73780152019-08-19 14:06:31 +0800650 s8 clkDelay[CHANNEL_MAX] = {0x0};
651 s8 dqsDelay[CHANNEL_MAX][DQS_NUMBER] = {0x0};
652
653 switch (freq_group) {
654 case LP4X_DDR1600:
655 clkDelay[CHANNEL_A] = 2;
656 clkDelay[CHANNEL_B] = 1;
657 dqsDelay[CHANNEL_A][0] = 0;
658 dqsDelay[CHANNEL_A][1] = 0;
659 dqsDelay[CHANNEL_B][0] = -1;
660 dqsDelay[CHANNEL_B][1] = 0;
661 break;
662 case LP4X_DDR2400:
663 clkDelay[CHANNEL_A] = clkDelay[CHANNEL_B] = 0;
664 dqsDelay[CHANNEL_A][0] = 0;
665 dqsDelay[CHANNEL_A][1] = -2;
666 dqsDelay[CHANNEL_B][0] = 0;
667 dqsDelay[CHANNEL_B][1] = -2;
668 break;
669 case LP4X_DDR3200:
670 clkDelay[CHANNEL_A] = clkDelay[CHANNEL_B] = 1;
671 dqsDelay[CHANNEL_A][0] = 1;
672 dqsDelay[CHANNEL_A][1] = -2;
673 dqsDelay[CHANNEL_B][0] = 1;
674 dqsDelay[CHANNEL_B][1] = -2;
675 break;
676 case LP4X_DDR3600:
677 clkDelay[CHANNEL_A] = 2;
678 clkDelay[CHANNEL_B] = 1;
679 dqsDelay[CHANNEL_A][0] = 0;
680 dqsDelay[CHANNEL_A][1] = 0;
681 dqsDelay[CHANNEL_B][0] = -1;
682 dqsDelay[CHANNEL_B][1] = 0;
683 break;
684 default:
685 die("Invalid DDR frequency group %u\n", freq_group);
686 return;
687 }
688
689 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
690 dramc_duty_set_clk_delay(chn, clkDelay[chn]);
691 dramc_duty_set_dqs_delay(chn, dqsDelay[chn]);
692 }
693}
694
695static u8 dramc_zq_calibration(u8 chn, u8 rank)
696{
697 const u32 TIMEOUT_US = 100;
698
699 struct reg_value regs_bak[] = {
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800700 {&ch[chn].ao.mrs},
701 {&ch[chn].ao.dramc_pd_ctrl},
702 {&ch[chn].ao.ckectrl},
Huayang Duan73780152019-08-19 14:06:31 +0800703 };
704
705 for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++)
706 regs_bak[i].value = read32(regs_bak[i].addr);
707
Julius Werner55009af2019-12-02 22:03:27 -0800708 setbits32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26);
Huayang Duan63ee1602020-06-01 16:30:27 +0800709 dramc_cke_fix_onoff(CKE_FIXON, chn);
Huayang Duan73780152019-08-19 14:06:31 +0800710
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800711 SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRSRK, rank);
712 SET32_BITFIELDS(&ch[chn].ao.mpc_option, MPC_OPTION_MPCRKEN, 1);
713 SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_ZQCEN, 1);
Huayang Duan73780152019-08-19 14:06:31 +0800714
715 if (!wait_us(TIMEOUT_US, read32(&ch[chn].nao.spcmdresp) & 0x1 << 4)) {
716 dramc_dbg("ZQCAL Start fail (time out)\n");
717 return 1;
718 }
719
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800720 SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_ZQCEN, 0);
Huayang Duan73780152019-08-19 14:06:31 +0800721
722 udelay(1);
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800723 SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_ZQLATEN, 1);
Huayang Duan73780152019-08-19 14:06:31 +0800724
725 if (!wait_us(TIMEOUT_US, read32(&ch[chn].nao.spcmdresp) & 0x1 << 6)) {
726 dramc_dbg("ZQCAL Latch fail (time out)\n");
727 return 1;
728 }
729
Hung-Te Lin5b29f172019-09-19 17:49:34 +0800730 SET32_BITFIELDS(&ch[chn].ao.spcmd, SPCMD_ZQLATEN, 0);
Huayang Duan73780152019-08-19 14:06:31 +0800731 udelay(1);
732 for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++)
733 write32(regs_bak[i].addr, regs_bak[i].value);
734
735 return 0;
736}
737
Yu-Ping Wu947916e2019-10-24 15:51:19 +0800738static void dramc_mode_reg_init(u8 freq_group, struct mr_value *mr)
Huayang Duan73780152019-08-19 14:06:31 +0800739{
Yu-Ping Wu947916e2019-10-24 15:51:19 +0800740 u8 *MR01Value = mr->MR01Value;
Huayang Duan73780152019-08-19 14:06:31 +0800741 u8 MR02Value[FSP_MAX] = {0x12, 0x12};
742 u8 MR03Value = 0x30;
743 u8 MR11Value[FSP_MAX] = {0x0, 0x23};
744 u8 MR12Value[CHANNEL_MAX][RANK_MAX][FSP_MAX] = {
745 {{0x5d, 0x5d}, {0x5d, 0x5d} }, {{0x5d, 0x5d}, {0x5d, 0x5d} },
746 };
Yu-Ping Wu947916e2019-10-24 15:51:19 +0800747 u8 MR13Value;
Huayang Duan73780152019-08-19 14:06:31 +0800748 u8 MR14Value[CHANNEL_MAX][RANK_MAX][FSP_MAX] = {
749 {{0x5d, 0x10}, {0x5d, 0x10} }, {{0x5d, 0x10}, {0x5d, 0x10} },
750 };
751
752 u8 MR22Value[FSP_MAX] = {0x38, 0x34};
753
Yu-Ping Wu947916e2019-10-24 15:51:19 +0800754 MR01Value[FSP_0] = 0x6;
755 MR01Value[FSP_1] = 0x6;
Huayang Duan73780152019-08-19 14:06:31 +0800756
757 if (freq_group == LP4X_DDR1600) {
758 MR02Value[0] = 0x12;
759 MR02Value[1] = 0x00;
760
761 MR01Value[FSP_0] |= (0x5 << 4);
762 MR01Value[FSP_1] |= (0x5 << 4);
763 } else if (freq_group == LP4X_DDR2400) {
764 MR02Value[0] = 0x24;
765 MR02Value[1] = 0x2d;
766
767 MR01Value[FSP_0] |= (0x5 << 4);
768 MR01Value[FSP_1] |= (0x5 << 4);
769 } else if (freq_group == LP4X_DDR3200) {
770 MR02Value[0] = 0x12;
771 MR02Value[1] = 0x2d;
772
773 MR01Value[FSP_0] |= (0x5 << 4);
774 MR01Value[FSP_1] |= (0x5 << 4);
775 } else if (freq_group == LP4X_DDR3600) {
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800776 MR02Value[0] = 0x1a;
Huayang Duan73780152019-08-19 14:06:31 +0800777 MR02Value[1] = 0x36;
778
779 MR01Value[FSP_0] |= (0x6 << 4);
780 MR01Value[FSP_1] |= (0x6 << 4);
781 }
782
783 u8 operate_fsp = get_freq_fsq(freq_group);
784 dramc_dbg("%s operate_fsp:%d, freq:%d\n", __func__, operate_fsp, freq_group);
785
786 u8 chn, rank;
787 u32 broadcast_bak = dramc_get_broadcast();
788 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
789 dramc_power_on_sequence();
790
791 for (chn = 0; chn < CHANNEL_MAX; chn++) {
792 for (rank = 0; rank < 2; rank++) {
Julius Werner55009af2019-12-02 22:03:27 -0800793 clrsetbits32(&ch[chn].ao.mrs, 0x3 << 24, rank << 24);
Huayang Duan73780152019-08-19 14:06:31 +0800794
795 dramc_zq_calibration(chn, rank);
796
797 for (uint32_t fsp = FSP_0; fsp < FSP_MAX; fsp++) {
798 dramc_dbg("chn:%d,rank:%d,fsp%d\n", chn, rank, fsp);
799
800 if (fsp == FSP_0)
801 MR13Value = (1 << 4) | (1 << 3);
802 else
803 MR13Value |= 0x40;
804 dramc_mode_reg_write(chn, 0xd, MR13Value);
805 dramc_mode_reg_write(chn, 0xc,
806 MR12Value[chn][rank][fsp]);
807 dramc_mode_reg_write(chn, 0x1, MR01Value[fsp]);
808 dramc_mode_reg_write(chn, 0x2, MR02Value[fsp]);
809 dramc_mode_reg_write(chn, 0xb, MR11Value[fsp]);
810
811 dramc_mode_reg_write(chn, 0x16, MR22Value[fsp]);
812 dramc_mode_reg_write(chn, 0xe,
813 MR14Value[chn][rank][fsp]);
814
815 /* MR3 set write-DBI and read-DBI */
816 dramc_mode_reg_write(chn, 0x3, MR03Value);
817 }
818
819 if (operate_fsp == FSP_0)
820 MR13Value &= 0x3f;
821 else
822 MR13Value |= 0xc0;
823 dramc_mode_reg_write(chn, 0xd, MR13Value);
824 }
825
Julius Werner55009af2019-12-02 22:03:27 -0800826 clrsetbits32(&ch[chn].ao.shu[0].hwset_mr13,
Huayang Duan73780152019-08-19 14:06:31 +0800827 (0x1fff << 0) | (0xff << 16),
828 (13 << 0) | ((MR13Value | (0x1 << 3)) << 16));
Julius Werner55009af2019-12-02 22:03:27 -0800829 clrsetbits32(&ch[chn].ao.shu[0].hwset_vrcg,
Huayang Duan73780152019-08-19 14:06:31 +0800830 (0x1fff << 0) | (0xff << 16),
831 (13 << 0) | ((MR13Value | (0x1 << 3)) << 16));
Julius Werner55009af2019-12-02 22:03:27 -0800832 clrsetbits32(&ch[chn].ao.shu[0].hwset_mr2,
Huayang Duan73780152019-08-19 14:06:31 +0800833 (0x1fff << 0) | (0xff << 16),
834 (2 << 0) | (MR02Value[operate_fsp] << 16));
835 }
836
Yu-Ping Wu947916e2019-10-24 15:51:19 +0800837 mr->MR13Value = MR13Value;
838
Julius Werner55009af2019-12-02 22:03:27 -0800839 clrsetbits32(&ch[0].ao.mrs, 0x3 << 24, RANK_0 << 24);
840 clrsetbits32(&ch[1].ao.mrs, 0x3 << 24, RANK_0 << 24);
Huayang Duan73780152019-08-19 14:06:31 +0800841 dramc_set_broadcast(broadcast_bak);
842}
843
844static void auto_refresh_cke_off(void)
845{
846 u32 broadcast_bak = dramc_get_broadcast();
847 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
848
849 for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800850 setbits32(&ch[chn].ao.refctrl0, 0x1 << 29);
Huayang Duan73780152019-08-19 14:06:31 +0800851
852 udelay(3);
Huayang Duan63ee1602020-06-01 16:30:27 +0800853 dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_A);
854 dramc_cke_fix_onoff(CKE_FIXOFF, CHANNEL_B);
Huayang Duan73780152019-08-19 14:06:31 +0800855
856 dramc_set_broadcast(broadcast_bak);
857}
858
859static void dramc_setting_DDR1600(void)
860{
Julius Werner55009af2019-12-02 22:03:27 -0800861 clrsetbits32(&ch[0].ao.shu[0].rankctl,
Huayang Duan73780152019-08-19 14:06:31 +0800862 (0xf << 20) | (0xf << 24) | (0xf << 28),
863 (0x0 << 20) | (0x0 << 24) | (0x2 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800864 clrbits32(&ch[0].ao.shu[0].ckectrl, 0x3 << 24);
865 clrbits32(&ch[0].ao.shu[0].odtctrl, (0x1 << 0) | (0x3 << 30));
Huayang Duan73780152019-08-19 14:06:31 +0800866
Julius Werner55009af2019-12-02 22:03:27 -0800867 clrbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
868 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
Huayang Duan73780152019-08-19 14:06:31 +0800869
Julius Werner55009af2019-12-02 22:03:27 -0800870 clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_1600);
871 clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_1600);
872 clrsetbits32(&ch[0].ao.shu[0].wodt, (0x1 << 29) | (0x1 << 31),
Huayang Duan73780152019-08-19 14:06:31 +0800873 (0x0 << 29) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800874 clrsetbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0, 0x4 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800875
876 for (size_t rank = 0; rank < 2; rank++) {
877 int value = ((rank == 0) ? 0x1a : 0x1e);
Julius Werner55009af2019-12-02 22:03:27 -0800878 clrbits32(&ch[0].ao.shu[0].rk[rank].dqsien, (0x7f << 0) | (0x7f << 8));
879 clrsetbits32(&ch[0].ao.shu[0].rk[rank].fine_tune,
Huayang Duan73780152019-08-19 14:06:31 +0800880 (0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
881 (value << 0) | (value << 8) | (value << 16) | (value << 24));
882
Julius Werner55009af2019-12-02 22:03:27 -0800883 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
Huayang Duan73780152019-08-19 14:06:31 +0800884 (0x7 << 8) | (0x7 << 12) |
885 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
886 (0x2 << 8) | (0x2 << 12) |
887 (0x1 << 16) | (0x1 << 20) | (0x1 << 24) | (0x1 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800888 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[1],
Huayang Duan73780152019-08-19 14:06:31 +0800889 (0x7 << 8) | (0x7 << 12) |
890 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
891 (0x2 << 8) | (0x2 << 12) |
892 (0x1 << 16) | (0x1 << 20) | (0x1 << 24) | (0x1 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800893 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800894 0x77777777, _SELPH_DQS_BITS(0x1, 0x7));
Julius Werner55009af2019-12-02 22:03:27 -0800895 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800896 0x77777777, _SELPH_DQS_BITS(0x1, 0x7));
Huayang Duan73780152019-08-19 14:06:31 +0800897 }
898
Julius Werner55009af2019-12-02 22:03:27 -0800899 clrsetbits32(&ch[0].ao.shu[0].dqsg_retry, (0x1 << 2) | (0xf << 8),
Huayang Duan73780152019-08-19 14:06:31 +0800900 (0x0 << 2) | (0x3 << 8));
Huayang Duancac990f2020-06-08 17:40:55 +0800901 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[5], 0x7 << 20, 0x4 << 20);
902 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
903 (0x3 << 4) | (0x1 << 7) | (0x1 << 13),
904 (0x2 << 4) | (0x0 << 7) | (0x0 << 13));
905 clrsetbits32(&ch[0].phy.shu[0].b[1].dq[5], 0x7 << 20, 0x4 << 20);
906 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 7) | (0x1 << 13));
Huayang Duan73780152019-08-19 14:06:31 +0800907
908 for (size_t r = 0; r < 2; r++) {
909 int value = ((r == 0) ? 0x1a : 0x26);
910 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -0800911 clrsetbits32(&ch[0].phy.shu[0].rk[r].b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800912 (0x3f << 8) | (0x3f << 16),
913 (value << 8) | (value << 16));
914 }
915}
916
917static void dramc_setting_DDR2400(void)
918{
Julius Werner55009af2019-12-02 22:03:27 -0800919 clrsetbits32(&ch[0].ao.shu[0].rankctl,
Huayang Duan73780152019-08-19 14:06:31 +0800920 (0xf << 20) | (0xf << 24) | (0xf << 28),
921 (0x2 << 20) | (0x2 << 24) | (0x4 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800922 clrsetbits32(&ch[0].ao.shu[0].ckectrl, 0x3 << 24, 0x3 << 24);
923 setbits32(&ch[0].ao.shu[0].odtctrl, (0x1 << 0) | (0x1 << 30) | (0x1 << 31));
Huayang Duan73780152019-08-19 14:06:31 +0800924
Julius Werner55009af2019-12-02 22:03:27 -0800925 setbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
926 setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
Huayang Duan73780152019-08-19 14:06:31 +0800927
Julius Werner55009af2019-12-02 22:03:27 -0800928 clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_2400);
929 clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_2400);
930 clrsetbits32(&ch[0].ao.shu[0].wodt,
Huayang Duan73780152019-08-19 14:06:31 +0800931 (0x1 << 29) | (0x1 << 31), (0x1 << 29) | (0x0 << 31));
Julius Werner55009af2019-12-02 22:03:27 -0800932 clrsetbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0, 0x7 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800933
934 for (size_t rank = 0; rank < 2; rank++) {
935 int value = ((rank == 0) ? 0x19 : 0x1f);
Julius Werner55009af2019-12-02 22:03:27 -0800936 clrsetbits32(&ch[0].ao.shu[0].rk[rank].dqsien,
Huayang Duan73780152019-08-19 14:06:31 +0800937 (0x7f << 0) | (0x7f << 8), (value << 0) | (value << 8));
Julius Werner55009af2019-12-02 22:03:27 -0800938 clrsetbits32(&ch[0].ao.shu[0].rk[rank].fine_tune,
Huayang Duan73780152019-08-19 14:06:31 +0800939 (0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
940 (0x14 << 0) | (0x14 << 8) | (0x14 << 16) | (0x14 << 24));
941
Julius Werner55009af2019-12-02 22:03:27 -0800942 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
Huayang Duan73780152019-08-19 14:06:31 +0800943 (0x7 << 8) | (0x7 << 12) |
944 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
945 (0x3 << 8) | (0x3 << 12) |
946 (0x3 << 16) | (0x3 << 20) | (0x3 << 24) | (0x3 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800947 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[1],
Huayang Duan73780152019-08-19 14:06:31 +0800948 (0x7 << 8) | (0x7 << 12) |
949 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
950 (0x3 << 8) | (0x3 << 12) |
951 (0x3 << 16) | (0x3 << 20) | (0x3 << 24) | (0x3 << 28));
Julius Werner55009af2019-12-02 22:03:27 -0800952 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800953 0x77777777, _SELPH_DQS_BITS(0x2, 0x0));
Julius Werner55009af2019-12-02 22:03:27 -0800954 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +0800955 0x77777777, _SELPH_DQS_BITS(0x2, 0x0));
Huayang Duan73780152019-08-19 14:06:31 +0800956 }
957
Julius Werner55009af2019-12-02 22:03:27 -0800958 clrsetbits32(&ch[0].ao.shu[0].dqsg_retry,
Huayang Duan73780152019-08-19 14:06:31 +0800959 (0x1 << 2) | (0xf << 8), (0x1 << 2) | (0x4 << 8));
Huayang Duancac990f2020-06-08 17:40:55 +0800960 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[5], 0x7 << 20, 0x3 << 20);
961 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7],
962 (0x3 << 4) | (0x1 << 7) | (0x1 << 13),
Huayang Duan73780152019-08-19 14:06:31 +0800963 (0x1 << 4) | (0x1 << 7) | (0x1 << 13));
Huayang Duancac990f2020-06-08 17:40:55 +0800964 clrsetbits32(&ch[0].phy.shu[0].b[1].dq[5], 0x7 << 20, 0x3 << 20);
965 clrsetbits32(&ch[0].phy.shu[0].b[1].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800966 (0x1 << 7) | (0x1 << 13), (0x1 << 7) | (0x1 << 13));
967
968 for (size_t r = 0; r < 2; r++) {
969 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -0800970 clrsetbits32(&ch[0].phy.shu[0].rk[r].b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +0800971 (0x3f << 8) | (0x3f << 16), (0x14 << 8) | (0x14 << 16));
972 }
973}
974
975static void dramc_setting_DDR3600(void)
976{
Julius Werner55009af2019-12-02 22:03:27 -0800977 clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_3600);
978 clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_3600);
Huayang Duan73780152019-08-19 14:06:31 +0800979}
980
Yu-Ping Wu4d4ccce2019-10-03 08:49:23 +0800981static void dramc_setting(const struct sdram_params *params, u8 freq_group,
982 const struct dram_impedance *impedance)
Huayang Duan73780152019-08-19 14:06:31 +0800983{
984 u8 chn;
985
986 auto_refresh_cke_off();
987 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
988
989 for (chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -0800990 setbits32(&ch[chn].phy.ckmux_sel, (0x1 << 0) | (0x1 << 1));
Huayang Duan73780152019-08-19 14:06:31 +0800991
992 dramc_set_broadcast(DRAMC_BROADCAST_ON);
993
Julius Werner55009af2019-12-02 22:03:27 -0800994 setbits32(&ch[0].phy.misc_cg_ctrl0, 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +0800995
996 /* 26M */
Julius Werner55009af2019-12-02 22:03:27 -0800997 clrbits32(&ch[0].phy.misc_cg_ctrl0, 0x3 << 4);
998 clrbits32(&ch[0].phy.misc_ctrl0, 0x1 << 17);
Huayang Duan73780152019-08-19 14:06:31 +0800999
Julius Werner55009af2019-12-02 22:03:27 -08001000 clrbits32(&ch[0].phy.misc_spm_ctrl1, 0xf << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001001 write32(&ch[0].phy.misc_spm_ctrl2, 0x0);
1002 write32(&ch[0].phy.misc_spm_ctrl0, 0x0);
1003 write32(&ch[0].phy.misc_cg_ctrl2, 0x6003bf);
1004 write32(&ch[0].phy.misc_cg_ctrl4, 0x333f3f00);
Julius Werner55009af2019-12-02 22:03:27 -08001005 setbits32(&ch[0].phy.shu[0].pll[1], (0x1 << 4) | (0x7 << 1));
1006 clrsetbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x3f << 0, 0x10 << 0);
1007 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x0f << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001008
1009 for (size_t b = 0; b <= 2; b += 2)
Julius Werner55009af2019-12-02 22:03:27 -08001010 clrsetbits32(&ch[0].phy.shu[0].pll[4 + b],
Huayang Duan73780152019-08-19 14:06:31 +08001011 (0x3 << 18) | (0x3 << 24) | (0x3 << 26),
1012 (0x2 << 18) | (0x1 << 24) | (0x1 << 26));
1013
Julius Werner55009af2019-12-02 22:03:27 -08001014 clrbits32(&ch[0].phy.shu[0].pll[14], 0x1 << 1);
1015 clrbits32(&ch[0].phy.shu[0].pll20, 0x1 << 1);
1016 clrbits32(&ch[0].phy.ca_cmd[2], (0x3 << 16) | (0x3 << 20));
Huayang Duan73780152019-08-19 14:06:31 +08001017 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001018 clrbits32(&ch[0].phy.b[b].dq[2], (0x3 << 16) | (0x3 << 20));
Huayang Duan73780152019-08-19 14:06:31 +08001019 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001020 clrsetbits32(&ch[0].phy.b[b].dq[9], 0x7 << 28, 0x1 << 28);
1021 clrbits32(&ch[0].phy.ca_cmd[10], 0x7 << 28);
Huayang Duan73780152019-08-19 14:06:31 +08001022
Julius Werner55009af2019-12-02 22:03:27 -08001023 setbits32(&ch[0].phy.b0_rxdvs[0], 0x1 << 28);
1024 setbits32(&ch[0].phy.b1_rxdvs[0], 0x1 << 28);
1025 setbits32(&ch[0].phy.b0_rxdvs[0], 0x1 << 9);
1026 setbits32(&ch[0].phy.b1_rxdvs[0], 0x1 << 9);
Huayang Duan73780152019-08-19 14:06:31 +08001027
1028 for (size_t b = 0; b < 2; b++) {
1029 for (size_t r = 0; r < 2; r++)
Julius Werner55009af2019-12-02 22:03:27 -08001030 setbits32(&ch[0].phy.r[r].b[b].rxdvs[2], 0x1 << 29);
1031 clrsetbits32(&ch[0].phy.shu[0].b[b].dq[5], 0x7 << 20, 0x3 << 20);
Huayang Duan73780152019-08-19 14:06:31 +08001032
1033 for (size_t r = 0; r < 2; r++) {
Julius Werner55009af2019-12-02 22:03:27 -08001034 clrsetbits32(&ch[0].phy.r[r].b[b].rxdvs[1],
Huayang Duan73780152019-08-19 14:06:31 +08001035 (0xffff << 0) | (0xffff << 16), (0x2 << 0) | (0x2 << 16));
Julius Werner55009af2019-12-02 22:03:27 -08001036 clrsetbits32(&ch[0].phy.r[r].b[b].rxdvs[2],
Huayang Duan73780152019-08-19 14:06:31 +08001037 (0x1 << 23) | (0x1 << 28) | (0x3 << 30),
1038 (0x1 << 23) | (0x1 << 28) | (0x2 << 30));
1039 }
1040 }
1041
Julius Werner55009af2019-12-02 22:03:27 -08001042 clrbits32(&ch[0].phy.b0_rxdvs[0], 0x1 << 28);
1043 clrbits32(&ch[0].phy.b1_rxdvs[0], 0x1 << 28);
Huayang Duan73780152019-08-19 14:06:31 +08001044
1045 for (size_t b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -08001046 setbits32(&ch[0].phy.b[b].dq[9], 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001047 for (size_t r = 0; r < 2; r++)
Julius Werner55009af2019-12-02 22:03:27 -08001048 clrsetbits32(&ch[0].phy.shu[0].rk[r].b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +08001049 (0x3f << 8) | (0x3f << 16), (0x1f << 8) | (0x1f << 16));
1050
Julius Werner55009af2019-12-02 22:03:27 -08001051 clrsetbits32(&ch[0].phy.b[b].dq[4],
Huayang Duan73780152019-08-19 14:06:31 +08001052 (0x7f << 0) | (0x7f << 8), (0x10 << 0) | (0x10 << 8));
Julius Werner55009af2019-12-02 22:03:27 -08001053 clrsetbits32(&ch[0].phy.b[b].dq[5],
Huayang Duan73780152019-08-19 14:06:31 +08001054 (0xff << 0) | (0x3f << 8) | (0x1 << 16) | (0xf << 20) | (0x1 << 24),
1055 (0x10 << 0) | (0xe << 8) | (0x1 << 16) | (0x1 << 20) | (0x0 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001056 clrsetbits32(&ch[0].phy.b[b].dq[6],
Huayang Duan73780152019-08-19 14:06:31 +08001057 (0x1 << 4) | (0x1 << 7) | (0x1 << 12) | (0x3 << 14) |
1058 (0xf << 16) | (0x1 << 24),
1059 (0x0 << 4) | (0x1 << 7) | (0x1 << 12) | (0x0 << 14) |
1060 (0x3 << 16) | (0x1 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001061 clrsetbits32(&ch[0].phy.b[b].dq[5],
Huayang Duan73780152019-08-19 14:06:31 +08001062 (0xff << 0) | (0x1 << 25), (0x0 << 0) | (0x1 << 25));
1063 }
1064
Julius Werner55009af2019-12-02 22:03:27 -08001065 setbits32(&ch[0].phy.ca_cmd[3], (0x3 << 2) | (0x1 << 7));
1066 clrsetbits32(&ch[0].phy.ca_cmd[6], (0x1 << 6) | (0x3 << 14) | (0x1 << 16),
Huayang Duan73780152019-08-19 14:06:31 +08001067 (0x0 << 6) | (0x0 << 14) | (0x0 << 16));
1068
Huayang Duancac990f2020-06-08 17:40:55 +08001069 clrbits32(&ch[0].phy.pll3, 0x1 << 0);
Julius Werner55009af2019-12-02 22:03:27 -08001070 setbits32(&ch[0].phy.b[0].dq[3], 0x1 << 3);
1071 setbits32(&ch[0].phy.b[1].dq[3], 0x1 << 3);
Huayang Duan73780152019-08-19 14:06:31 +08001072
1073 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -08001074 clrsetbits32(&ch[0].phy.shu[0].pll[8],
Huayang Duan73780152019-08-19 14:06:31 +08001075 (0x7 << 0) | (0x3 << 18), (0x0 << 0) | (0x1 << 18));
1076
1077 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -08001078 clrbits32(&ch[0].phy.shu[0].pll[9],
Huayang Duan73780152019-08-19 14:06:31 +08001079 (0x3 << 8) | (0x1 << 12) | (0x3 << 14) | (0x1 << 16));
Julius Werner55009af2019-12-02 22:03:27 -08001080 clrbits32(&ch[0].phy.shu[0].pll[11],
Huayang Duan73780152019-08-19 14:06:31 +08001081 (0x3 << 8) | (0x1 << 12) | (0x3 << 14) | (0x1 << 16));
1082 udelay(1);
1083
Julius Werner55009af2019-12-02 22:03:27 -08001084 clrsetbits32(&ch[0].phy.shu[0].pll[10],
Huayang Duan73780152019-08-19 14:06:31 +08001085 (0x7 << 0) | (0x3 << 18), (0x0 << 0) | (0x1 << 18));
1086 udelay(1);
1087
1088 /* PLL EN */
1089 /* MID FINE_TUNE Init 1 */
Julius Werner55009af2019-12-02 22:03:27 -08001090 clrsetbits32(&ch[0].phy.pll4, (0x3 << 18) | (0x1 << 21), 0x3 << 18);
Huayang Duan73780152019-08-19 14:06:31 +08001091
1092 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -08001093 clrsetbits32(&ch[0].phy.shu[0].pll[0], 0xffff << 0, 0x3 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001094
1095 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -08001096 setbits32(&ch[0].phy.ca_dll_fine_tune[1], 0x1 << 21);
Huayang Duan73780152019-08-19 14:06:31 +08001097
1098 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001099 setbits32(&ch[0].phy.b[b].dq[3], (0x3 << 1) | (0x1 << 10));
Huayang Duancac990f2020-06-08 17:40:55 +08001100
1101 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
Julius Werner55009af2019-12-02 22:03:27 -08001102 setbits32(&ch[0].phy.shu[0].ca_dll[0], 0x1 << 0);
Huayang Duancac990f2020-06-08 17:40:55 +08001103 setbits32(&ch[1].phy.shu[0].ca_dll[0], 0x1 << 0);
1104 dramc_set_broadcast(DRAMC_BROADCAST_ON);
Huayang Duan73780152019-08-19 14:06:31 +08001105
1106 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001107 clrsetbits32(&ch[0].phy.shu[0].b[b].dll[0],
Huayang Duan73780152019-08-19 14:06:31 +08001108 (0x1 << 4) | (0x3 << 9) | (0xf << 12) |
1109 (0xf << 16) | (0xf << 20) | (0x1 << 30),
1110 (0x0 << 4) | (0x3 << 9) | (0x8 << 12) |
1111 (0x7 << 16) | (0x7 << 20) | (0x1 << 30));
1112
Julius Werner55009af2019-12-02 22:03:27 -08001113 clrbits32(&ch[0].phy.shu[0].ca_cmd[5], 0x3f << 0);
1114 clrsetbits32(&ch[0].phy.shu[0].ca_cmd[0],
Huayang Duan73780152019-08-19 14:06:31 +08001115 (0x1 << 4) | (0x7 << 12) | (0x1 << 20),
1116 (0x1 << 4) | (0x4 << 12) | (0x1 << 20));
1117
1118 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
Julius Werner55009af2019-12-02 22:03:27 -08001119 clrsetbits32(&ch[0].phy.shu[0].ca_cmd[6], 0xffff << 6, 0x3 << 6);
1120 clrsetbits32(&ch[1].phy.shu[0].ca_cmd[6], 0xffff << 6, 0x1 << 6);
Huayang Duan73780152019-08-19 14:06:31 +08001121 dramc_set_broadcast(DRAMC_BROADCAST_ON);
1122
1123 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001124 clrsetbits32(&ch[0].phy.shu[0].b[b].dq[6], 0xffff << 6, 0x1 << 6);
Huayang Duan73780152019-08-19 14:06:31 +08001125
1126 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001127 for (chn = 0; chn < CHANNEL_MAX; chn++)
Julius Werner55009af2019-12-02 22:03:27 -08001128 clrsetbits32(&ch[chn].phy.misc_shu_opt,
Huayang Duan73780152019-08-19 14:06:31 +08001129 (0x1 << 0) | (0x3 << 2) | (0x1 << 8) |
1130 (0x3 << 10) | (0x1 << 16) | (0x3 << 18),
1131 (0x1 << 0) | (0x2 << 2) | (0x1 << 8) |
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001132 (0x2 << 10) | (0x1 << 16) | ((0x1 + chn) << 18));
Huayang Duan73780152019-08-19 14:06:31 +08001133
1134 udelay(9);
Julius Werner55009af2019-12-02 22:03:27 -08001135 clrsetbits32(&ch[0].phy.shu[0].ca_dll[1], (0x1 << 0) | (0x1 << 2), 0x1 << 2);
1136 clrsetbits32(&ch[1].phy.shu[0].ca_dll[1], (0x1 << 0) | (0x1 << 2), 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001137 dramc_set_broadcast(DRAMC_BROADCAST_ON);
1138
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001139 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001140 clrsetbits32(&ch[0].phy.shu[0].b[b].dll[1],
Huayang Duan73780152019-08-19 14:06:31 +08001141 (0x1 << 0) | (0x1 << 2), (0x1 << 0) | (0x0 << 2));
Huayang Duan73780152019-08-19 14:06:31 +08001142 udelay(1);
1143
Julius Werner55009af2019-12-02 22:03:27 -08001144 clrbits32(&ch[0].phy.pll2, 0x1 << 31);
1145 clrsetbits32(&ch[0].phy.misc_cg_ctrl0, 0xffffffff, 0xf);
Huayang Duan73780152019-08-19 14:06:31 +08001146 udelay(1);
1147
1148 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
1149 ddr_phy_reserved_rg_setting(freq_group);
1150 for (chn = 0; chn < CHANNEL_MAX; chn++)
1151 ddr_phy_pll_setting(chn, freq_group);
1152
1153 dramc_set_broadcast(DRAMC_BROADCAST_ON);
Julius Werner55009af2019-12-02 22:03:27 -08001154 setbits32(&ch[0].ao.drsctrl, 0x1 << 29);
Huayang Duan73780152019-08-19 14:06:31 +08001155
1156 /* Set Run time MRR CKE fix to 1 in tMRRI old mode
1157 * to avoid no ACK from precharge all */
Julius Werner55009af2019-12-02 22:03:27 -08001158 setbits32(&ch[0].ao.ckectrl, 0x1 << 27);
1159 clrsetbits32(&ch[0].ao.dramctrl,
Huayang Duan73780152019-08-19 14:06:31 +08001160 (0x1 << 15) | (0x1 << 17) | (0x1 << 23),
1161 (0x0 << 15) | (0x1 << 17) | (0x1 << 23));
Julius Werner55009af2019-12-02 22:03:27 -08001162 setbits32(&ch[0].ao.spcmdctrl, (0x1 << 1) | (0x1 << 8) | (0x1 << 9) | (0x1 << 10));
1163 setbits32(&ch[0].phy.b[0].dq[9], 0x1 << 4);
1164 setbits32(&ch[0].phy.b[1].dq[9], 0x1 << 4);
Huayang Duan73780152019-08-19 14:06:31 +08001165
Julius Werner55009af2019-12-02 22:03:27 -08001166 clrsetbits32(&ch[0].ao.shu[0].rk[1].dqsien,
Huayang Duan73780152019-08-19 14:06:31 +08001167 (0x7f << 0) | (0x7f << 8) | (0x7f << 16) | (0x7f << 24),
1168 (0xf << 0) | (0xf << 8) | (0xf << 16) | (0xf << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001169 clrsetbits32(&ch[0].ao.stbcal1,
Huayang Duan73780152019-08-19 14:06:31 +08001170 (0x1 << 4) | (0x1 << 8) | (0x1 << 12), (0x1 << 4) | (0x1 << 8));
Julius Werner55009af2019-12-02 22:03:27 -08001171 clrsetbits32(&ch[0].ao.shu[0].dqsg_retry,
Huayang Duan73780152019-08-19 14:06:31 +08001172 (0x1 << 3) | (0xf << 8) | (0x1 << 21) | (0x1 << 31),
1173 (0x1 << 3) | (0x6 << 8) | (0x1 << 21) | (0x1 << 31));
1174
1175 for (size_t i = 0; i < 4; i++) {
Julius Werner55009af2019-12-02 22:03:27 -08001176 clrsetbits32(&ch[0].ao.shu[0].drving[i],
Huayang Duan73780152019-08-19 14:06:31 +08001177 (0x1f << 0) | (0x1f << 5) | (0x1f << 10) |
1178 (0x1f << 15) | (0x1f << 20) | (0x1f << 25),
1179 (0xa << 0) | (0xa << 5) | (0xa << 10) |
1180 (0xa << 15) | (0xa << 20) | (0xa << 25));
1181 }
1182
Julius Werner55009af2019-12-02 22:03:27 -08001183 clrsetbits32(&ch[0].ao.shuctrl2,
Huayang Duan73780152019-08-19 14:06:31 +08001184 (0x3f << 0) | (0x1 << 12) | (0x1 << 14) |
1185 (0x1 << 15) | (0xff << 16) | (0x1 << 24),
1186 (0xa << 0) | (0x1 << 12) | (0x1 << 14) |
1187 (0x1 << 15) | (0x1 << 16) | (0x0 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001188 setbits32(&ch[0].ao.dvfsdll, 0x1 << 0);
1189 setbits32(&ch[0].ao.ddrconf0,
Huayang Duan73780152019-08-19 14:06:31 +08001190 (0x1 << 12) | (0x1 << 15) | (0x1 << 20) | (0x1 << 26));
Julius Werner55009af2019-12-02 22:03:27 -08001191 setbits32(&ch[0].ao.stbcal2, (0x1 << 4) | (0x7 << 28));
1192 clrbits32(&ch[0].ao.stbcal2, 0x1 << 29);
1193 setbits32(&ch[0].ao.clkar, 0x1 << 19);
Huayang Duan73780152019-08-19 14:06:31 +08001194
1195 for (size_t b = 0; b < 2; b++)
Julius Werner55009af2019-12-02 22:03:27 -08001196 clrsetbits32(&ch[0].phy.b[b].dq[9], 0x7 << 20, 0x1 << 20);
1197 clrsetbits32(&ch[0].phy.ca_cmd[10], 0x7 << 20, 0x0 << 20);
1198 setbits32(&ch[0].phy.misc_ctrl0,
Huayang Duan73780152019-08-19 14:06:31 +08001199 (0xf << 0) | (0x1 << 9) | (0x1 << 24) | (0x1 << 31));
1200
Julius Werner55009af2019-12-02 22:03:27 -08001201 setbits32(&ch[0].phy.misc_ctrl1,
Yu-Ping Wu553e2db2019-10-16 11:05:54 +08001202 (0x1 << 2) | (0x1 << 3) | (0x1 << 15) | (0x1 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001203 clrsetbits32(&ch[0].phy.b0_rxdvs[0], 0x1 << 24, 0x1 << 24);
1204 clrsetbits32(&ch[0].phy.b1_rxdvs[0], 0x1 << 24, 0x1 << 24);
1205 clrsetbits32(&ch[0].phy.ca_rxdvs0, 0x1 << 24, 0x0 << 24);
1206 clrbits32(&ch[0].phy.ca_cmd[7], (0x1 << 4) | (0x1 << 6));
1207 clrbits32(&ch[0].phy.b[0].dq[7], 0x1 << 6);
1208 clrbits32(&ch[0].phy.b[1].dq[7], 0x1 << 6);
Huayang Duan73780152019-08-19 14:06:31 +08001209
Julius Werner55009af2019-12-02 22:03:27 -08001210 clrsetbits32(&ch[0].ao.shu[0].conf[0],
Huayang Duan73780152019-08-19 14:06:31 +08001211 (0x3f << 0) | (0x1 << 7) | (0xf << 12) | (0x1 << 24) |
1212 (0x1 << 29) | (0x3 << 30),
1213 (0x3f << 0) | (0x1 << 7) | (0x1 << 12) | (0x1 << 24) |
1214 (0x1 << 29) | (0x2 << 30));
Julius Werner55009af2019-12-02 22:03:27 -08001215 clrsetbits32(&ch[0].ao.shu[0].odtctrl,
Huayang Duan73780152019-08-19 14:06:31 +08001216 (0x1 << 0) | (0x1 << 1) | (0x7f << 16) | (0x1 << 30) | (0x1 << 31),
1217 (0x1 << 0) | (0x1 << 1) | (0x1 << 16) | (0x1 << 30) | (0x1 << 31));
Julius Werner55009af2019-12-02 22:03:27 -08001218 setbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 15);
1219 setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 15);
Huayang Duan73780152019-08-19 14:06:31 +08001220
Julius Werner55009af2019-12-02 22:03:27 -08001221 clrsetbits32(&ch[0].ao.refctrl0, 0xf << 24, 0x5 << 24);
1222 clrbits32(&ch[0].ao.shu[0].selph_ca1,
Huayang Duan73780152019-08-19 14:06:31 +08001223 (0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
1224 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001225 clrsetbits32(&ch[0].ao.shu[0].selph_ca2,
Huayang Duan73780152019-08-19 14:06:31 +08001226 (0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 16) | (0x7 << 24),
1227 (0x0 << 0) | (0x0 << 4) | (0x0 << 8) | (0x7 << 16) | (0x0 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001228 clrbits32(&ch[0].ao.shu[0].selph_ca3,
Huayang Duan73780152019-08-19 14:06:31 +08001229 (0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
1230 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001231 clrbits32(&ch[0].ao.shu[0].selph_ca4,
Huayang Duan73780152019-08-19 14:06:31 +08001232 (0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) |
1233 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001234 clrbits32(&ch[0].ao.shu[0].selph_ca5, 0x7 << 8);
Huayang Duan06264662020-04-20 19:33:28 +08001235 clrsetbits32(&ch[0].ao.shu[0].selph_dqs0, 0x77777777, SELPH_DQS0_3200);
1236 clrsetbits32(&ch[0].ao.shu[0].selph_dqs1, 0x77777777, SELPH_DQS1_3200);
Huayang Duan73780152019-08-19 14:06:31 +08001237
1238 for (size_t rank = 0; rank < 2; rank++) {
Julius Werner55009af2019-12-02 22:03:27 -08001239 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[0],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001240 0x77777777, _SELPH_DQS_BITS(0x3, 0x3));
Julius Werner55009af2019-12-02 22:03:27 -08001241 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[1],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001242 0x77777777, _SELPH_DQS_BITS(0x3, 0x3));
Julius Werner55009af2019-12-02 22:03:27 -08001243 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001244 0x77777777, _SELPH_DQS_BITS(0x6, 0x2));
Julius Werner55009af2019-12-02 22:03:27 -08001245 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
Yu-Ping Wu31ec0c42019-10-09 16:11:47 +08001246 0x77777777, _SELPH_DQS_BITS(0x6, 0x2));
Huayang Duan73780152019-08-19 14:06:31 +08001247 }
1248
1249 for (int b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -08001250 clrsetbits32(&ch[0].phy.shu[0].rk[0].b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +08001251 (0x3f << 8) | (0x3f << 16), (0x1a << 8) | (0x1a << 16));
Julius Werner55009af2019-12-02 22:03:27 -08001252 clrsetbits32(&ch[0].phy.shu[0].rk[1].b[b].dq[7],
Huayang Duan73780152019-08-19 14:06:31 +08001253 (0x3f << 8) | (0x3f << 16), (0x14 << 8) | (0x14 << 16));
1254 }
1255 udelay(1);
1256
1257 for (size_t b = 0; b < 2; b++) {
Julius Werner55009af2019-12-02 22:03:27 -08001258 setbits32(&ch[0].phy.b[b].dq[9], 0x1 << 5);
1259 clrsetbits32(&ch[0].phy.b[b].dq[6], 0x3 << 14, 0x1 << 14);
Huayang Duan73780152019-08-19 14:06:31 +08001260 }
Julius Werner55009af2019-12-02 22:03:27 -08001261 setbits32(&ch[0].ao.stbcal, 0x1 << 31);
1262 clrsetbits32(&ch[0].ao.srefctrl, (0xf << 24) | (0x1 << 30), 0x8 << 24);
1263 clrsetbits32(&ch[0].ao.shu[0].ckectrl,
Huayang Duan73780152019-08-19 14:06:31 +08001264 (0x3 << 24) | (0x3 << 28), (0x3 << 24) | (0x3 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001265 setbits32(&ch[0].ao.shu[0].pipe, (0x1 << 30) | (0x1 << 31));
1266 setbits32(&ch[0].ao.ckectrl, (0x1 << 13) | (0x1 << 31));
1267 setbits32(&ch[0].ao.rkcfg, 0x1 << 2);
1268 clrsetbits32(&ch[0].ao.shu[0].conf[2],
Huayang Duan73780152019-08-19 14:06:31 +08001269 (0x7 << 16) | (0x1 << 28), (0x7 << 16) | (0x1 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001270 clrsetbits32(&ch[0].ao.spcmdctrl, 0x1 << 26, 0x1 << 26);
1271 clrsetbits32(&ch[0].ao.shuctrl1, 0xff << 0, 0x40 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001272
Julius Werner55009af2019-12-02 22:03:27 -08001273 setbits32(&ch[0].ao.shuctrl, 0x1 << 16);
1274 clrbits32(&ch[0].ao.refctrl1, (0x1 << 1) | (0x1 << 2) | (0x1 << 3) | (0x1 << 6));
1275 clrsetbits32(&ch[0].ao.refratre_filter, (0x1 << 15) | (0x1 << 23),
Huayang Duan73780152019-08-19 14:06:31 +08001276 (0x1 << 15) | (0x0 << 23));
Julius Werner55009af2019-12-02 22:03:27 -08001277 clrbits32(&ch[0].ao.dramctrl, 0x1 << 9);
1278 setbits32(&ch[0].ao.misctl0, (0x1 << 19) | (0x1 << 24) | (0x1 << 31));
1279 setbits32(&ch[0].ao.perfctl0,
Huayang Duan73780152019-08-19 14:06:31 +08001280 (0x1 << 0) | (0x1 << 1) | (0x1 << 4) | (0x1 << 8) |
1281 (0x1 << 9) | (0x1 << 10) | (0x1 << 11) | (0x1 << 14) | (0x1 << 17));
Julius Werner55009af2019-12-02 22:03:27 -08001282 clrsetbits32(&ch[0].ao.arbctl, 0xff << 0, 0x80 << 0);
1283 clrsetbits32(&ch[0].ao.padctrl, (0x3 << 0) | (0x1 << 3), (0x1 << 0) | (0x1 << 3));
1284 setbits32(&ch[0].ao.dramc_pd_ctrl, 0x1 << 8);
1285 setbits32(&ch[0].ao.clkctrl, 0x1 << 29);
1286 clrsetbits32(&ch[0].ao.refctrl0, (0x1 << 0) | (0x7 << 12), (0x1 << 0) | (0x4 << 12));
1287 clrsetbits32(&ch[0].ao.shu[0].rankctl, (0xf << 20) | (0xf << 24) | (0xf << 28),
Huayang Duan73780152019-08-19 14:06:31 +08001288 (0x4 << 20) | (0x4 << 24) | (0x6 << 28));
1289 udelay(2);
1290
Julius Werner55009af2019-12-02 22:03:27 -08001291 clrsetbits32(&ch[0].ao.shu[0].rk[0].dqsien,
Huayang Duan73780152019-08-19 14:06:31 +08001292 (0x7f << 0) | (0x7f << 8), (0x19 << 0) | (0x19 << 8));
Julius Werner55009af2019-12-02 22:03:27 -08001293 clrsetbits32(&ch[0].ao.shu[0].rk[1].dqsien,
Huayang Duan73780152019-08-19 14:06:31 +08001294 (0x7f << 0) | (0x7f << 8) | (0x7f << 16) | (0x7f << 24),
1295 (0x1b << 0) | (0x1b << 8) | (0x0 << 16) | (0x0 << 24));
1296
Julius Werner55009af2019-12-02 22:03:27 -08001297 setbits32(&ch[0].ao.dramctrl, 0x1 << 19);
1298 clrsetbits32(&ch[0].ao.zqcs, 0xff << 0, 0x56 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001299 udelay(1);
1300
Julius Werner55009af2019-12-02 22:03:27 -08001301 clrsetbits32(&ch[0].ao.shu[0].conf[3], 0x1ff << 16, 0xff << 16);
1302 setbits32(&ch[0].ao.refctrl0, 0x1 << 30);
1303 setbits32(&ch[0].ao.srefctrl, 0x1 << 30);
1304 setbits32(&ch[0].ao.mpc_option, 0x1 << 17);
1305 setbits32(&ch[0].ao.dramc_pd_ctrl, 0x1 << 30);
1306 setbits32(&ch[0].ao.dramc_pd_ctrl, 0x1 << 0);
1307 clrsetbits32(&ch[0].ao.eyescan, (0x1 << 1) | (0xf << 16), (0x0 << 1) | (0x1 << 16));
1308 setbits32(&ch[0].ao.stbcal1, (0x1 << 10) | (0x1 << 11));
1309 clrsetbits32(&ch[0].ao.test2_1, 0xfffffff << 4, 0x10000 << 4);
1310 clrsetbits32(&ch[0].ao.test2_2, 0xfffffff << 4, 0x400 << 4);
1311 clrsetbits32(&ch[0].ao.test2_3,
Huayang Duan73780152019-08-19 14:06:31 +08001312 (0x1 << 7) | (0x7 << 8) | (0x1 << 28),
1313 (0x1 << 7) | (0x4 << 8) | (0x1 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001314 clrbits32(&ch[0].ao.rstmask, 0x1 << 29);
1315 clrbits32(&ch[0].ao.rstmask, 0x1 << 30);
Huayang Duan73780152019-08-19 14:06:31 +08001316
1317 udelay(1);
Julius Werner55009af2019-12-02 22:03:27 -08001318 clrsetbits32(&ch[0].ao.hw_mrr_fun, (0xf << 0) | (0xf << 4), (0x8 << 0) | (0x6 << 4));
Huayang Duan73780152019-08-19 14:06:31 +08001319
Julius Werner55009af2019-12-02 22:03:27 -08001320 clrbits32(&ch[0].ao.dramctrl, 0x1 << 0);
1321 clrsetbits32(&ch[0].ao.perfctl0,
Huayang Duan73780152019-08-19 14:06:31 +08001322 (0x1 << 18) | (0x1 << 19), (0x0 << 18) | (0x1 << 19));
Julius Werner55009af2019-12-02 22:03:27 -08001323 setbits32(&ch[0].ao.spcmdctrl, 0x1 << 28);
1324 clrbits32(&ch[0].ao.rstmask, 0x1 << 28);
1325 setbits32(&ch[0].ao.rkcfg, 0x1 << 11);
1326 setbits32(&ch[0].ao.mpc_option, 0x1 << 17);
1327 setbits32(&ch[0].ao.eyescan, 0x1 << 2);
1328 setbits32(&ch[0].ao.shu[0].wodt, 0x1 << 29);
1329 setbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 7);
1330 setbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 7);
1331 clrsetbits32(&ch[0].ao.shu[0].rankctl, 0xf << 20, 0x4 << 20);
Huayang Duan73780152019-08-19 14:06:31 +08001332
1333 for (size_t r = 0; r < 2; r++) {
Julius Werner55009af2019-12-02 22:03:27 -08001334 clrsetbits32(&ch[0].ao.shu[0].rk[r].selph_dq[0],
Huayang Duan73780152019-08-19 14:06:31 +08001335 (0x7 << 0) | (0x7 << 4), (0x2 << 0) | (0x2 << 4));
Julius Werner55009af2019-12-02 22:03:27 -08001336 clrsetbits32(&ch[0].ao.shu[0].rk[r].selph_dq[1],
Huayang Duan73780152019-08-19 14:06:31 +08001337 (0x7 << 0) | (0x7 << 4), (0x2 << 0) | (0x2 << 4));
1338 }
1339 udelay(5);
1340
Julius Werner55009af2019-12-02 22:03:27 -08001341 clrsetbits32(&ch[0].ao.stbcal1, 0xffff << 16, 0x3 << 16);
1342 clrsetbits32(&ch[0].ao.stbcal1, 0xffff << 16, 0x1 << 16);
1343 clrsetbits32(&ch[0].ao.stbcal,
Huayang Duan73780152019-08-19 14:06:31 +08001344 (0x1 << 0) | (0x1 << 22) | (0x1 << 24) | (0x1 << 26) | (0x1 << 27),
1345 (0x1 << 0) | (0x0 << 22) | (0x0 << 24) | (0x1 << 26) | (0x1 << 27));
Julius Werner55009af2019-12-02 22:03:27 -08001346 setbits32(&ch[0].ao.stbcal1, 0x1 << 6);
1347 clrsetbits32(&ch[0].ao.shu[0].dqsg,
Huayang Duan73780152019-08-19 14:06:31 +08001348 (0x1 << 11) | (0xf << 12), (0x1 << 11) | (0x9 << 12));
Julius Werner55009af2019-12-02 22:03:27 -08001349 clrbits32(&ch[0].phy.misc_ctrl0, 0xf << 0);
1350 setbits32(&ch[0].ao.shu[0].stbcal, 0x1 << 8);
1351 setbits32(&ch[0].ao.stbcal, 0x1 << 17);
1352 clrbits32(&ch[0].phy.shu[0].b[0].dq[7], 0x1 << 14);
1353 clrbits32(&ch[0].phy.shu[0].b[1].dq[7], 0x1 << 14);
1354 clrsetbits32(&ch[0].ao.shu[0].stbcal, 0x7 << 4, 0x1 << 4);
Huayang Duan73780152019-08-19 14:06:31 +08001355
1356 if (freq_group == LP4X_DDR1600)
Julius Werner55009af2019-12-02 22:03:27 -08001357 clrsetbits32(&ch[0].ao.shu[0].stbcal, 0x3 << 0, 0x0 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001358 else
Julius Werner55009af2019-12-02 22:03:27 -08001359 clrsetbits32(&ch[0].ao.shu[0].stbcal, 0x3 << 0, 0x2 << 0);
1360 setbits32(&ch[0].ao.refctrl1, (0x1 << 0) | (0x1 << 5));
1361 setbits32(&ch[0].ao.dqsoscr, (0x1 << 23) | (0x1 << 27));
1362 clrbits32(&ch[0].ao.rstmask, (0x1 << 24) | (0x1 << 25) | (0x1 << 26));
1363 clrsetbits32(&ch[0].ao.rkcfg, 0x7 << 4, 0x1 << 4);
Huayang Duan73780152019-08-19 14:06:31 +08001364 udelay(12);
1365
Julius Werner55009af2019-12-02 22:03:27 -08001366 clrsetbits32(&ch[0].ao.shu[0].rankctl,
Huayang Duan73780152019-08-19 14:06:31 +08001367 (0xf << 24) | (0xf << 28), (0x4 << 24) | 0x6 << 28);
Julius Werner55009af2019-12-02 22:03:27 -08001368 clrbits32(&ch[0].ao.shu[0].wodt, 0x1 << 31);
1369 clrsetbits32(&ch[0].ao.shu[0].rk[0].fine_tune,
Huayang Duan73780152019-08-19 14:06:31 +08001370 (0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
1371 (0x1a << 0) | (0x1a << 8) | (0x1a << 16) | (0x1a << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001372 clrsetbits32(&ch[0].ao.shu[0].rk[1].fine_tune,
Huayang Duan73780152019-08-19 14:06:31 +08001373 (0x3f << 0) | (0x3f << 8) | (0x3f << 16) | (0x3f << 24),
1374 (0x14 << 0) | (0x14 << 8) | (0x14 << 16) | (0x14 << 24));
1375 for (u8 rank = 0; rank < 2; rank++) {
Julius Werner55009af2019-12-02 22:03:27 -08001376 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[2],
Huayang Duan73780152019-08-19 14:06:31 +08001377 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
1378 (0x4 << 16) | (0x4 << 20) | (0x4 << 24) | (0x4 << 28));
Julius Werner55009af2019-12-02 22:03:27 -08001379 clrsetbits32(&ch[0].ao.shu[0].rk[rank].selph_dq[3],
Huayang Duan73780152019-08-19 14:06:31 +08001380 (0x7 << 16) | (0x7 << 20) | (0x7 << 24) | (0x7 << 28),
1381 (0x4 << 16) | (0x4 << 20) | (0x4 << 24) | (0x4 << 28));
1382 }
Julius Werner55009af2019-12-02 22:03:27 -08001383 clrsetbits32(&ch[0].ao.shu[0].dqsg_retry,
Huayang Duan73780152019-08-19 14:06:31 +08001384 (0x1 << 2) | (0xf << 8) | (0x1 << 14) | (0x3 << 24),
1385 (0x1 << 2) | (0x5 << 8) | (0x0 << 14) | (0x1 << 24));
Julius Werner55009af2019-12-02 22:03:27 -08001386 setbits32(&ch[0].phy.shu[0].b[0].dq[7], (0x1 << 12) | (0x1 << 13));
1387 setbits32(&ch[0].phy.shu[0].b[1].dq[7], (0x1 << 12) | (0x1 << 13));
1388 clrbits32(&ch[0].ao.shu[0].dqs2dq_tx, 0x1f << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001389
Huayang Duan06264662020-04-20 19:33:28 +08001390 /* The default dramc init settings were tuned at frequency of 3200Mbps.
1391 For other frequencies uses dramc_setting_DDRxxx() to overwrite
1392 the default settings. */
Huayang Duan73780152019-08-19 14:06:31 +08001393 switch (freq_group) {
1394 case LP4X_DDR1600:
1395 dramc_setting_DDR1600();
1396 break;
1397 case LP4X_DDR2400:
1398 dramc_setting_DDR2400();
1399 break;
1400 case LP4X_DDR3200:
1401 /* Do nothing */
1402 break;
1403 case LP4X_DDR3600:
1404 dramc_setting_DDR3600();
1405 break;
1406 default:
1407 die("Invalid DDR frequency group %u\n", freq_group);
1408 return;
Huayang Duan73780152019-08-19 14:06:31 +08001409 }
1410
1411 update_initial_settings(freq_group);
Yu-Ping Wu4d4ccce2019-10-03 08:49:23 +08001412 dramc_sw_impedance_save_reg(freq_group, impedance);
Huayang Duan73780152019-08-19 14:06:31 +08001413
Julius Werner55009af2019-12-02 22:03:27 -08001414 clrbits32(&ch[0].ao.test2_4, 0x1 << 17);
1415 clrsetbits32(&ch[0].ao.shu[0].conf[3], 0x1ff << 0, 0x5 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001416 udelay(1);
1417
Julius Werner55009af2019-12-02 22:03:27 -08001418 setbits32(&ch[0].ao.refctrl0, (0x1 << 17) | (0x1 << 18));
1419 setbits32(&ch[0].ao.shuctrl2, (0x1 << 24) | (0x1 << 25));
1420 setbits32(&ch[0].ao.refctrl0, 0x1 << 29);
1421 setbits32(&ch[0].ao.dramctrl, 0x1 << 26);
1422 clrsetbits32(&ch[0].ao.dummy_rd,
Huayang Duan73780152019-08-19 14:06:31 +08001423 (0x1 << 4) | (0x1 << 11) | (0x1 << 13) |
1424 (0x1 << 14) | (0x3 << 16) | (0x1 << 22),
1425 (0x1 << 4) | (0x1 << 11) | (0x1 << 13) |
1426 (0x1 << 14) | (0x2 << 16) | (0x1 << 22));
Julius Werner55009af2019-12-02 22:03:27 -08001427 clrsetbits32(&ch[0].ao.test2_4, 0x7 << 28, 0x4 << 28);
1428 clrbits32(&ch[0].ao.dramctrl, 0x1 << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001429 udelay(1);
1430
1431 dramc_set_broadcast(DRAMC_BROADCAST_OFF);
Julius Werner55009af2019-12-02 22:03:27 -08001432 clrsetbits32(&ch[0].ao.shuctrl, (0x1 << 5) | (0x1 << 17), (0x0 << 5) | (0x1 << 17));
1433 setbits32(&ch[0].ao.shuctrl2, 0x1 << 12);
1434 clrsetbits32(&ch[1].ao.shuctrl, (0x1 << 5) | (0x1 << 17), (0x1 << 5) | (0x0 << 17));
1435 clrbits32(&ch[1].ao.shuctrl2, 0x1 << 12);
Huayang Duan73780152019-08-19 14:06:31 +08001436}
1437
1438struct ac_time {
1439 u8 dqsinctl;
1440 u8 datlat;
1441 u8 trcd;
1442 u8 trrd;
1443 u8 twr;
1444 u8 twtr;
1445 u8 trc;
1446 u8 tras;
1447 u8 trp;
1448 u8 trpab;
1449 u8 tfaw;
1450 u8 trtw_odt_on;
1451 u8 trtp;
1452 u8 txp;
1453 u8 refcnt;
1454 u8 trfc;
1455 u8 trfcpb;
1456 u8 tzqcs;
1457 u8 refcnt_fr_clk;
1458 u8 txrefcnt;
1459 u8 tmrr2w_odt_on;
1460 u8 twtpd;
1461 u8 trtpd;
1462 u8 xrtw2w;
1463 u8 xrtw2r;
1464 u8 xrtr2w;
1465 u8 xrtr2r;
1466 u8 twtr_05T;
1467 u8 trtw_odt_on_05T;
1468 u8 twtpd_05T;
1469 u8 trtpd_05T;
1470 u8 tfaw_05T;
1471 u8 trrd_05T;
1472 u8 twr_05T;
1473 u8 tras_05T;
1474 u8 trpab_05T;
1475 u8 trp_05T;
1476 u8 trcd_05T;
1477 u8 trtp_05T;
1478 u8 txp_05T;
1479 u8 trfc_05T;
1480 u8 trfcpb_05T;
1481 u8 trc_05T;
1482 u8 r_dmcatrain_intv;
1483 u8 r_dmmrw_intv;
1484 u8 r_dmfspchg_prdcnt;
1485 u8 ckeprd;
1486 u8 ckelckcnt;
1487 u8 zqlat2;
1488};
1489
1490static const struct ac_time ac_timing_tbl[LP4X_DDRFREQ_MAX] = {
1491 /* LP4x-1600, 800MHz, RDBI_OFF, normal mode */
1492 [LP4X_DDR1600] = {
1493 .tras = 0, .tras_05T = 0,
1494 .trp = 2, .trp_05T = 0,
1495 .trpab = 0, .trpab_05T = 1,
1496 .trc = 4, .trc_05T = 0,
1497 .trfc = 44, .trfc_05T = 0,
1498 .trfcpb = 16, .trfcpb_05T = 0,
1499 .txp = 0, .txp_05T = 0,
1500 .trtp = 1, .trtp_05T = 1,
1501 .trcd = 3, .trcd_05T = 0,
1502 .twr = 7, .twr_05T = 1,
1503 .twtr = 4, .twtr_05T = 1,
1504 .trrd = 0, .trrd_05T = 0,
1505 .tfaw = 0, .tfaw_05T = 0,
1506 .trtw_odt_on = 4, .trtw_odt_on_05T = 0,
1507 .refcnt = 48,
1508 .refcnt_fr_clk = 101,
1509 .txrefcnt = 62,
1510 .tzqcs = 16,
1511 .xrtw2w = 5,
1512 .xrtw2r = 3,
1513 .xrtr2w = 3,
1514 .xrtr2r = 8,
1515 .r_dmcatrain_intv = 8,
1516 .r_dmmrw_intv = 0xf,
1517 .r_dmfspchg_prdcnt = 50,
1518 .trtpd = 6, .trtpd_05T = 0,
1519 .twtpd = 6, .twtpd_05T = 0,
1520 .tmrr2w_odt_on = 5,
1521 .ckeprd = 1,
1522 .ckelckcnt = 0,
1523 .zqlat2 = 6,
1524 .dqsinctl = 1, .datlat = 10,
1525 },
1526 /* LP4x-2400, 1200MHz, RDBI_OFF, normal mode */
1527 [LP4X_DDR2400] = {
1528 .tras = 4, .tras_05T = 1,
1529 .trp = 3, .trp_05T = 1,
1530 .trpab = 1, .trpab_05T = 0,
1531 .trc = 10, .trc_05T = 0,
1532 .trfc = 72, .trfc_05T = 0,
1533 .trfcpb = 30, .trfcpb_05T = 0,
1534 .txp = 0, .txp_05T = 1,
1535 .trtp = 1, .trtp_05T = 0,
1536 .trcd = 4, .trcd_05T = 1,
1537 .twr = 10, .twr_05T = 1,
1538 .twtr = 6, .twtr_05T = 1,
1539 .trrd = 1, .trrd_05T = 0,
1540 .tfaw = 3, .tfaw_05T = 0,
1541 .trtw_odt_on = 7, .trtw_odt_on_05T = 0,
1542 .refcnt = 73,
1543 .refcnt_fr_clk = 101,
1544 .txrefcnt = 91,
1545 .tzqcs = 25,
1546 .xrtw2w = 5,
1547 .xrtw2r = 3,
1548 .xrtr2w = 6,
1549 .xrtr2r = 8,
1550 .r_dmcatrain_intv = 9,
1551 .r_dmmrw_intv = 0xf,
1552 .r_dmfspchg_prdcnt = 75,
1553 .trtpd = 9, .trtpd_05T = 0,
1554 .twtpd = 9, .twtpd_05T = 0,
1555 .tmrr2w_odt_on = 8,
1556 .ckeprd = 2,
1557 .ckelckcnt = 0,
1558 .zqlat2 = 9,
1559 .dqsinctl = 3, .datlat = 13,
1560 },
1561 /* LP4x-3200, 1600MHz, RDBI_OFF, normal mode */
1562 [LP4X_DDR3200] = {
1563 .tras = 8, .tras_05T = 1,
1564 .trp = 5, .trp_05T = 1,
1565 .trpab = 1, .trpab_05T = 0,
1566 .trc = 16, .trc_05T = 1,
1567 .trfc = 100, .trfc_05T = 0,
1568 .trfcpb = 44, .trfcpb_05T = 0,
1569 .txp = 1, .txp_05T = 0,
1570 .trtp = 2, .trtp_05T = 1,
1571 .trcd = 6, .trcd_05T = 1,
1572 .twr = 12, .twr_05T = 1,
1573 .twtr = 7, .twtr_05T = 0,
1574 .trrd = 2, .trrd_05T = 0,
1575 .tfaw = 7, .tfaw_05T = 0,
1576 .trtw_odt_on = 7, .trtw_odt_on_05T = 0,
1577 .refcnt = 97,
1578 .refcnt_fr_clk = 101,
1579 .txrefcnt = 119,
1580 .tzqcs = 34,
1581 .xrtw2w = 5,
1582 .xrtw2r = 3,
1583 .xrtr2w = 6,
1584 .xrtr2r = 9,
1585 .r_dmcatrain_intv = 11,
1586 .r_dmmrw_intv = 0xf,
1587 .r_dmfspchg_prdcnt = 100,
1588 .trtpd = 11, .trtpd_05T = 0,
1589 .twtpd = 12, .twtpd_05T = 1,
1590 .tmrr2w_odt_on = 10,
1591 .ckeprd = 2,
1592 .ckelckcnt = 0,
1593 .zqlat2 = 12,
1594 .dqsinctl = 4, .datlat = 15,
1595 },
1596 /* LP4x-3600, 1800MHz, RDBI_OFF, normal mode */
1597 [LP4X_DDR3600] = {
1598 .tras = 11, .tras_05T = 1,
1599 .trp = 6, .trp_05T = 1,
1600 .trpab = 1, .trpab_05T = 1,
1601 .trc = 20, .trc_05T = 1,
1602 .trfc = 118, .trfc_05T = 1,
1603 .trfcpb = 53, .trfcpb_05T = 1,
1604 .txp = 1, .txp_05T = 1,
1605 .trtp = 2, .trtp_05T = 0,
1606 .trcd = 7, .trcd_05T = 1,
1607 .twr = 14, .twr_05T = 1,
1608 .twtr = 8, .twtr_05T = 0,
1609 .trrd = 3, .trrd_05T = 0,
1610 .tfaw = 10, .tfaw_05T = 0,
1611 .trtw_odt_on = 8, .trtw_odt_on_05T = 0,
1612 .refcnt = 113,
1613 .refcnt_fr_clk = 101,
1614 .txrefcnt = 138,
1615 .tzqcs = 40,
1616 .xrtw2w = 5,
1617 .xrtw2r = 3,
1618 .xrtr2w = 7,
1619 .xrtr2r = 9,
1620 .r_dmcatrain_intv = 13,
1621 .r_dmmrw_intv = 0xf,
1622 .r_dmfspchg_prdcnt = 117,
1623 .trtpd = 12, .trtpd_05T = 0,
1624 .twtpd = 13, .twtpd_05T = 0,
1625 .tmrr2w_odt_on = 11,
1626 .ckeprd = 3,
1627 .ckelckcnt = 0,
1628 .zqlat2 = 14,
1629 .dqsinctl = 6, .datlat = 18,
1630 },
1631};
1632
1633static void ddr_update_ac_timing(u8 freq_group)
1634{
1635 struct ac_time ac_t;
1636 u32 temp, r2w_odt_onoff = ODT_ON;
1637 u8 new_datlat;
1638 u8 root = 0, tx_rank_inctl = 0, tx_dly = 0;
1639 u8 trtw = 0, trtw_05t = 0, tmrr2w = 0;
1640
1641 memcpy(&ac_t, &ac_timing_tbl[freq_group], sizeof(struct ac_time));
1642 new_datlat = ac_timing_tbl[freq_group].datlat - 2;
1643
1644 if (freq_group == LP4X_DDR1600) {
1645 root = 0; tx_rank_inctl = 0; tx_dly = 1;
1646 } else {
1647 root = (freq_group == LP4X_DDR3600) ? 1 : 0;
1648 tx_rank_inctl = 1; tx_dly = 2;
1649 }
1650
1651 if (r2w_odt_onoff == ODT_ON) {
1652 trtw = ac_t.trtw_odt_on;
1653 trtw_05t = ac_t.trtw_odt_on_05T;
1654 tmrr2w = ac_t.tmrr2w_odt_on;
1655 }
1656
1657 for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
Julius Werner55009af2019-12-02 22:03:27 -08001658 clrsetbits32(&ch[chn].ao.shu[0].actim[0],
Huayang Duan73780152019-08-19 14:06:31 +08001659 (0xf << 24) | (0x7 << 16) | (0x1f << 8) | (0xf << 0),
1660 (ac_t.trcd << 24) | (ac_t.trrd << 16) |
1661 (ac_t.twr << 8) | (ac_t.twtr << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001662 clrsetbits32(&ch[chn].ao.shu[0].actim[1],
Huayang Duan73780152019-08-19 14:06:31 +08001663 (0x1f << 24) | (0xf << 16) | (0xf << 8) | (0x7 << 0),
1664 (ac_t.trc << 24) | (ac_t.tras << 16) |
1665 (ac_t.trp << 8) | (ac_t.trpab << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001666 clrsetbits32(&ch[chn].ao.shu[0].actim[2],
Huayang Duan73780152019-08-19 14:06:31 +08001667 (0x1f << 24) | (0xf << 16) | (0x7 << 8) | (0x7 << 0),
1668 (ac_t.tfaw << 24) | (trtw << 16) |
1669 (ac_t.trtp << 8) | (ac_t.txp << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001670 clrsetbits32(&ch[chn].ao.shu[0].actim[3],
Huayang Duan73780152019-08-19 14:06:31 +08001671 (0xff << 16) | (0xff << 24) | (0xff << 0),
1672 (ac_t.trfc << 16) | (ac_t.refcnt << 24) | (ac_t.trfcpb << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001673 clrsetbits32(&ch[chn].ao.shu[0].actim[4],
Huayang Duan73780152019-08-19 14:06:31 +08001674 (0xff << 24) | (0xff << 16) | (0x3ff << 0),
1675 (ac_t.tzqcs << 24) | (ac_t.refcnt_fr_clk << 16) |
1676 (ac_t.txrefcnt << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001677 clrsetbits32(&ch[chn].ao.shu[0].actim[5],
Huayang Duan73780152019-08-19 14:06:31 +08001678 (0xf << 24) | (0x1f << 8) | (0x1f << 0),
1679 (tmrr2w << 24) | (ac_t.twtpd << 8) | (ac_t.trtpd << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001680 clrsetbits32(&ch[chn].ao.shu[0].actim_xrt,
Huayang Duan73780152019-08-19 14:06:31 +08001681 (0xf << 24) | (0x7 << 16) | (0xf << 8) | (0x1f << 0),
1682 (ac_t.xrtw2w << 24) | (ac_t.xrtw2r << 16) |
1683 (ac_t.xrtr2w << 8) | (ac_t.xrtr2r << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001684 clrsetbits32(&ch[chn].ao.shu[0].ac_time_05t,
Huayang Duan73780152019-08-19 14:06:31 +08001685 (0x1 << 25) | (0x0 << 24) | (0x1 << 16) | (0x0 << 15) |
1686 (0x1 << 13) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) |
1687 (0x1 << 8) | (0x1 << 7) | (0x1 << 6) | (0x1 << 5) |
1688 (0x1 << 4) | (0x1 << 2) | (0x1 << 1) | (0x1 << 0),
1689 (ac_t.twtr_05T << 25) | (trtw_05t << 24) |
1690 (ac_t.twtpd_05T << 16) | (ac_t.trtpd_05T << 15) |
1691 (ac_t.tfaw_05T << 13) | (ac_t.trrd_05T << 12) |
1692 (ac_t.twr_05T << 10) | (ac_t.tras_05T << 9) |
1693 (ac_t.trpab_05T << 8) | (ac_t.trp_05T << 7) |
1694 (ac_t.trcd_05T << 6) | (ac_t.trtp_05T << 5) |
1695 (ac_t.txp_05T << 4) | (ac_t.trfc_05T << 2) |
1696 (ac_t.trfcpb_05T << 1) | (ac_t.trc_05T << 0));
Julius Werner55009af2019-12-02 22:03:27 -08001697 clrsetbits32(&ch[chn].ao.catraining1, (0xff << 24) | (0xf << 20),
Huayang Duan73780152019-08-19 14:06:31 +08001698 (ac_t.r_dmcatrain_intv << 24) | (0x0 << 20));
1699
1700 /* DQSINCTL related */
Julius Werner55009af2019-12-02 22:03:27 -08001701 clrsetbits32(&ch[chn].ao.shu[0].rk[0].dqsctl, 0xf << 0,
Huayang Duan73780152019-08-19 14:06:31 +08001702 ac_t.dqsinctl << 0);
Julius Werner55009af2019-12-02 22:03:27 -08001703 clrsetbits32(&ch[chn].ao.shu[0].rk[1].dqsctl, 0xf << 0,
Huayang Duan73780152019-08-19 14:06:31 +08001704 ac_t.dqsinctl << 0);
Julius Werner55009af2019-12-02 22:03:27 -08001705 clrsetbits32(&ch[chn].ao.shu[0].odtctrl, 0xf << 4,
Huayang Duan73780152019-08-19 14:06:31 +08001706 ac_t.dqsinctl << 4);
1707
1708 /* DATLAT related, tREFBW */
Julius Werner55009af2019-12-02 22:03:27 -08001709 clrsetbits32(&ch[chn].ao.shu[0].conf[1],
Huayang Duan73780152019-08-19 14:06:31 +08001710 (0x1f << 0) | (0x1f << 8) | (0x1f << 26) | (0x3ff << 16),
1711 (ac_t.datlat << 0) | (new_datlat << 8) |
1712 (new_datlat << 26) | (0x0 << 16));
Julius Werner55009af2019-12-02 22:03:27 -08001713 clrsetbits32(&ch[chn].ao.shu[0].conf[2],
Huayang Duan73780152019-08-19 14:06:31 +08001714 (0xff << 8), ac_t.r_dmfspchg_prdcnt << 8);
Julius Werner55009af2019-12-02 22:03:27 -08001715 clrsetbits32(&ch[chn].ao.shu[0].scintv, (0x1f << 13) | (0x1f << 6),
Huayang Duan73780152019-08-19 14:06:31 +08001716 (ac_t.r_dmmrw_intv << 13) | (ac_t.zqlat2 << 6));
1717
1718 /* CKEPRD - CKE pulse width */
Julius Werner55009af2019-12-02 22:03:27 -08001719 clrsetbits32(&ch[chn].ao.shu[0].ckectrl, 0x7 << 20, ac_t.ckeprd << 20);
Huayang Duan73780152019-08-19 14:06:31 +08001720
1721 /* CKELCKCNT: Valid clock requirement after CKE input low */
Julius Werner55009af2019-12-02 22:03:27 -08001722 clrsetbits32(&ch[chn].ao.ckectrl, 0x7 << 24, ac_t.ckelckcnt << 24);
Huayang Duan73780152019-08-19 14:06:31 +08001723
1724 temp = ((read32(&ch[chn].ao.shu[0].rankctl) & 0x00f00000) >> 20) & 0xf;
Julius Werner55009af2019-12-02 22:03:27 -08001725 clrsetbits32(&ch[chn].ao.shu[0].rankctl, 0xf << 0, temp << 0);
Huayang Duan73780152019-08-19 14:06:31 +08001726
Julius Werner55009af2019-12-02 22:03:27 -08001727 clrsetbits32(&ch[chn].ao.shu[0].rankctl,
Huayang Duan73780152019-08-19 14:06:31 +08001728 (0xf << 16) | (0xf << 12) | (0xf << 8),
1729 (root << 16) | (tx_rank_inctl << 12) | (tx_dly << 8));
1730 }
1731
1732 u8 dram_cbt_mode = 0;
Julius Werner55009af2019-12-02 22:03:27 -08001733 clrsetbits32(&ch[0].ao.arbctl, 0x7 << 10, 0x3 << 10);
1734 clrsetbits32(&ch[0].ao.rstmask, 0x3 << 13, dram_cbt_mode);
1735 clrsetbits32(&ch[0].ao.arbctl, 0x1 << 13, dram_cbt_mode);
Huayang Duan73780152019-08-19 14:06:31 +08001736}
1737
Yu-Ping Wu4d4ccce2019-10-03 08:49:23 +08001738void dramc_init(const struct sdram_params *params, u8 freq_group,
Yu-Ping Wu947916e2019-10-24 15:51:19 +08001739 struct dram_shared_data *shared)
Huayang Duan73780152019-08-19 14:06:31 +08001740{
Yu-Ping Wu947916e2019-10-24 15:51:19 +08001741 dramc_setting(params, freq_group, &shared->impedance);
Huayang Duan73780152019-08-19 14:06:31 +08001742
1743 dramc_duty_calibration(params, freq_group);
Huayang Duancea735c2019-09-24 14:07:11 +08001744 dvfs_settings(freq_group);
Huayang Duan73780152019-08-19 14:06:31 +08001745
Yu-Ping Wu947916e2019-10-24 15:51:19 +08001746 dramc_mode_reg_init(freq_group, &shared->mr);
Huayang Duan73780152019-08-19 14:06:31 +08001747 ddr_update_ac_timing(freq_group);
Huayang Duane19d61b2018-09-26 14:51:51 +08001748}