blob: c9f198af9bc5b9372b2d9a91f60d11fbaf5a4fb8 [file] [log] [blame]
Kever Yangc43acfd2018-12-20 11:33:42 +08001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
Kever Yangfa437432017-02-22 16:56:35 +08002/*
3 * (C) Copyright 2016-2017 Rockchip Inc.
4 *
Kever Yangfa437432017-02-22 16:56:35 +08005 * Adapted from coreboot.
6 */
Philipp Tomsichfbecb942017-05-31 18:16:34 +02007
Kever Yangfa437432017-02-22 16:56:35 +08008#include <common.h>
9#include <clk.h>
10#include <dm.h>
11#include <dt-structs.h>
12#include <ram.h>
13#include <regmap.h>
14#include <syscon.h>
15#include <asm/io.h>
Kever Yang15f09a12019-03-28 11:01:23 +080016#include <asm/arch-rockchip/clock.h>
Kever Yang15f09a12019-03-28 11:01:23 +080017#include <asm/arch-rockchip/cru_rk3399.h>
18#include <asm/arch-rockchip/grf_rk3399.h>
Jagan Tekic36abd02019-07-16 17:27:40 +053019#include <asm/arch-rockchip/pmu_rk3399.h>
Kever Yang15f09a12019-03-28 11:01:23 +080020#include <asm/arch-rockchip/hardware.h>
Kever Yang5d19ddf2019-11-15 11:04:33 +080021#include <asm/arch-rockchip/sdram.h>
Jagan Teki3eaf5392019-07-15 23:50:57 +053022#include <asm/arch-rockchip/sdram_rk3399.h>
Kever Yangfa437432017-02-22 16:56:35 +080023#include <linux/err.h>
Philipp Tomsichfbecb942017-05-31 18:16:34 +020024#include <time.h>
Kever Yangfa437432017-02-22 16:56:35 +080025
Jagan Teki3eaf5392019-07-15 23:50:57 +053026#define PRESET_SGRF_HOLD(n) ((0x1 << (6 + 16)) | ((n) << 6))
27#define PRESET_GPIO0_HOLD(n) ((0x1 << (7 + 16)) | ((n) << 7))
28#define PRESET_GPIO1_HOLD(n) ((0x1 << (8 + 16)) | ((n) << 8))
29
30#define PHY_DRV_ODT_HI_Z 0x0
31#define PHY_DRV_ODT_240 0x1
32#define PHY_DRV_ODT_120 0x8
33#define PHY_DRV_ODT_80 0x9
34#define PHY_DRV_ODT_60 0xc
35#define PHY_DRV_ODT_48 0xd
36#define PHY_DRV_ODT_40 0xe
37#define PHY_DRV_ODT_34_3 0xf
38
Jagan Teki881860f2019-07-16 17:27:15 +053039#define PHY_BOOSTP_EN 0x1
40#define PHY_BOOSTN_EN 0x1
Jagan Tekif9f32d62019-07-16 17:27:16 +053041#define PHY_SLEWP_EN 0x1
42#define PHY_SLEWN_EN 0x1
Jagan Tekid3d00992019-07-16 17:27:17 +053043#define PHY_RX_CM_INPUT 0x1
Jagan Tekif288d542019-07-16 17:27:24 +053044#define CS0_MR22_VAL 0
45#define CS1_MR22_VAL 3
Jagan Teki881860f2019-07-16 17:27:15 +053046
Jagan Teki33921032019-07-15 23:58:43 +053047#define CRU_SFTRST_DDR_CTRL(ch, n) ((0x1 << (8 + 16 + (ch) * 4)) | \
48 ((n) << (8 + (ch) * 4)))
49#define CRU_SFTRST_DDR_PHY(ch, n) ((0x1 << (9 + 16 + (ch) * 4)) | \
50 ((n) << (9 + (ch) * 4)))
Kever Yangfa437432017-02-22 16:56:35 +080051struct chan_info {
52 struct rk3399_ddr_pctl_regs *pctl;
53 struct rk3399_ddr_pi_regs *pi;
54 struct rk3399_ddr_publ_regs *publ;
YouMin Chena922d0d2019-11-15 11:04:45 +080055 struct msch_regs *msch;
Kever Yangfa437432017-02-22 16:56:35 +080056};
57
58struct dram_info {
Kever Yang82763342019-04-01 17:20:53 +080059#if defined(CONFIG_TPL_BUILD) || \
60 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Jagan Tekia0aebe82019-07-15 23:58:45 +053061 u32 pwrup_srefresh_exit[2];
Kever Yangfa437432017-02-22 16:56:35 +080062 struct chan_info chan[2];
63 struct clk ddr_clk;
64 struct rk3399_cru *cru;
Jagan Tekia0aebe82019-07-15 23:58:45 +053065 struct rk3399_grf_regs *grf;
Jagan Tekic36abd02019-07-16 17:27:40 +053066 struct rk3399_pmu_regs *pmu;
Kever Yangfa437432017-02-22 16:56:35 +080067 struct rk3399_pmucru *pmucru;
68 struct rk3399_pmusgrf_regs *pmusgrf;
69 struct rk3399_ddr_cic_regs *cic;
Jagan Teki299deec2019-07-16 17:27:30 +053070 const struct sdram_rk3399_ops *ops;
Kever Yangfa437432017-02-22 16:56:35 +080071#endif
72 struct ram_info info;
73 struct rk3399_pmugrf_regs *pmugrf;
74};
75
Jagan Teki299deec2019-07-16 17:27:30 +053076struct sdram_rk3399_ops {
YouMin Chenf8088bf2019-11-15 11:04:46 +080077 int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
78 struct rk3399_sdram_params *sdram);
79 int (*set_rate_index)(struct dram_info *dram,
80 struct rk3399_sdram_params *params);
YouMin Chen0cacc272019-11-15 11:04:48 +080081 void (*modify_param)(const struct chan_info *chan,
82 struct rk3399_sdram_params *params);
83 struct rk3399_sdram_params *
84 (*get_phy_index_params)(u32 phy_fn,
85 struct rk3399_sdram_params *params);
Jagan Teki299deec2019-07-16 17:27:30 +053086};
87
Kever Yang82763342019-04-01 17:20:53 +080088#if defined(CONFIG_TPL_BUILD) || \
89 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yangfa437432017-02-22 16:56:35 +080090
91struct rockchip_dmc_plat {
92#if CONFIG_IS_ENABLED(OF_PLATDATA)
93 struct dtd_rockchip_rk3399_dmc dtplat;
94#else
95 struct rk3399_sdram_params sdram_params;
96#endif
97 struct regmap *map;
98};
99
Jagan Teki74109de2019-07-16 17:27:21 +0530100struct io_setting {
101 u32 mhz;
102 u32 mr5;
103 /* dram side */
104 u32 dq_odt;
105 u32 ca_odt;
106 u32 pdds;
107 u32 dq_vref;
108 u32 ca_vref;
109 /* phy side */
110 u32 rd_odt;
111 u32 wr_dq_drv;
112 u32 wr_ca_drv;
113 u32 wr_ckcs_drv;
114 u32 rd_odt_en;
115 u32 rd_vref;
116} lpddr4_io_setting[] = {
117 {
118 50 * MHz,
119 0,
120 /* dram side */
121 0, /* dq_odt; */
122 0, /* ca_odt; */
123 6, /* pdds; */
124 0x72, /* dq_vref; */
125 0x72, /* ca_vref; */
126 /* phy side */
127 PHY_DRV_ODT_HI_Z, /* rd_odt; */
128 PHY_DRV_ODT_40, /* wr_dq_drv; */
129 PHY_DRV_ODT_40, /* wr_ca_drv; */
130 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
131 0, /* rd_odt_en;*/
132 41, /* rd_vref; (unit %, range 3.3% - 48.7%) */
133 },
134 {
135 600 * MHz,
136 0,
137 /* dram side */
138 1, /* dq_odt; */
139 0, /* ca_odt; */
140 6, /* pdds; */
141 0x72, /* dq_vref; */
142 0x72, /* ca_vref; */
143 /* phy side */
144 PHY_DRV_ODT_HI_Z, /* rd_odt; */
145 PHY_DRV_ODT_48, /* wr_dq_drv; */
146 PHY_DRV_ODT_40, /* wr_ca_drv; */
147 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
148 0, /* rd_odt_en; */
149 32, /* rd_vref; (unit %, range 3.3% - 48.7%) */
150 },
151 {
152 800 * MHz,
153 0,
154 /* dram side */
155 1, /* dq_odt; */
156 0, /* ca_odt; */
157 1, /* pdds; */
158 0x72, /* dq_vref; */
159 0x72, /* ca_vref; */
160 /* phy side */
161 PHY_DRV_ODT_40, /* rd_odt; */
162 PHY_DRV_ODT_48, /* wr_dq_drv; */
163 PHY_DRV_ODT_40, /* wr_ca_drv; */
164 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
165 1, /* rd_odt_en; */
166 17, /* rd_vref; (unit %, range 3.3% - 48.7%) */
167 },
168 {
169 933 * MHz,
170 0,
171 /* dram side */
172 3, /* dq_odt; */
173 0, /* ca_odt; */
174 6, /* pdds; */
175 0x59, /* dq_vref; 32% */
176 0x72, /* ca_vref; */
177 /* phy side */
178 PHY_DRV_ODT_HI_Z, /* rd_odt; */
179 PHY_DRV_ODT_48, /* wr_dq_drv; */
180 PHY_DRV_ODT_40, /* wr_ca_drv; */
181 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
182 0, /* rd_odt_en; */
183 32, /* rd_vref; (unit %, range 3.3% - 48.7%) */
184 },
185 {
186 1066 * MHz,
187 0,
188 /* dram side */
189 6, /* dq_odt; */
190 0, /* ca_odt; */
191 1, /* pdds; */
192 0x10, /* dq_vref; */
193 0x72, /* ca_vref; */
194 /* phy side */
195 PHY_DRV_ODT_40, /* rd_odt; */
196 PHY_DRV_ODT_60, /* wr_dq_drv; */
197 PHY_DRV_ODT_40, /* wr_ca_drv; */
198 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
199 1, /* rd_odt_en; */
200 17, /* rd_vref; (unit %, range 3.3% - 48.7%) */
201 },
202};
203
Jagan Teki2fb2de32019-07-16 17:27:22 +0530204static struct io_setting *
205lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
206{
207 struct io_setting *io = NULL;
208 u32 n;
209
210 for (n = 0; n < ARRAY_SIZE(lpddr4_io_setting); n++) {
211 io = &lpddr4_io_setting[n];
212
213 if (io->mr5 != 0) {
214 if (io->mhz >= params->base.ddr_freq &&
215 io->mr5 == mr5)
216 break;
217 } else {
218 if (io->mhz >= params->base.ddr_freq)
219 break;
220 }
221 }
222
223 return io;
224}
225
Jagan Tekic36abd02019-07-16 17:27:40 +0530226static void *get_denali_ctl(const struct chan_info *chan,
227 struct rk3399_sdram_params *params, bool reg)
228{
229 return reg ? &chan->pctl->denali_ctl : &params->pctl_regs.denali_ctl;
230}
231
YouMin Chena922d0d2019-11-15 11:04:45 +0800232static void *get_denali_phy(const struct chan_info *chan,
233 struct rk3399_sdram_params *params, bool reg)
234{
235 return reg ? &chan->publ->denali_phy : &params->phy_regs.denali_phy;
236}
237
Jagan Tekia0aebe82019-07-15 23:58:45 +0530238static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
239{
YouMin Chen410d7862019-11-15 11:04:47 +0800240 return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc1_con0;
Jagan Tekia0aebe82019-07-15 23:58:45 +0530241}
242
Jagan Teki33921032019-07-15 23:58:43 +0530243static void rkclk_ddr_reset(struct rk3399_cru *cru, u32 channel, u32 ctl,
244 u32 phy)
245{
246 channel &= 0x1;
247 ctl &= 0x1;
248 phy &= 0x1;
249 writel(CRU_SFTRST_DDR_CTRL(channel, ctl) |
250 CRU_SFTRST_DDR_PHY(channel, phy),
251 &cru->softrst_con[4]);
252}
253
254static void phy_pctrl_reset(struct rk3399_cru *cru, u32 channel)
255{
256 rkclk_ddr_reset(cru, channel, 1, 1);
257 udelay(10);
258
259 rkclk_ddr_reset(cru, channel, 1, 0);
260 udelay(10);
261
262 rkclk_ddr_reset(cru, channel, 0, 0);
263 udelay(10);
264}
265
Kever Yangfa437432017-02-22 16:56:35 +0800266static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs,
267 u32 freq)
268{
269 u32 *denali_phy = ddr_publ_regs->denali_phy;
270
271 /* From IP spec, only freq small than 125 can enter dll bypass mode */
272 if (freq <= 125) {
273 /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
274 setbits_le32(&denali_phy[86], (0x3 << 2) << 8);
275 setbits_le32(&denali_phy[214], (0x3 << 2) << 8);
276 setbits_le32(&denali_phy[342], (0x3 << 2) << 8);
277 setbits_le32(&denali_phy[470], (0x3 << 2) << 8);
278
279 /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
280 setbits_le32(&denali_phy[547], (0x3 << 2) << 16);
281 setbits_le32(&denali_phy[675], (0x3 << 2) << 16);
282 setbits_le32(&denali_phy[803], (0x3 << 2) << 16);
283 } else {
284 /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
285 clrbits_le32(&denali_phy[86], (0x3 << 2) << 8);
286 clrbits_le32(&denali_phy[214], (0x3 << 2) << 8);
287 clrbits_le32(&denali_phy[342], (0x3 << 2) << 8);
288 clrbits_le32(&denali_phy[470], (0x3 << 2) << 8);
289
290 /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
291 clrbits_le32(&denali_phy[547], (0x3 << 2) << 16);
292 clrbits_le32(&denali_phy[675], (0x3 << 2) << 16);
293 clrbits_le32(&denali_phy[803], (0x3 << 2) << 16);
294 }
295}
296
297static void set_memory_map(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +0530298 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +0800299{
Jagan Tekifde7f452019-07-15 23:50:58 +0530300 const struct rk3399_sdram_channel *sdram_ch = &params->ch[channel];
Kever Yangfa437432017-02-22 16:56:35 +0800301 u32 *denali_ctl = chan->pctl->denali_ctl;
302 u32 *denali_pi = chan->pi->denali_pi;
303 u32 cs_map;
304 u32 reduc;
305 u32 row;
306
307 /* Get row number from ddrconfig setting */
Jagan Teki355490d2019-07-15 23:51:05 +0530308 if (sdram_ch->cap_info.ddrconfig < 2 ||
309 sdram_ch->cap_info.ddrconfig == 4)
Kever Yangfa437432017-02-22 16:56:35 +0800310 row = 16;
Jagan Teki355490d2019-07-15 23:51:05 +0530311 else if (sdram_ch->cap_info.ddrconfig == 3)
Kever Yangfa437432017-02-22 16:56:35 +0800312 row = 14;
313 else
314 row = 15;
315
Jagan Teki355490d2019-07-15 23:51:05 +0530316 cs_map = (sdram_ch->cap_info.rank > 1) ? 3 : 1;
317 reduc = (sdram_ch->cap_info.bw == 2) ? 0 : 1;
Kever Yangfa437432017-02-22 16:56:35 +0800318
319 /* Set the dram configuration to ctrl */
Jagan Teki355490d2019-07-15 23:51:05 +0530320 clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->cap_info.col));
Kever Yangfa437432017-02-22 16:56:35 +0800321 clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
Jagan Teki355490d2019-07-15 23:51:05 +0530322 ((3 - sdram_ch->cap_info.bk) << 16) |
Kever Yangfa437432017-02-22 16:56:35 +0800323 ((16 - row) << 24));
324
325 clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16),
326 cs_map | (reduc << 16));
327
328 /* PI_199 PI_COL_DIFF:RW:0:4 */
Jagan Teki355490d2019-07-15 23:51:05 +0530329 clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->cap_info.col));
Kever Yangfa437432017-02-22 16:56:35 +0800330
331 /* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */
332 clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24),
Jagan Teki355490d2019-07-15 23:51:05 +0530333 ((3 - sdram_ch->cap_info.bk) << 16) |
Kever Yangfa437432017-02-22 16:56:35 +0800334 ((16 - row) << 24));
Jagan Teki4e9de9e2019-07-16 17:27:18 +0530335
YouMin Chenf8088bf2019-11-15 11:04:46 +0800336 if (params->base.dramtype == LPDDR4) {
Jagan Teki4e9de9e2019-07-16 17:27:18 +0530337 if (cs_map == 1)
338 cs_map = 0x5;
339 else if (cs_map == 2)
340 cs_map = 0xa;
341 else
342 cs_map = 0xF;
343 }
344
Kever Yangfa437432017-02-22 16:56:35 +0800345 /* PI_41 PI_CS_MAP:RW:24:4 */
346 clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24);
Jagan Teki355490d2019-07-15 23:51:05 +0530347 if (sdram_ch->cap_info.rank == 1 && params->base.dramtype == DDR3)
Kever Yangfa437432017-02-22 16:56:35 +0800348 writel(0x2EC7FFFF, &denali_pi[34]);
349}
350
Kever Yangfa437432017-02-22 16:56:35 +0800351static int phy_io_config(const struct chan_info *chan,
Jagan Teki95be76e2019-07-16 17:27:26 +0530352 const struct rk3399_sdram_params *params, u32 mr5)
Kever Yangfa437432017-02-22 16:56:35 +0800353{
354 u32 *denali_phy = chan->publ->denali_phy;
355 u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
356 u32 mode_sel;
357 u32 reg_value;
358 u32 drv_value, odt_value;
359 u32 speed;
360
Jagan Teki274c3372019-07-16 17:27:27 +0530361 /* vref setting & mode setting */
Jagan Tekifde7f452019-07-15 23:50:58 +0530362 if (params->base.dramtype == LPDDR4) {
Jagan Teki95be76e2019-07-16 17:27:26 +0530363 struct io_setting *io = lpddr4_get_io_settings(params, mr5);
364 u32 rd_vref = io->rd_vref * 1000;
365
366 if (rd_vref < 36700) {
367 /* MODE_LV[2:0] = LPDDR4 (Range 2)*/
368 vref_mode_dq = 0x7;
Jagan Teki274c3372019-07-16 17:27:27 +0530369 /* MODE[2:0]= LPDDR4 Range 2(0.4*VDDQ) */
370 mode_sel = 0x5;
Jagan Teki95be76e2019-07-16 17:27:26 +0530371 vref_value_dq = (rd_vref - 3300) / 521;
372 } else {
373 /* MODE_LV[2:0] = LPDDR4 (Range 1)*/
374 vref_mode_dq = 0x6;
Jagan Teki274c3372019-07-16 17:27:27 +0530375 /* MODE[2:0]= LPDDR4 Range 1(0.33*VDDQ) */
376 mode_sel = 0x4;
Jagan Teki95be76e2019-07-16 17:27:26 +0530377 vref_value_dq = (rd_vref - 15300) / 521;
378 }
Kever Yangfa437432017-02-22 16:56:35 +0800379 vref_mode_ac = 0x6;
Jagan Tekie939f922019-07-16 17:27:28 +0530380 /* VDDQ/3/2=16.8% */
381 vref_value_ac = 0x3;
Jagan Tekifde7f452019-07-15 23:50:58 +0530382 } else if (params->base.dramtype == LPDDR3) {
383 if (params->base.odt == 1) {
Kever Yangfa437432017-02-22 16:56:35 +0800384 vref_mode_dq = 0x5; /* LPDDR3 ODT */
385 drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
386 odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
387 if (drv_value == PHY_DRV_ODT_48) {
388 switch (odt_value) {
389 case PHY_DRV_ODT_240:
390 vref_value_dq = 0x16;
391 break;
392 case PHY_DRV_ODT_120:
393 vref_value_dq = 0x26;
394 break;
395 case PHY_DRV_ODT_60:
396 vref_value_dq = 0x36;
397 break;
398 default:
399 debug("Invalid ODT value.\n");
400 return -EINVAL;
401 }
402 } else if (drv_value == PHY_DRV_ODT_40) {
403 switch (odt_value) {
404 case PHY_DRV_ODT_240:
405 vref_value_dq = 0x19;
406 break;
407 case PHY_DRV_ODT_120:
408 vref_value_dq = 0x23;
409 break;
410 case PHY_DRV_ODT_60:
411 vref_value_dq = 0x31;
412 break;
413 default:
414 debug("Invalid ODT value.\n");
415 return -EINVAL;
416 }
417 } else if (drv_value == PHY_DRV_ODT_34_3) {
418 switch (odt_value) {
419 case PHY_DRV_ODT_240:
420 vref_value_dq = 0x17;
421 break;
422 case PHY_DRV_ODT_120:
423 vref_value_dq = 0x20;
424 break;
425 case PHY_DRV_ODT_60:
426 vref_value_dq = 0x2e;
427 break;
428 default:
429 debug("Invalid ODT value.\n");
430 return -EINVAL;
431 }
432 } else {
433 debug("Invalid DRV value.\n");
434 return -EINVAL;
435 }
436 } else {
437 vref_mode_dq = 0x2; /* LPDDR3 */
438 vref_value_dq = 0x1f;
439 }
440 vref_mode_ac = 0x2;
441 vref_value_ac = 0x1f;
Jagan Teki6cbd2422019-07-16 17:27:11 +0530442 mode_sel = 0x0;
Jagan Tekifde7f452019-07-15 23:50:58 +0530443 } else if (params->base.dramtype == DDR3) {
Kever Yangfa437432017-02-22 16:56:35 +0800444 /* DDR3L */
445 vref_mode_dq = 0x1;
446 vref_value_dq = 0x1f;
447 vref_mode_ac = 0x1;
448 vref_value_ac = 0x1f;
Jagan Teki6cbd2422019-07-16 17:27:11 +0530449 mode_sel = 0x1;
Kever Yangfa437432017-02-22 16:56:35 +0800450 } else {
451 debug("Unknown DRAM type.\n");
452 return -EINVAL;
453 }
454
455 reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq;
456
457 /* PHY_913 PHY_PAD_VREF_CTRL_DQ_0 12bits offset_8 */
458 clrsetbits_le32(&denali_phy[913], 0xfff << 8, reg_value << 8);
459 /* PHY_914 PHY_PAD_VREF_CTRL_DQ_1 12bits offset_0 */
460 clrsetbits_le32(&denali_phy[914], 0xfff, reg_value);
461 /* PHY_914 PHY_PAD_VREF_CTRL_DQ_2 12bits offset_16 */
462 clrsetbits_le32(&denali_phy[914], 0xfff << 16, reg_value << 16);
463 /* PHY_915 PHY_PAD_VREF_CTRL_DQ_3 12bits offset_0 */
464 clrsetbits_le32(&denali_phy[915], 0xfff, reg_value);
465
466 reg_value = (vref_mode_ac << 9) | (0x1 << 8) | vref_value_ac;
467
468 /* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */
469 clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16);
470
Kever Yangfa437432017-02-22 16:56:35 +0800471 /* PHY_924 PHY_PAD_FDBK_DRIVE */
472 clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15);
473 /* PHY_926 PHY_PAD_DATA_DRIVE */
474 clrsetbits_le32(&denali_phy[926], 0x7 << 6, mode_sel << 6);
475 /* PHY_927 PHY_PAD_DQS_DRIVE */
476 clrsetbits_le32(&denali_phy[927], 0x7 << 6, mode_sel << 6);
477 /* PHY_928 PHY_PAD_ADDR_DRIVE */
478 clrsetbits_le32(&denali_phy[928], 0x7 << 14, mode_sel << 14);
479 /* PHY_929 PHY_PAD_CLK_DRIVE */
480 clrsetbits_le32(&denali_phy[929], 0x7 << 14, mode_sel << 14);
481 /* PHY_935 PHY_PAD_CKE_DRIVE */
482 clrsetbits_le32(&denali_phy[935], 0x7 << 14, mode_sel << 14);
483 /* PHY_937 PHY_PAD_RST_DRIVE */
484 clrsetbits_le32(&denali_phy[937], 0x7 << 14, mode_sel << 14);
485 /* PHY_939 PHY_PAD_CS_DRIVE */
486 clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
487
YouMin Chenf8088bf2019-11-15 11:04:46 +0800488 if (params->base.dramtype == LPDDR4) {
Jagan Teki881860f2019-07-16 17:27:15 +0530489 /* BOOSTP_EN & BOOSTN_EN */
490 reg_value = ((PHY_BOOSTP_EN << 4) | PHY_BOOSTN_EN);
491 /* PHY_925 PHY_PAD_FDBK_DRIVE2 */
492 clrsetbits_le32(&denali_phy[925], 0xff << 8, reg_value << 8);
493 /* PHY_926 PHY_PAD_DATA_DRIVE */
494 clrsetbits_le32(&denali_phy[926], 0xff << 12, reg_value << 12);
495 /* PHY_927 PHY_PAD_DQS_DRIVE */
496 clrsetbits_le32(&denali_phy[927], 0xff << 14, reg_value << 14);
497 /* PHY_928 PHY_PAD_ADDR_DRIVE */
498 clrsetbits_le32(&denali_phy[928], 0xff << 20, reg_value << 20);
499 /* PHY_929 PHY_PAD_CLK_DRIVE */
500 clrsetbits_le32(&denali_phy[929], 0xff << 22, reg_value << 22);
501 /* PHY_935 PHY_PAD_CKE_DRIVE */
502 clrsetbits_le32(&denali_phy[935], 0xff << 20, reg_value << 20);
503 /* PHY_937 PHY_PAD_RST_DRIVE */
504 clrsetbits_le32(&denali_phy[937], 0xff << 20, reg_value << 20);
505 /* PHY_939 PHY_PAD_CS_DRIVE */
506 clrsetbits_le32(&denali_phy[939], 0xff << 20, reg_value << 20);
Jagan Tekif9f32d62019-07-16 17:27:16 +0530507
508 /* SLEWP_EN & SLEWN_EN */
509 reg_value = ((PHY_SLEWP_EN << 3) | PHY_SLEWN_EN);
510 /* PHY_924 PHY_PAD_FDBK_DRIVE */
511 clrsetbits_le32(&denali_phy[924], 0x3f << 8, reg_value << 8);
512 /* PHY_926 PHY_PAD_DATA_DRIVE */
513 clrsetbits_le32(&denali_phy[926], 0x3f, reg_value);
514 /* PHY_927 PHY_PAD_DQS_DRIVE */
515 clrsetbits_le32(&denali_phy[927], 0x3f, reg_value);
516 /* PHY_928 PHY_PAD_ADDR_DRIVE */
517 clrsetbits_le32(&denali_phy[928], 0x3f << 8, reg_value << 8);
518 /* PHY_929 PHY_PAD_CLK_DRIVE */
519 clrsetbits_le32(&denali_phy[929], 0x3f << 8, reg_value << 8);
520 /* PHY_935 PHY_PAD_CKE_DRIVE */
521 clrsetbits_le32(&denali_phy[935], 0x3f << 8, reg_value << 8);
522 /* PHY_937 PHY_PAD_RST_DRIVE */
523 clrsetbits_le32(&denali_phy[937], 0x3f << 8, reg_value << 8);
524 /* PHY_939 PHY_PAD_CS_DRIVE */
525 clrsetbits_le32(&denali_phy[939], 0x3f << 8, reg_value << 8);
Jagan Teki881860f2019-07-16 17:27:15 +0530526 }
527
Kever Yangfa437432017-02-22 16:56:35 +0800528 /* speed setting */
Jagan Tekifde7f452019-07-15 23:50:58 +0530529 if (params->base.ddr_freq < 400)
Kever Yangfa437432017-02-22 16:56:35 +0800530 speed = 0x0;
Jagan Tekifde7f452019-07-15 23:50:58 +0530531 else if (params->base.ddr_freq < 800)
Kever Yangfa437432017-02-22 16:56:35 +0800532 speed = 0x1;
Jagan Tekifde7f452019-07-15 23:50:58 +0530533 else if (params->base.ddr_freq < 1200)
Kever Yangfa437432017-02-22 16:56:35 +0800534 speed = 0x2;
535 else
536 speed = 0x3;
537
538 /* PHY_924 PHY_PAD_FDBK_DRIVE */
539 clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
540 /* PHY_926 PHY_PAD_DATA_DRIVE */
541 clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
542 /* PHY_927 PHY_PAD_DQS_DRIVE */
543 clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
544 /* PHY_928 PHY_PAD_ADDR_DRIVE */
545 clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
546 /* PHY_929 PHY_PAD_CLK_DRIVE */
547 clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
548 /* PHY_935 PHY_PAD_CKE_DRIVE */
549 clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
550 /* PHY_937 PHY_PAD_RST_DRIVE */
551 clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
552 /* PHY_939 PHY_PAD_CS_DRIVE */
553 clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
554
YouMin Chenf8088bf2019-11-15 11:04:46 +0800555 if (params->base.dramtype == LPDDR4) {
Jagan Tekid3d00992019-07-16 17:27:17 +0530556 /* RX_CM_INPUT */
557 reg_value = PHY_RX_CM_INPUT;
558 /* PHY_924 PHY_PAD_FDBK_DRIVE */
559 clrsetbits_le32(&denali_phy[924], 0x1 << 14, reg_value << 14);
560 /* PHY_926 PHY_PAD_DATA_DRIVE */
561 clrsetbits_le32(&denali_phy[926], 0x1 << 11, reg_value << 11);
562 /* PHY_927 PHY_PAD_DQS_DRIVE */
563 clrsetbits_le32(&denali_phy[927], 0x1 << 13, reg_value << 13);
564 /* PHY_928 PHY_PAD_ADDR_DRIVE */
565 clrsetbits_le32(&denali_phy[928], 0x1 << 19, reg_value << 19);
566 /* PHY_929 PHY_PAD_CLK_DRIVE */
567 clrsetbits_le32(&denali_phy[929], 0x1 << 21, reg_value << 21);
568 /* PHY_935 PHY_PAD_CKE_DRIVE */
569 clrsetbits_le32(&denali_phy[935], 0x1 << 19, reg_value << 19);
570 /* PHY_937 PHY_PAD_RST_DRIVE */
571 clrsetbits_le32(&denali_phy[937], 0x1 << 19, reg_value << 19);
572 /* PHY_939 PHY_PAD_CS_DRIVE */
573 clrsetbits_le32(&denali_phy[939], 0x1 << 19, reg_value << 19);
574 }
575
Kever Yangfa437432017-02-22 16:56:35 +0800576 return 0;
577}
578
Jagan Tekiba607fa2019-07-16 17:27:07 +0530579static void set_ds_odt(const struct chan_info *chan,
Jagan Tekic36abd02019-07-16 17:27:40 +0530580 struct rk3399_sdram_params *params,
581 bool ctl_phy_reg, u32 mr5)
Jagan Tekiba607fa2019-07-16 17:27:07 +0530582{
Jagan Tekic36abd02019-07-16 17:27:40 +0530583 u32 *denali_phy = get_denali_phy(chan, params, ctl_phy_reg);
584 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530585 u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
586 u32 tsel_idle_select_p, tsel_rd_select_p;
587 u32 tsel_idle_select_n, tsel_rd_select_n;
588 u32 tsel_wr_select_dq_p, tsel_wr_select_ca_p;
589 u32 tsel_wr_select_dq_n, tsel_wr_select_ca_n;
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530590 u32 tsel_ckcs_select_p, tsel_ckcs_select_n;
Jagan Teki2fb2de32019-07-16 17:27:22 +0530591 struct io_setting *io = NULL;
Jagan Tekif288d542019-07-16 17:27:24 +0530592 u32 soc_odt = 0;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530593 u32 reg_value;
594
595 if (params->base.dramtype == LPDDR4) {
Jagan Teki2fb2de32019-07-16 17:27:22 +0530596 io = lpddr4_get_io_settings(params, mr5);
597
Jagan Tekiba607fa2019-07-16 17:27:07 +0530598 tsel_rd_select_p = PHY_DRV_ODT_HI_Z;
Jagan Teki2fb2de32019-07-16 17:27:22 +0530599 tsel_rd_select_n = io->rd_odt;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530600
601 tsel_idle_select_p = PHY_DRV_ODT_HI_Z;
602 tsel_idle_select_n = PHY_DRV_ODT_240;
603
Jagan Teki2fb2de32019-07-16 17:27:22 +0530604 tsel_wr_select_dq_p = io->wr_dq_drv;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530605 tsel_wr_select_dq_n = PHY_DRV_ODT_40;
606
Jagan Teki2fb2de32019-07-16 17:27:22 +0530607 tsel_wr_select_ca_p = io->wr_ca_drv;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530608 tsel_wr_select_ca_n = PHY_DRV_ODT_40;
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530609
610 tsel_ckcs_select_p = io->wr_ckcs_drv;
611 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Jagan Tekif288d542019-07-16 17:27:24 +0530612 switch (tsel_rd_select_n) {
613 case PHY_DRV_ODT_240:
614 soc_odt = 1;
615 break;
616 case PHY_DRV_ODT_120:
617 soc_odt = 2;
618 break;
619 case PHY_DRV_ODT_80:
620 soc_odt = 3;
621 break;
622 case PHY_DRV_ODT_60:
623 soc_odt = 4;
624 break;
625 case PHY_DRV_ODT_48:
626 soc_odt = 5;
627 break;
628 case PHY_DRV_ODT_40:
629 soc_odt = 6;
630 break;
631 case PHY_DRV_ODT_34_3:
632 soc_odt = 6;
633 printf("%s: Unable to support LPDDR4 MR22 Soc ODT\n",
634 __func__);
635 break;
636 case PHY_DRV_ODT_HI_Z:
637 default:
638 soc_odt = 0;
639 break;
640 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530641 } else if (params->base.dramtype == LPDDR3) {
642 tsel_rd_select_p = PHY_DRV_ODT_240;
643 tsel_rd_select_n = PHY_DRV_ODT_HI_Z;
644
645 tsel_idle_select_p = PHY_DRV_ODT_240;
646 tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
647
648 tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
649 tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
650
651 tsel_wr_select_ca_p = PHY_DRV_ODT_48;
652 tsel_wr_select_ca_n = PHY_DRV_ODT_48;
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530653
654 tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
655 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530656 } else {
657 tsel_rd_select_p = PHY_DRV_ODT_240;
658 tsel_rd_select_n = PHY_DRV_ODT_240;
659
660 tsel_idle_select_p = PHY_DRV_ODT_240;
661 tsel_idle_select_n = PHY_DRV_ODT_240;
662
663 tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
664 tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
665
666 tsel_wr_select_ca_p = PHY_DRV_ODT_34_3;
667 tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530668
669 tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
670 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530671 }
672
Jagan Teki4eceda02019-07-16 17:27:25 +0530673 if (params->base.odt == 1) {
Jagan Tekiba607fa2019-07-16 17:27:07 +0530674 tsel_rd_en = 1;
Jagan Teki4eceda02019-07-16 17:27:25 +0530675
676 if (params->base.dramtype == LPDDR4)
677 tsel_rd_en = io->rd_odt_en;
678 } else {
Jagan Tekiba607fa2019-07-16 17:27:07 +0530679 tsel_rd_en = 0;
Jagan Teki4eceda02019-07-16 17:27:25 +0530680 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530681
682 tsel_wr_en = 0;
683 tsel_idle_en = 0;
684
Jagan Tekif288d542019-07-16 17:27:24 +0530685 /* F0_0 */
686 clrsetbits_le32(&denali_ctl[145], 0xFF << 16,
687 (soc_odt | (CS0_MR22_VAL << 3)) << 16);
688 /* F2_0, F1_0 */
689 clrsetbits_le32(&denali_ctl[146], 0xFF00FF,
690 ((soc_odt | (CS0_MR22_VAL << 3)) << 16) |
691 (soc_odt | (CS0_MR22_VAL << 3)));
692 /* F0_1 */
693 clrsetbits_le32(&denali_ctl[159], 0xFF << 16,
694 (soc_odt | (CS1_MR22_VAL << 3)) << 16);
695 /* F2_1, F1_1 */
696 clrsetbits_le32(&denali_ctl[160], 0xFF00FF,
697 ((soc_odt | (CS1_MR22_VAL << 3)) << 16) |
698 (soc_odt | (CS1_MR22_VAL << 3)));
699
Jagan Tekiba607fa2019-07-16 17:27:07 +0530700 /*
701 * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
702 * sets termination values for read/idle cycles and drive strength
703 * for write cycles for DQ/DM
704 */
705 reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
706 (tsel_wr_select_dq_n << 8) | (tsel_wr_select_dq_p << 12) |
707 (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
708 clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
709 clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
710 clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
711 clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
712
713 /*
714 * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
715 * sets termination values for read/idle cycles and drive strength
716 * for write cycles for DQS
717 */
718 clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
719 clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
720 clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
721 clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
722
723 /* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
724 reg_value = tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 0x4);
YouMin Chenf8088bf2019-11-15 11:04:46 +0800725 if (params->base.dramtype == LPDDR4) {
Jagan Teki66912ba2019-07-16 17:27:19 +0530726 /* LPDDR4 these register read always return 0, so
727 * can not use clrsetbits_le32(), need to write32
728 */
729 writel((0x300 << 8) | reg_value, &denali_phy[544]);
730 writel((0x300 << 8) | reg_value, &denali_phy[672]);
731 writel((0x300 << 8) | reg_value, &denali_phy[800]);
732 } else {
733 clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
734 clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
735 clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
736 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530737
738 /* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
739 clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
740
741 /* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
Jagan Tekic36abd02019-07-16 17:27:40 +0530742 if (!ctl_phy_reg)
743 clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530744
745 /* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
746 clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
747
748 /* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530749 clrsetbits_le32(&denali_phy[939], 0xff,
750 tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
Jagan Tekiba607fa2019-07-16 17:27:07 +0530751
752 /* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
Jagan Tekiaa30aae2019-07-16 17:27:23 +0530753 clrsetbits_le32(&denali_phy[929], 0xff,
754 tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
Jagan Tekiba607fa2019-07-16 17:27:07 +0530755
756 /* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
757 clrsetbits_le32(&denali_phy[924], 0xff,
758 tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
759 clrsetbits_le32(&denali_phy[925], 0xff,
760 tsel_rd_select_n | (tsel_rd_select_p << 4));
761
762 /* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
763 reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
764 << 16;
765 clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
766 clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
767 clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
768 clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
769
770 /* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
771 reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
772 << 24;
773 clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
774 clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
775 clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
776 clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
777
778 /* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
779 reg_value = tsel_wr_en << 8;
780 clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
781 clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
782 clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
783
784 /* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
785 reg_value = tsel_wr_en << 17;
786 clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
787 /*
788 * pad_rst/cke/cs/clk_term tsel 1bits
789 * DENALI_PHY_938/936/940/934 offset_17
790 */
791 clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
792 clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
793 clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
794 clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
795
796 /* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
797 clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
798
Jagan Teki95be76e2019-07-16 17:27:26 +0530799 phy_io_config(chan, params, mr5);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530800}
801
YouMin Chen0cacc272019-11-15 11:04:48 +0800802static void pctl_start(struct dram_info *dram,
803 struct rk3399_sdram_params *params,
804 u32 channel_mask)
Jagan Tekiba607fa2019-07-16 17:27:07 +0530805{
YouMin Chen0cacc272019-11-15 11:04:48 +0800806 const struct chan_info *chan_0 = &dram->chan[0];
807 const struct chan_info *chan_1 = &dram->chan[1];
808
809 u32 *denali_ctl_0 = chan_0->pctl->denali_ctl;
810 u32 *denali_phy_0 = chan_0->publ->denali_phy;
811 u32 *ddrc0_con_0 = get_ddrc0_con(dram, 0);
812 u32 *denali_ctl_1 = chan_1->pctl->denali_ctl;
813 u32 *denali_phy_1 = chan_1->publ->denali_phy;
814 u32 *ddrc1_con_0 = get_ddrc0_con(dram, 1);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530815 u32 count = 0;
816 u32 byte, tmp;
817
YouMin Chen0cacc272019-11-15 11:04:48 +0800818 /* PHY_DLL_RST_EN */
819 if (channel_mask & 1) {
820 writel(0x01000000, &ddrc0_con_0);
821 clrsetbits_le32(&denali_phy_0[957], 0x3 << 24, 0x2 << 24);
822 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530823
YouMin Chen0cacc272019-11-15 11:04:48 +0800824 if (channel_mask & 1) {
825 count = 0;
826 while (!(readl(&denali_ctl_0[203]) & (1 << 3))) {
827 if (count > 1000) {
828 printf("%s: Failed to init pctl channel 0\n",
829 __func__);
830 while (1)
831 ;
832 }
833 udelay(1);
834 count++;
Jagan Tekiba607fa2019-07-16 17:27:07 +0530835 }
836
YouMin Chen0cacc272019-11-15 11:04:48 +0800837 writel(0x01000100, &ddrc0_con_0);
838 for (byte = 0; byte < 4; byte++) {
839 tmp = 0x820;
840 writel((tmp << 16) | tmp,
841 &denali_phy_0[53 + (128 * byte)]);
842 writel((tmp << 16) | tmp,
843 &denali_phy_0[54 + (128 * byte)]);
844 writel((tmp << 16) | tmp,
845 &denali_phy_0[55 + (128 * byte)]);
846 writel((tmp << 16) | tmp,
847 &denali_phy_0[56 + (128 * byte)]);
848 writel((tmp << 16) | tmp,
849 &denali_phy_0[57 + (128 * byte)]);
850 clrsetbits_le32(&denali_phy_0[58 + (128 * byte)],
851 0xffff, tmp);
852 }
853 clrsetbits_le32(&denali_ctl_0[68], PWRUP_SREFRESH_EXIT,
854 dram->pwrup_srefresh_exit[0]);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530855 }
856
YouMin Chen0cacc272019-11-15 11:04:48 +0800857 if (channel_mask & 2) {
858 writel(0x01000000, &ddrc1_con_0);
859 clrsetbits_le32(&denali_phy_1[957], 0x3 << 24, 0x2 << 24);
Jagan Tekiba607fa2019-07-16 17:27:07 +0530860 }
YouMin Chen0cacc272019-11-15 11:04:48 +0800861 if (channel_mask & 2) {
862 count = 0;
863 while (!(readl(&denali_ctl_1[203]) & (1 << 3))) {
864 if (count > 1000) {
865 printf("%s: Failed to init pctl channel 1\n",
866 __func__);
867 while (1)
868 ;
869 }
870 udelay(1);
871 count++;
872 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530873
YouMin Chen0cacc272019-11-15 11:04:48 +0800874 writel(0x01000100, &ddrc1_con_0);
875 for (byte = 0; byte < 4; byte++) {
876 tmp = 0x820;
877 writel((tmp << 16) | tmp,
878 &denali_phy_1[53 + (128 * byte)]);
879 writel((tmp << 16) | tmp,
880 &denali_phy_1[54 + (128 * byte)]);
881 writel((tmp << 16) | tmp,
882 &denali_phy_1[55 + (128 * byte)]);
883 writel((tmp << 16) | tmp,
884 &denali_phy_1[56 + (128 * byte)]);
885 writel((tmp << 16) | tmp,
886 &denali_phy_1[57 + (128 * byte)]);
887 clrsetbits_le32(&denali_phy_1[58 + (128 * byte)],
888 0xffff, tmp);
889 }
890
891 clrsetbits_le32(&denali_ctl_1[68], PWRUP_SREFRESH_EXIT,
892 dram->pwrup_srefresh_exit[1]);
893
894 /*
895 * restore channel 1 RESET original setting
896 * to avoid 240ohm too weak to prevent ESD test
897 */
898 if (params->base.dramtype == LPDDR4)
899 clrsetbits_le32(&denali_phy_1[937], 0xff,
900 params->phy_regs.denali_phy[937] &
901 0xFF);
902 }
Jagan Tekiba607fa2019-07-16 17:27:07 +0530903}
904
Jagan Tekife42d4a2019-07-15 23:58:44 +0530905static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
Jagan Teki2fb2de32019-07-16 17:27:22 +0530906 u32 channel, struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +0800907{
908 u32 *denali_ctl = chan->pctl->denali_ctl;
909 u32 *denali_pi = chan->pi->denali_pi;
910 u32 *denali_phy = chan->publ->denali_phy;
Jagan Tekifde7f452019-07-15 23:50:58 +0530911 const u32 *params_ctl = params->pctl_regs.denali_ctl;
912 const u32 *params_phy = params->phy_regs.denali_phy;
Kever Yangfa437432017-02-22 16:56:35 +0800913 u32 tmp, tmp1, tmp2;
YouMin Chen0cacc272019-11-15 11:04:48 +0800914 struct rk3399_sdram_params *params_cfg;
915 u32 byte;
Kever Yangfa437432017-02-22 16:56:35 +0800916
YouMin Chen0cacc272019-11-15 11:04:48 +0800917 dram->ops->modify_param(chan, params);
Kever Yangfa437432017-02-22 16:56:35 +0800918 /*
919 * work around controller bug:
920 * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
921 */
YouMin Chena922d0d2019-11-15 11:04:45 +0800922 sdram_copy_to_reg(&denali_ctl[1], &params_ctl[1],
923 sizeof(struct rk3399_ddr_pctl_regs) - 4);
Kever Yangfa437432017-02-22 16:56:35 +0800924 writel(params_ctl[0], &denali_ctl[0]);
Jagan Teki3eaf5392019-07-15 23:50:57 +0530925
Jagan Teki47627c82019-07-16 17:27:13 +0530926 /*
927 * two channel init at the same time, then ZQ Cal Start
928 * at the same time, it will use the same RZQ, but cannot
929 * start at the same time.
930 *
931 * So, increase tINIT3 for channel 1, will avoid two
932 * channel ZQ Cal Start at the same time
933 */
934 if (params->base.dramtype == LPDDR4 && channel == 1) {
935 tmp = ((params->base.ddr_freq * MHz + 999) / 1000);
936 tmp1 = readl(&denali_ctl[14]);
937 writel(tmp + tmp1, &denali_ctl[14]);
938 }
939
YouMin Chena922d0d2019-11-15 11:04:45 +0800940 sdram_copy_to_reg(denali_pi, &params->pi_regs.denali_pi[0],
941 sizeof(struct rk3399_ddr_pi_regs));
Jagan Teki3eaf5392019-07-15 23:50:57 +0530942
Kever Yangfa437432017-02-22 16:56:35 +0800943 /* rank count need to set for init */
Jagan Tekifde7f452019-07-15 23:50:58 +0530944 set_memory_map(chan, channel, params);
Kever Yangfa437432017-02-22 16:56:35 +0800945
Jagan Tekifde7f452019-07-15 23:50:58 +0530946 writel(params->phy_regs.denali_phy[910], &denali_phy[910]);
947 writel(params->phy_regs.denali_phy[911], &denali_phy[911]);
948 writel(params->phy_regs.denali_phy[912], &denali_phy[912]);
Kever Yangfa437432017-02-22 16:56:35 +0800949
YouMin Chenf8088bf2019-11-15 11:04:46 +0800950 if (params->base.dramtype == LPDDR4) {
Jagan Teki009fe1b2019-07-16 17:27:14 +0530951 writel(params->phy_regs.denali_phy[898], &denali_phy[898]);
952 writel(params->phy_regs.denali_phy[919], &denali_phy[919]);
953 }
954
Jagan Tekia0aebe82019-07-15 23:58:45 +0530955 dram->pwrup_srefresh_exit[channel] = readl(&denali_ctl[68]) &
956 PWRUP_SREFRESH_EXIT;
Kever Yangfa437432017-02-22 16:56:35 +0800957 clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT);
958
959 /* PHY_DLL_RST_EN */
960 clrsetbits_le32(&denali_phy[957], 0x3 << 24, 1 << 24);
961
962 setbits_le32(&denali_pi[0], START);
963 setbits_le32(&denali_ctl[0], START);
964
Jagan Teki5cbc8662019-07-16 17:27:12 +0530965 /**
966 * LPDDR4 use PLL bypass mode for init
967 * not need to wait for the PLL to lock
968 */
969 if (params->base.dramtype != LPDDR4) {
970 /* Waiting for phy DLL lock */
971 while (1) {
972 tmp = readl(&denali_phy[920]);
973 tmp1 = readl(&denali_phy[921]);
974 tmp2 = readl(&denali_phy[922]);
975 if ((((tmp >> 16) & 0x1) == 0x1) &&
976 (((tmp1 >> 16) & 0x1) == 0x1) &&
977 (((tmp1 >> 0) & 0x1) == 0x1) &&
978 (((tmp2 >> 0) & 0x1) == 0x1))
979 break;
980 }
Kever Yangfa437432017-02-22 16:56:35 +0800981 }
982
YouMin Chena922d0d2019-11-15 11:04:45 +0800983 sdram_copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
984 sdram_copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
985 sdram_copy_to_reg(&denali_phy[128], &params_phy[128],
986 (218 - 128 + 1) * 4);
987 sdram_copy_to_reg(&denali_phy[256], &params_phy[256],
988 (346 - 256 + 1) * 4);
989 sdram_copy_to_reg(&denali_phy[384], &params_phy[384],
990 (474 - 384 + 1) * 4);
991 sdram_copy_to_reg(&denali_phy[512], &params_phy[512],
992 (549 - 512 + 1) * 4);
993 sdram_copy_to_reg(&denali_phy[640], &params_phy[640],
994 (677 - 640 + 1) * 4);
995 sdram_copy_to_reg(&denali_phy[768], &params_phy[768],
996 (805 - 768 + 1) * 4);
997
YouMin Chen0cacc272019-11-15 11:04:48 +0800998 if (params->base.dramtype == LPDDR4)
999 params_cfg = dram->ops->get_phy_index_params(1, params);
1000 else
1001 params_cfg = dram->ops->get_phy_index_params(0, params);
Kever Yangfa437432017-02-22 16:56:35 +08001002
YouMin Chen0cacc272019-11-15 11:04:48 +08001003 clrsetbits_le32(&params_cfg->phy_regs.denali_phy[896], 0x3 << 8,
1004 0 << 8);
1005 writel(params_cfg->phy_regs.denali_phy[896], &denali_phy[896]);
Kever Yangfa437432017-02-22 16:56:35 +08001006
YouMin Chen0cacc272019-11-15 11:04:48 +08001007 writel(params->phy_regs.denali_phy[83] + (0x10 << 16),
1008 &denali_phy[83]);
1009 writel(params->phy_regs.denali_phy[84] + (0x10 << 8),
1010 &denali_phy[84]);
1011 writel(params->phy_regs.denali_phy[211] + (0x10 << 16),
1012 &denali_phy[211]);
1013 writel(params->phy_regs.denali_phy[212] + (0x10 << 8),
1014 &denali_phy[212]);
1015 writel(params->phy_regs.denali_phy[339] + (0x10 << 16),
1016 &denali_phy[339]);
1017 writel(params->phy_regs.denali_phy[340] + (0x10 << 8),
1018 &denali_phy[340]);
1019 writel(params->phy_regs.denali_phy[467] + (0x10 << 16),
1020 &denali_phy[467]);
1021 writel(params->phy_regs.denali_phy[468] + (0x10 << 8),
1022 &denali_phy[468]);
1023
1024 if (params->base.dramtype == LPDDR4) {
1025 /*
1026 * to improve write dqs and dq phase from 1.5ns to 3.5ns
1027 * at 50MHz. this's the measure result from oscilloscope
1028 * of dqs and dq write signal.
1029 */
1030 for (byte = 0; byte < 4; byte++) {
1031 tmp = 0x680;
1032 clrsetbits_le32(&denali_phy[1 + (128 * byte)],
1033 0xfff << 8, tmp << 8);
1034 }
1035 /*
1036 * to workaround 366ball two channel's RESET connect to
1037 * one RESET signal of die
1038 */
1039 if (channel == 1)
1040 clrsetbits_le32(&denali_phy[937], 0xff,
1041 PHY_DRV_ODT_240 |
1042 (PHY_DRV_ODT_240 << 0x4));
1043 }
Kever Yangfa437432017-02-22 16:56:35 +08001044
Kever Yangfa437432017-02-22 16:56:35 +08001045 return 0;
1046}
1047
1048static void select_per_cs_training_index(const struct chan_info *chan,
1049 u32 rank)
1050{
1051 u32 *denali_phy = chan->publ->denali_phy;
1052
1053 /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
Jagan Teki63f4d712019-07-15 23:50:56 +05301054 if ((readl(&denali_phy[84]) >> 16) & 1) {
Kever Yangfa437432017-02-22 16:56:35 +08001055 /*
1056 * PHY_8/136/264/392
1057 * phy_per_cs_training_index_X 1bit offset_24
1058 */
1059 clrsetbits_le32(&denali_phy[8], 0x1 << 24, rank << 24);
1060 clrsetbits_le32(&denali_phy[136], 0x1 << 24, rank << 24);
1061 clrsetbits_le32(&denali_phy[264], 0x1 << 24, rank << 24);
1062 clrsetbits_le32(&denali_phy[392], 0x1 << 24, rank << 24);
1063 }
1064}
1065
1066static void override_write_leveling_value(const struct chan_info *chan)
1067{
1068 u32 *denali_ctl = chan->pctl->denali_ctl;
1069 u32 *denali_phy = chan->publ->denali_phy;
1070 u32 byte;
1071
1072 /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
1073 setbits_le32(&denali_phy[896], 1);
1074
1075 /*
1076 * PHY_8/136/264/392
1077 * phy_per_cs_training_multicast_en_X 1bit offset_16
1078 */
1079 clrsetbits_le32(&denali_phy[8], 0x1 << 16, 1 << 16);
1080 clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16);
1081 clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16);
1082 clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16);
1083
1084 for (byte = 0; byte < 4; byte++)
1085 clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16,
1086 0x200 << 16);
1087
1088 /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
1089 clrbits_le32(&denali_phy[896], 1);
1090
1091 /* CTL_200 ctrlupd_req 1bit offset_8 */
1092 clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
1093}
1094
1095static int data_training_ca(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301096 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001097{
1098 u32 *denali_pi = chan->pi->denali_pi;
1099 u32 *denali_phy = chan->publ->denali_phy;
1100 u32 i, tmp;
1101 u32 obs_0, obs_1, obs_2, obs_err = 0;
Jagan Teki355490d2019-07-15 23:51:05 +05301102 u32 rank = params->ch[channel].cap_info.rank;
Jagan Teki708e9a72019-07-15 23:58:41 +05301103 u32 rank_mask;
Kever Yangfa437432017-02-22 16:56:35 +08001104
Jagan Teki01976ae2019-07-15 23:58:40 +05301105 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1106 writel(0x00003f7c, (&denali_pi[175]));
1107
Jagan Teki3dae87d2019-07-16 17:27:09 +05301108 if (params->base.dramtype == LPDDR4)
1109 rank_mask = (rank == 1) ? 0x5 : 0xf;
1110 else
1111 rank_mask = (rank == 1) ? 0x1 : 0x3;
Jagan Teki708e9a72019-07-15 23:58:41 +05301112
1113 for (i = 0; i < 4; i++) {
1114 if (!(rank_mask & (1 << i)))
1115 continue;
1116
Kever Yangfa437432017-02-22 16:56:35 +08001117 select_per_cs_training_index(chan, i);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301118
Kever Yangfa437432017-02-22 16:56:35 +08001119 /* PI_100 PI_CALVL_EN:RW:8:2 */
1120 clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301121
Kever Yangfa437432017-02-22 16:56:35 +08001122 /* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
1123 clrsetbits_le32(&denali_pi[92],
1124 (0x1 << 16) | (0x3 << 24),
1125 (0x1 << 16) | (i << 24));
1126
1127 /* Waiting for training complete */
1128 while (1) {
1129 /* PI_174 PI_INT_STATUS:RD:8:18 */
1130 tmp = readl(&denali_pi[174]) >> 8;
1131 /*
1132 * check status obs
1133 * PHY_532/660/789 phy_adr_calvl_obs1_:0:32
1134 */
1135 obs_0 = readl(&denali_phy[532]);
1136 obs_1 = readl(&denali_phy[660]);
1137 obs_2 = readl(&denali_phy[788]);
1138 if (((obs_0 >> 30) & 0x3) ||
1139 ((obs_1 >> 30) & 0x3) ||
1140 ((obs_2 >> 30) & 0x3))
1141 obs_err = 1;
1142 if ((((tmp >> 11) & 0x1) == 0x1) &&
1143 (((tmp >> 13) & 0x1) == 0x1) &&
1144 (((tmp >> 5) & 0x1) == 0x0) &&
Jagan Teki63f4d712019-07-15 23:50:56 +05301145 obs_err == 0)
Kever Yangfa437432017-02-22 16:56:35 +08001146 break;
1147 else if ((((tmp >> 5) & 0x1) == 0x1) ||
1148 (obs_err == 1))
1149 return -EIO;
1150 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301151
Kever Yangfa437432017-02-22 16:56:35 +08001152 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1153 writel(0x00003f7c, (&denali_pi[175]));
1154 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301155
Kever Yangfa437432017-02-22 16:56:35 +08001156 clrbits_le32(&denali_pi[100], 0x3 << 8);
1157
1158 return 0;
1159}
1160
1161static int data_training_wl(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301162 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001163{
1164 u32 *denali_pi = chan->pi->denali_pi;
1165 u32 *denali_phy = chan->publ->denali_phy;
1166 u32 i, tmp;
1167 u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
Jagan Teki355490d2019-07-15 23:51:05 +05301168 u32 rank = params->ch[channel].cap_info.rank;
Kever Yangfa437432017-02-22 16:56:35 +08001169
Jagan Teki01976ae2019-07-15 23:58:40 +05301170 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1171 writel(0x00003f7c, (&denali_pi[175]));
1172
Kever Yangfa437432017-02-22 16:56:35 +08001173 for (i = 0; i < rank; i++) {
1174 select_per_cs_training_index(chan, i);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301175
Kever Yangfa437432017-02-22 16:56:35 +08001176 /* PI_60 PI_WRLVL_EN:RW:8:2 */
1177 clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301178
Kever Yangfa437432017-02-22 16:56:35 +08001179 /* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
1180 clrsetbits_le32(&denali_pi[59],
1181 (0x1 << 8) | (0x3 << 16),
1182 (0x1 << 8) | (i << 16));
1183
1184 /* Waiting for training complete */
1185 while (1) {
1186 /* PI_174 PI_INT_STATUS:RD:8:18 */
1187 tmp = readl(&denali_pi[174]) >> 8;
1188
1189 /*
1190 * check status obs, if error maybe can not
1191 * get leveling done PHY_40/168/296/424
1192 * phy_wrlvl_status_obs_X:0:13
1193 */
1194 obs_0 = readl(&denali_phy[40]);
1195 obs_1 = readl(&denali_phy[168]);
1196 obs_2 = readl(&denali_phy[296]);
1197 obs_3 = readl(&denali_phy[424]);
1198 if (((obs_0 >> 12) & 0x1) ||
1199 ((obs_1 >> 12) & 0x1) ||
1200 ((obs_2 >> 12) & 0x1) ||
1201 ((obs_3 >> 12) & 0x1))
1202 obs_err = 1;
1203 if ((((tmp >> 10) & 0x1) == 0x1) &&
1204 (((tmp >> 13) & 0x1) == 0x1) &&
1205 (((tmp >> 4) & 0x1) == 0x0) &&
Jagan Teki63f4d712019-07-15 23:50:56 +05301206 obs_err == 0)
Kever Yangfa437432017-02-22 16:56:35 +08001207 break;
1208 else if ((((tmp >> 4) & 0x1) == 0x1) ||
1209 (obs_err == 1))
1210 return -EIO;
1211 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301212
Kever Yangfa437432017-02-22 16:56:35 +08001213 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1214 writel(0x00003f7c, (&denali_pi[175]));
1215 }
1216
1217 override_write_leveling_value(chan);
1218 clrbits_le32(&denali_pi[60], 0x3 << 8);
1219
1220 return 0;
1221}
1222
1223static int data_training_rg(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301224 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001225{
1226 u32 *denali_pi = chan->pi->denali_pi;
1227 u32 *denali_phy = chan->publ->denali_phy;
1228 u32 i, tmp;
1229 u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
Jagan Teki355490d2019-07-15 23:51:05 +05301230 u32 rank = params->ch[channel].cap_info.rank;
Kever Yangfa437432017-02-22 16:56:35 +08001231
Jagan Teki01976ae2019-07-15 23:58:40 +05301232 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1233 writel(0x00003f7c, (&denali_pi[175]));
1234
Kever Yangfa437432017-02-22 16:56:35 +08001235 for (i = 0; i < rank; i++) {
1236 select_per_cs_training_index(chan, i);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301237
Kever Yangfa437432017-02-22 16:56:35 +08001238 /* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
1239 clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301240
Kever Yangfa437432017-02-22 16:56:35 +08001241 /*
1242 * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
1243 * PI_RDLVL_CS:RW:24:2
1244 */
1245 clrsetbits_le32(&denali_pi[74],
1246 (0x1 << 16) | (0x3 << 24),
1247 (0x1 << 16) | (i << 24));
1248
1249 /* Waiting for training complete */
1250 while (1) {
1251 /* PI_174 PI_INT_STATUS:RD:8:18 */
1252 tmp = readl(&denali_pi[174]) >> 8;
1253
1254 /*
1255 * check status obs
1256 * PHY_43/171/299/427
1257 * PHY_GTLVL_STATUS_OBS_x:16:8
1258 */
1259 obs_0 = readl(&denali_phy[43]);
1260 obs_1 = readl(&denali_phy[171]);
1261 obs_2 = readl(&denali_phy[299]);
1262 obs_3 = readl(&denali_phy[427]);
1263 if (((obs_0 >> (16 + 6)) & 0x3) ||
1264 ((obs_1 >> (16 + 6)) & 0x3) ||
1265 ((obs_2 >> (16 + 6)) & 0x3) ||
1266 ((obs_3 >> (16 + 6)) & 0x3))
1267 obs_err = 1;
1268 if ((((tmp >> 9) & 0x1) == 0x1) &&
1269 (((tmp >> 13) & 0x1) == 0x1) &&
1270 (((tmp >> 3) & 0x1) == 0x0) &&
Jagan Teki63f4d712019-07-15 23:50:56 +05301271 obs_err == 0)
Kever Yangfa437432017-02-22 16:56:35 +08001272 break;
1273 else if ((((tmp >> 3) & 0x1) == 0x1) ||
1274 (obs_err == 1))
1275 return -EIO;
1276 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301277
Kever Yangfa437432017-02-22 16:56:35 +08001278 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1279 writel(0x00003f7c, (&denali_pi[175]));
1280 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301281
Kever Yangfa437432017-02-22 16:56:35 +08001282 clrbits_le32(&denali_pi[80], 0x3 << 24);
1283
1284 return 0;
1285}
1286
1287static int data_training_rl(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301288 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001289{
1290 u32 *denali_pi = chan->pi->denali_pi;
1291 u32 i, tmp;
Jagan Teki355490d2019-07-15 23:51:05 +05301292 u32 rank = params->ch[channel].cap_info.rank;
Kever Yangfa437432017-02-22 16:56:35 +08001293
Jagan Teki01976ae2019-07-15 23:58:40 +05301294 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1295 writel(0x00003f7c, (&denali_pi[175]));
1296
Kever Yangfa437432017-02-22 16:56:35 +08001297 for (i = 0; i < rank; i++) {
1298 select_per_cs_training_index(chan, i);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301299
Kever Yangfa437432017-02-22 16:56:35 +08001300 /* PI_80 PI_RDLVL_EN:RW:16:2 */
1301 clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301302
Kever Yangfa437432017-02-22 16:56:35 +08001303 /* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
1304 clrsetbits_le32(&denali_pi[74],
1305 (0x1 << 8) | (0x3 << 24),
1306 (0x1 << 8) | (i << 24));
1307
1308 /* Waiting for training complete */
1309 while (1) {
1310 /* PI_174 PI_INT_STATUS:RD:8:18 */
1311 tmp = readl(&denali_pi[174]) >> 8;
1312
1313 /*
1314 * make sure status obs not report error bit
1315 * PHY_46/174/302/430
1316 * phy_rdlvl_status_obs_X:16:8
1317 */
1318 if ((((tmp >> 8) & 0x1) == 0x1) &&
1319 (((tmp >> 13) & 0x1) == 0x1) &&
1320 (((tmp >> 2) & 0x1) == 0x0))
1321 break;
1322 else if (((tmp >> 2) & 0x1) == 0x1)
1323 return -EIO;
1324 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301325
Kever Yangfa437432017-02-22 16:56:35 +08001326 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1327 writel(0x00003f7c, (&denali_pi[175]));
1328 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301329
Kever Yangfa437432017-02-22 16:56:35 +08001330 clrbits_le32(&denali_pi[80], 0x3 << 16);
1331
1332 return 0;
1333}
1334
1335static int data_training_wdql(const struct chan_info *chan, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301336 const struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001337{
1338 u32 *denali_pi = chan->pi->denali_pi;
1339 u32 i, tmp;
Jagan Teki355490d2019-07-15 23:51:05 +05301340 u32 rank = params->ch[channel].cap_info.rank;
Jagan Teki21cf3922019-07-15 23:58:42 +05301341 u32 rank_mask;
Kever Yangfa437432017-02-22 16:56:35 +08001342
Jagan Teki01976ae2019-07-15 23:58:40 +05301343 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1344 writel(0x00003f7c, (&denali_pi[175]));
1345
Jagan Tekic716bf62019-07-16 17:27:10 +05301346 if (params->base.dramtype == LPDDR4)
1347 rank_mask = (rank == 1) ? 0x5 : 0xf;
1348 else
1349 rank_mask = (rank == 1) ? 0x1 : 0x3;
Jagan Teki21cf3922019-07-15 23:58:42 +05301350
1351 for (i = 0; i < 4; i++) {
1352 if (!(rank_mask & (1 << i)))
1353 continue;
1354
Kever Yangfa437432017-02-22 16:56:35 +08001355 select_per_cs_training_index(chan, i);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301356
Kever Yangfa437432017-02-22 16:56:35 +08001357 /*
1358 * disable PI_WDQLVL_VREF_EN before wdq leveling?
1359 * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
1360 */
1361 clrbits_le32(&denali_pi[181], 0x1 << 8);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301362
Kever Yangfa437432017-02-22 16:56:35 +08001363 /* PI_124 PI_WDQLVL_EN:RW:16:2 */
1364 clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
Jagan Teki3eaf5392019-07-15 23:50:57 +05301365
Kever Yangfa437432017-02-22 16:56:35 +08001366 /* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
1367 clrsetbits_le32(&denali_pi[121],
1368 (0x1 << 8) | (0x3 << 16),
1369 (0x1 << 8) | (i << 16));
1370
1371 /* Waiting for training complete */
1372 while (1) {
1373 /* PI_174 PI_INT_STATUS:RD:8:18 */
1374 tmp = readl(&denali_pi[174]) >> 8;
1375 if ((((tmp >> 12) & 0x1) == 0x1) &&
1376 (((tmp >> 13) & 0x1) == 0x1) &&
1377 (((tmp >> 6) & 0x1) == 0x0))
1378 break;
1379 else if (((tmp >> 6) & 0x1) == 0x1)
1380 return -EIO;
1381 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301382
Kever Yangfa437432017-02-22 16:56:35 +08001383 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1384 writel(0x00003f7c, (&denali_pi[175]));
1385 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05301386
Kever Yangfa437432017-02-22 16:56:35 +08001387 clrbits_le32(&denali_pi[124], 0x3 << 16);
1388
1389 return 0;
1390}
1391
Jagan Tekie6ae37a2019-07-16 17:27:29 +05301392static int data_training(struct dram_info *dram, u32 channel,
Jagan Tekifde7f452019-07-15 23:50:58 +05301393 const struct rk3399_sdram_params *params,
Kever Yangfa437432017-02-22 16:56:35 +08001394 u32 training_flag)
1395{
Jagan Tekie6ae37a2019-07-16 17:27:29 +05301396 struct chan_info *chan = &dram->chan[channel];
Kever Yangfa437432017-02-22 16:56:35 +08001397 u32 *denali_phy = chan->publ->denali_phy;
Jagan Teki02fad6f2019-07-15 23:58:39 +05301398 int ret;
Kever Yangfa437432017-02-22 16:56:35 +08001399
1400 /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
1401 setbits_le32(&denali_phy[927], (1 << 22));
1402
1403 if (training_flag == PI_FULL_TRAINING) {
Jagan Tekifde7f452019-07-15 23:50:58 +05301404 if (params->base.dramtype == LPDDR4) {
Jagan Tekic36abd02019-07-16 17:27:40 +05301405 training_flag = PI_WRITE_LEVELING |
Kever Yangfa437432017-02-22 16:56:35 +08001406 PI_READ_GATE_TRAINING |
1407 PI_READ_LEVELING | PI_WDQ_LEVELING;
Jagan Tekifde7f452019-07-15 23:50:58 +05301408 } else if (params->base.dramtype == LPDDR3) {
Kever Yangfa437432017-02-22 16:56:35 +08001409 training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
1410 PI_READ_GATE_TRAINING;
Jagan Tekifde7f452019-07-15 23:50:58 +05301411 } else if (params->base.dramtype == DDR3) {
Kever Yangfa437432017-02-22 16:56:35 +08001412 training_flag = PI_WRITE_LEVELING |
1413 PI_READ_GATE_TRAINING |
1414 PI_READ_LEVELING;
1415 }
1416 }
1417
1418 /* ca training(LPDDR4,LPDDR3 support) */
Jagan Teki02fad6f2019-07-15 23:58:39 +05301419 if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) {
1420 ret = data_training_ca(chan, channel, params);
1421 if (ret < 0) {
1422 debug("%s: data training ca failed\n", __func__);
1423 return ret;
1424 }
1425 }
Kever Yangfa437432017-02-22 16:56:35 +08001426
1427 /* write leveling(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki02fad6f2019-07-15 23:58:39 +05301428 if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) {
1429 ret = data_training_wl(chan, channel, params);
1430 if (ret < 0) {
1431 debug("%s: data training wl failed\n", __func__);
1432 return ret;
1433 }
1434 }
Kever Yangfa437432017-02-22 16:56:35 +08001435
1436 /* read gate training(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki02fad6f2019-07-15 23:58:39 +05301437 if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) {
1438 ret = data_training_rg(chan, channel, params);
1439 if (ret < 0) {
1440 debug("%s: data training rg failed\n", __func__);
1441 return ret;
1442 }
1443 }
Kever Yangfa437432017-02-22 16:56:35 +08001444
1445 /* read leveling(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki02fad6f2019-07-15 23:58:39 +05301446 if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) {
1447 ret = data_training_rl(chan, channel, params);
1448 if (ret < 0) {
1449 debug("%s: data training rl failed\n", __func__);
1450 return ret;
1451 }
1452 }
Kever Yangfa437432017-02-22 16:56:35 +08001453
1454 /* wdq leveling(LPDDR4 support) */
Jagan Teki02fad6f2019-07-15 23:58:39 +05301455 if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) {
1456 ret = data_training_wdql(chan, channel, params);
1457 if (ret < 0) {
1458 debug("%s: data training wdql failed\n", __func__);
1459 return ret;
1460 }
1461 }
Kever Yangfa437432017-02-22 16:56:35 +08001462
1463 /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
1464 clrbits_le32(&denali_phy[927], (1 << 22));
1465
1466 return 0;
1467}
1468
1469static void set_ddrconfig(const struct chan_info *chan,
Jagan Tekifde7f452019-07-15 23:50:58 +05301470 const struct rk3399_sdram_params *params,
Kever Yangfa437432017-02-22 16:56:35 +08001471 unsigned char channel, u32 ddrconfig)
1472{
1473 /* only need to set ddrconfig */
YouMin Chena922d0d2019-11-15 11:04:45 +08001474 struct msch_regs *ddr_msch_regs = chan->msch;
Kever Yangfa437432017-02-22 16:56:35 +08001475 unsigned int cs0_cap = 0;
1476 unsigned int cs1_cap = 0;
1477
Jagan Teki355490d2019-07-15 23:51:05 +05301478 cs0_cap = (1 << (params->ch[channel].cap_info.cs0_row
1479 + params->ch[channel].cap_info.col
1480 + params->ch[channel].cap_info.bk
1481 + params->ch[channel].cap_info.bw - 20));
1482 if (params->ch[channel].cap_info.rank > 1)
1483 cs1_cap = cs0_cap >> (params->ch[channel].cap_info.cs0_row
1484 - params->ch[channel].cap_info.cs1_row);
1485 if (params->ch[channel].cap_info.row_3_4) {
Kever Yangfa437432017-02-22 16:56:35 +08001486 cs0_cap = cs0_cap * 3 / 4;
1487 cs1_cap = cs1_cap * 3 / 4;
1488 }
1489
1490 writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
1491 writel(((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8),
1492 &ddr_msch_regs->ddrsize);
1493}
1494
YouMin Chena922d0d2019-11-15 11:04:45 +08001495static void sdram_msch_config(struct msch_regs *msch,
1496 struct sdram_msch_timings *noc_timings)
1497{
1498 writel(noc_timings->ddrtiminga0.d32,
1499 &msch->ddrtiminga0.d32);
1500 writel(noc_timings->ddrtimingb0.d32,
1501 &msch->ddrtimingb0.d32);
1502 writel(noc_timings->ddrtimingc0.d32,
1503 &msch->ddrtimingc0.d32);
1504 writel(noc_timings->devtodev0.d32,
1505 &msch->devtodev0.d32);
1506 writel(noc_timings->ddrmode.d32,
1507 &msch->ddrmode.d32);
1508}
1509
Kever Yangfa437432017-02-22 16:56:35 +08001510static void dram_all_config(struct dram_info *dram,
YouMin Chena922d0d2019-11-15 11:04:45 +08001511 struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001512{
Jagan Tekie0ddb0b2019-07-16 17:27:00 +05301513 u32 sys_reg2 = 0;
Jagan Teki01cc1032019-07-16 17:27:01 +05301514 u32 sys_reg3 = 0;
Kever Yangfa437432017-02-22 16:56:35 +08001515 unsigned int channel, idx;
1516
Kever Yangfa437432017-02-22 16:56:35 +08001517 for (channel = 0, idx = 0;
Jagan Tekifde7f452019-07-15 23:50:58 +05301518 (idx < params->base.num_channels) && (channel < 2);
Kever Yangfa437432017-02-22 16:56:35 +08001519 channel++) {
YouMin Chena922d0d2019-11-15 11:04:45 +08001520 struct msch_regs *ddr_msch_regs;
1521 struct sdram_msch_timings *noc_timing;
Kever Yangfa437432017-02-22 16:56:35 +08001522
Jagan Teki355490d2019-07-15 23:51:05 +05301523 if (params->ch[channel].cap_info.col == 0)
Kever Yangfa437432017-02-22 16:56:35 +08001524 continue;
1525 idx++;
YouMin Chena922d0d2019-11-15 11:04:45 +08001526 sdram_org_config(&params->ch[channel].cap_info,
1527 &params->base, &sys_reg2,
1528 &sys_reg3, channel);
Kever Yangfa437432017-02-22 16:56:35 +08001529 ddr_msch_regs = dram->chan[channel].msch;
Jagan Tekifde7f452019-07-15 23:50:58 +05301530 noc_timing = &params->ch[channel].noc_timings;
YouMin Chena922d0d2019-11-15 11:04:45 +08001531 sdram_msch_config(ddr_msch_regs, noc_timing);
Kever Yangfa437432017-02-22 16:56:35 +08001532
Jagan Teki74040982019-07-16 17:27:20 +05301533 /**
1534 * rank 1 memory clock disable (dfi_dram_clk_disable = 1)
1535 *
1536 * The hardware for LPDDR4 with
1537 * - CLK0P/N connect to lower 16-bits
1538 * - CLK1P/N connect to higher 16-bits
1539 *
1540 * dfi dram clk is configured via CLK1P/N, so disabling
1541 * dfi dram clk will disable the CLK1P/N as well for lpddr4.
1542 */
1543 if (params->ch[channel].cap_info.rank == 1 &&
1544 params->base.dramtype != LPDDR4)
Kever Yangfa437432017-02-22 16:56:35 +08001545 setbits_le32(&dram->chan[channel].pctl->denali_ctl[276],
1546 1 << 17);
1547 }
1548
Jagan Tekie0ddb0b2019-07-16 17:27:00 +05301549 writel(sys_reg2, &dram->pmugrf->os_reg2);
Jagan Teki01cc1032019-07-16 17:27:01 +05301550 writel(sys_reg3, &dram->pmugrf->os_reg3);
Kever Yangfa437432017-02-22 16:56:35 +08001551 rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10,
Jagan Tekifde7f452019-07-15 23:50:58 +05301552 params->base.stride << 10);
Kever Yangfa437432017-02-22 16:56:35 +08001553
1554 /* reboot hold register set */
1555 writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) |
1556 PRESET_GPIO1_HOLD(1),
1557 &dram->pmucru->pmucru_rstnhold_con[1]);
1558 clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
1559}
1560
Kever Yange0f907e2019-08-12 20:02:29 +08001561static void set_cap_relate_config(const struct chan_info *chan,
1562 struct rk3399_sdram_params *params,
1563 unsigned int channel)
1564{
1565 u32 *denali_ctl = chan->pctl->denali_ctl;
1566 u32 tmp;
YouMin Chena922d0d2019-11-15 11:04:45 +08001567 struct sdram_msch_timings *noc_timing;
Kever Yange0f907e2019-08-12 20:02:29 +08001568
1569 if (params->base.dramtype == LPDDR3) {
1570 tmp = (8 << params->ch[channel].cap_info.bw) /
1571 (8 << params->ch[channel].cap_info.dbw);
1572
1573 /**
1574 * memdata_ratio
1575 * 1 -> 0, 2 -> 1, 4 -> 2
1576 */
1577 clrsetbits_le32(&denali_ctl[197], 0x7,
1578 (tmp >> 1));
1579 clrsetbits_le32(&denali_ctl[198], 0x7 << 8,
1580 (tmp >> 1) << 8);
1581 }
1582
1583 noc_timing = &params->ch[channel].noc_timings;
1584
1585 /*
1586 * noc timing bw relate timing is 32 bit, and real bw is 16bit
1587 * actually noc reg is setting at function dram_all_config
1588 */
1589 if (params->ch[channel].cap_info.bw == 16 &&
1590 noc_timing->ddrmode.b.mwrsize == 2) {
1591 if (noc_timing->ddrmode.b.burstsize)
1592 noc_timing->ddrmode.b.burstsize -= 1;
1593 noc_timing->ddrmode.b.mwrsize -= 1;
1594 noc_timing->ddrtimingc0.b.burstpenalty *= 2;
1595 noc_timing->ddrtimingc0.b.wrtomwr *= 2;
1596 }
1597}
1598
1599static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
1600{
1601 unsigned int cs0_row = params->ch[channel].cap_info.cs0_row;
1602 unsigned int col = params->ch[channel].cap_info.col;
1603 unsigned int bw = params->ch[channel].cap_info.bw;
1604 u16 ddr_cfg_2_rbc[] = {
1605 /*
1606 * [6] highest bit col
1607 * [5:3] max row(14+n)
1608 * [2] insertion row
1609 * [1:0] col(9+n),col, data bus 32bit
1610 *
1611 * highbitcol, max_row, insertion_row, col
1612 */
1613 ((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */
1614 ((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */
1615 ((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */
1616 ((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */
1617 ((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */
1618 ((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */
1619 ((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */
1620 ((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */
1621 };
1622 u32 i;
1623
1624 col -= (bw == 2) ? 0 : 1;
1625 col -= 9;
1626
1627 for (i = 0; i < 4; i++) {
1628 if ((col == (ddr_cfg_2_rbc[i] & 0x3)) &&
1629 (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14)))
1630 break;
1631 }
1632
1633 if (i >= 4)
1634 i = -EINVAL;
1635
1636 return i;
1637}
1638
YouMin Chenf2b58f02019-11-15 11:04:49 +08001639static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
1640{
1641 rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
1642}
1643
Jagan Tekia0ded6d2019-07-16 17:27:31 +05301644#if !defined(CONFIG_RAM_RK3399_LPDDR4)
YouMin Chenf8088bf2019-11-15 11:04:46 +08001645static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
1646 struct rk3399_sdram_params *params)
Jagan Teki299deec2019-07-16 17:27:30 +05301647{
1648 u8 training_flag = PI_READ_GATE_TRAINING;
1649
1650 /*
1651 * LPDDR3 CA training msut be trigger before
1652 * other training.
1653 * DDR3 is not have CA training.
1654 */
1655
1656 if (params->base.dramtype == LPDDR3)
1657 training_flag |= PI_CA_TRAINING;
1658
1659 return data_training(dram, channel, params, training_flag);
1660}
1661
Kever Yangfa437432017-02-22 16:56:35 +08001662static int switch_to_phy_index1(struct dram_info *dram,
Jagan Tekic36abd02019-07-16 17:27:40 +05301663 struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08001664{
1665 u32 channel;
1666 u32 *denali_phy;
Jagan Tekifde7f452019-07-15 23:50:58 +05301667 u32 ch_count = params->base.num_channels;
Kever Yangfa437432017-02-22 16:56:35 +08001668 int ret;
1669 int i = 0;
1670
1671 writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
1672 1 << 4 | 1 << 2 | 1),
1673 &dram->cic->cic_ctrl0);
1674 while (!(readl(&dram->cic->cic_status0) & (1 << 2))) {
1675 mdelay(10);
1676 i++;
1677 if (i > 10) {
1678 debug("index1 frequency change overtime\n");
1679 return -ETIME;
1680 }
1681 }
1682
1683 i = 0;
1684 writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
1685 while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
1686 mdelay(10);
Heinrich Schuchardt2ebc80e2018-03-18 12:10:55 +01001687 i++;
Kever Yangfa437432017-02-22 16:56:35 +08001688 if (i > 10) {
1689 debug("index1 frequency done overtime\n");
1690 return -ETIME;
1691 }
1692 }
1693
1694 for (channel = 0; channel < ch_count; channel++) {
1695 denali_phy = dram->chan[channel].publ->denali_phy;
1696 clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
Jagan Tekie6ae37a2019-07-16 17:27:29 +05301697 ret = data_training(dram, channel, params, PI_FULL_TRAINING);
Jagan Teki02fad6f2019-07-15 23:58:39 +05301698 if (ret < 0) {
Kever Yangfa437432017-02-22 16:56:35 +08001699 debug("index1 training failed\n");
1700 return ret;
1701 }
1702 }
1703
1704 return 0;
1705}
1706
YouMin Chen0cacc272019-11-15 11:04:48 +08001707struct rk3399_sdram_params
1708 *get_phy_index_params(u32 phy_fn,
1709 struct rk3399_sdram_params *params)
1710{
1711 if (phy_fn == 0)
1712 return params;
1713 else
1714 return NULL;
1715}
1716
1717void modify_param(const struct chan_info *chan,
1718 struct rk3399_sdram_params *params)
1719{
1720 struct rk3399_sdram_params *params_cfg;
1721 u32 *denali_pi_params;
1722
1723 denali_pi_params = params->pi_regs.denali_pi;
1724
1725 /* modify PHY F0/F1/F2 params */
1726 params_cfg = get_phy_index_params(0, params);
1727 set_ds_odt(chan, params_cfg, false, 0);
1728
1729 clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
1730 clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
1731 clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
1732 clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
1733}
Jagan Teki1dd1cb62019-07-16 17:27:39 +05301734#else
1735
YouMin Chenf8088bf2019-11-15 11:04:46 +08001736struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
1737#include "sdram-rk3399-lpddr4-400.inc"
1738#include "sdram-rk3399-lpddr4-800.inc"
Jagan Tekic36abd02019-07-16 17:27:40 +05301739};
1740
YouMin Chen0cacc272019-11-15 11:04:48 +08001741static struct rk3399_sdram_params
1742 *lpddr4_get_phy_index_params(u32 phy_fn,
1743 struct rk3399_sdram_params *params)
1744{
1745 if (phy_fn == 0)
1746 return params;
1747 else if (phy_fn == 1)
1748 return &dfs_cfgs_lpddr4[1];
1749 else if (phy_fn == 2)
1750 return &dfs_cfgs_lpddr4[0];
1751 else
1752 return NULL;
1753}
1754
Jagan Tekic36abd02019-07-16 17:27:40 +05301755static void *get_denali_pi(const struct chan_info *chan,
1756 struct rk3399_sdram_params *params, bool reg)
1757{
1758 return reg ? &chan->pi->denali_pi : &params->pi_regs.denali_pi;
1759}
1760
YouMin Chenf8088bf2019-11-15 11:04:46 +08001761static u32 lpddr4_get_phy_fn(struct rk3399_sdram_params *params, u32 ctl_fn)
Jagan Tekic36abd02019-07-16 17:27:40 +05301762{
YouMin Chenf8088bf2019-11-15 11:04:46 +08001763 u32 lpddr4_phy_fn[] = {1, 0, 0xb};
Jagan Tekic36abd02019-07-16 17:27:40 +05301764
YouMin Chenf8088bf2019-11-15 11:04:46 +08001765 return lpddr4_phy_fn[ctl_fn];
Jagan Tekic36abd02019-07-16 17:27:40 +05301766}
1767
YouMin Chenf8088bf2019-11-15 11:04:46 +08001768static u32 lpddr4_get_ctl_fn(struct rk3399_sdram_params *params, u32 phy_fn)
Jagan Tekic36abd02019-07-16 17:27:40 +05301769{
YouMin Chenf8088bf2019-11-15 11:04:46 +08001770 u32 lpddr4_ctl_fn[] = {1, 0, 2};
Jagan Tekic36abd02019-07-16 17:27:40 +05301771
YouMin Chenf8088bf2019-11-15 11:04:46 +08001772 return lpddr4_ctl_fn[phy_fn];
Jagan Tekic36abd02019-07-16 17:27:40 +05301773}
1774
Jagan Tekia0ded6d2019-07-16 17:27:31 +05301775static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
1776{
1777 return ((readl(&pmusgrf->soc_con4) >> 10) & 0x1F);
1778}
1779
YouMin Chenf2b58f02019-11-15 11:04:49 +08001780/*
Jagan Tekia0ded6d2019-07-16 17:27:31 +05301781 * read mr_num mode register
1782 * rank = 1: cs0
1783 * rank = 2: cs1
1784 */
1785static int read_mr(struct rk3399_ddr_pctl_regs *ddr_pctl_regs, u32 rank,
1786 u32 mr_num, u32 *buf)
1787{
1788 s32 timeout = 100;
1789
1790 writel(((1 << 16) | (((rank == 2) ? 1 : 0) << 8) | mr_num) << 8,
1791 &ddr_pctl_regs->denali_ctl[118]);
1792
1793 while (0 == (readl(&ddr_pctl_regs->denali_ctl[203]) &
1794 ((1 << 21) | (1 << 12)))) {
1795 udelay(1);
1796
1797 if (timeout <= 0) {
1798 printf("%s: pctl timeout!\n", __func__);
1799 return -ETIMEDOUT;
1800 }
1801
1802 timeout--;
1803 }
1804
1805 if (!(readl(&ddr_pctl_regs->denali_ctl[203]) & (1 << 12))) {
1806 *buf = readl(&ddr_pctl_regs->denali_ctl[119]) & 0xFF;
1807 } else {
1808 printf("%s: read mr failed with 0x%x status\n", __func__,
1809 readl(&ddr_pctl_regs->denali_ctl[17]) & 0x3);
1810 *buf = 0;
1811 }
1812
1813 setbits_le32(&ddr_pctl_regs->denali_ctl[205], (1 << 21) | (1 << 12));
1814
1815 return 0;
1816}
1817
1818static int lpddr4_mr_detect(struct dram_info *dram, u32 channel, u8 rank,
1819 struct rk3399_sdram_params *params)
1820{
1821 u64 cs0_cap;
1822 u32 stride;
1823 u32 cs = 0, col = 0, bk = 0, bw = 0, row_3_4 = 0;
1824 u32 cs0_row = 0, cs1_row = 0, ddrconfig = 0;
1825 u32 mr5, mr12, mr14;
1826 struct chan_info *chan = &dram->chan[channel];
1827 struct rk3399_ddr_pctl_regs *ddr_pctl_regs = chan->pctl;
1828 void __iomem *addr = NULL;
1829 int ret = 0;
1830 u32 val;
1831
1832 stride = get_ddr_stride(dram->pmusgrf);
1833
1834 if (params->ch[channel].cap_info.col == 0) {
1835 ret = -EPERM;
1836 goto end;
1837 }
1838
1839 cs = params->ch[channel].cap_info.rank;
1840 col = params->ch[channel].cap_info.col;
1841 bk = params->ch[channel].cap_info.bk;
1842 bw = params->ch[channel].cap_info.bw;
1843 row_3_4 = params->ch[channel].cap_info.row_3_4;
1844 cs0_row = params->ch[channel].cap_info.cs0_row;
1845 cs1_row = params->ch[channel].cap_info.cs1_row;
1846 ddrconfig = params->ch[channel].cap_info.ddrconfig;
1847
1848 /* 2GB */
1849 params->ch[channel].cap_info.rank = 2;
1850 params->ch[channel].cap_info.col = 10;
1851 params->ch[channel].cap_info.bk = 3;
1852 params->ch[channel].cap_info.bw = 2;
1853 params->ch[channel].cap_info.row_3_4 = 0;
1854 params->ch[channel].cap_info.cs0_row = 15;
1855 params->ch[channel].cap_info.cs1_row = 15;
1856 params->ch[channel].cap_info.ddrconfig = 1;
1857
1858 set_memory_map(chan, channel, params);
1859 params->ch[channel].cap_info.ddrconfig =
1860 calculate_ddrconfig(params, channel);
1861 set_ddrconfig(chan, params, channel,
1862 params->ch[channel].cap_info.ddrconfig);
1863 set_cap_relate_config(chan, params, channel);
1864
1865 cs0_cap = (1 << (params->ch[channel].cap_info.bw
1866 + params->ch[channel].cap_info.col
1867 + params->ch[channel].cap_info.bk
1868 + params->ch[channel].cap_info.cs0_row));
1869
1870 if (params->ch[channel].cap_info.row_3_4)
1871 cs0_cap = cs0_cap * 3 / 4;
1872
1873 if (channel == 0)
1874 set_ddr_stride(dram->pmusgrf, 0x17);
1875 else
1876 set_ddr_stride(dram->pmusgrf, 0x18);
1877
1878 /* read and write data to DRAM, avoid be optimized by compiler. */
1879 if (rank == 1)
1880 addr = (void __iomem *)0x100;
1881 else if (rank == 2)
1882 addr = (void __iomem *)(cs0_cap + 0x100);
1883
1884 val = readl(addr);
1885 writel(val + 1, addr);
1886
1887 read_mr(ddr_pctl_regs, rank, 5, &mr5);
1888 read_mr(ddr_pctl_regs, rank, 12, &mr12);
1889 read_mr(ddr_pctl_regs, rank, 14, &mr14);
1890
1891 if (mr5 == 0 || mr12 != 0x4d || mr14 != 0x4d) {
1892 ret = -EINVAL;
1893 goto end;
1894 }
1895end:
1896 params->ch[channel].cap_info.rank = cs;
1897 params->ch[channel].cap_info.col = col;
1898 params->ch[channel].cap_info.bk = bk;
1899 params->ch[channel].cap_info.bw = bw;
1900 params->ch[channel].cap_info.row_3_4 = row_3_4;
1901 params->ch[channel].cap_info.cs0_row = cs0_row;
1902 params->ch[channel].cap_info.cs1_row = cs1_row;
1903 params->ch[channel].cap_info.ddrconfig = ddrconfig;
1904
1905 set_ddr_stride(dram->pmusgrf, stride);
1906
1907 return ret;
1908}
Jagan Tekic36abd02019-07-16 17:27:40 +05301909
1910static void set_lpddr4_dq_odt(const struct chan_info *chan,
YouMin Chenf8088bf2019-11-15 11:04:46 +08001911 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Tekic36abd02019-07-16 17:27:40 +05301912 bool en, bool ctl_phy_reg, u32 mr5)
1913{
1914 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
1915 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
1916 struct io_setting *io;
1917 u32 reg_value;
1918
Jagan Tekic36abd02019-07-16 17:27:40 +05301919 io = lpddr4_get_io_settings(params, mr5);
YouMin Chenf8088bf2019-11-15 11:04:46 +08001920 if (en)
1921 reg_value = io->dq_odt;
1922 else
1923 reg_value = 0;
Jagan Tekic36abd02019-07-16 17:27:40 +05301924
YouMin Chenf8088bf2019-11-15 11:04:46 +08001925 switch (ctl_fn) {
Jagan Tekic36abd02019-07-16 17:27:40 +05301926 case 0:
1927 clrsetbits_le32(&denali_ctl[139], 0x7 << 24, reg_value << 24);
1928 clrsetbits_le32(&denali_ctl[153], 0x7 << 24, reg_value << 24);
1929
1930 clrsetbits_le32(&denali_pi[132], 0x7 << 0, (reg_value << 0));
1931 clrsetbits_le32(&denali_pi[139], 0x7 << 16, (reg_value << 16));
1932 clrsetbits_le32(&denali_pi[147], 0x7 << 0, (reg_value << 0));
1933 clrsetbits_le32(&denali_pi[154], 0x7 << 16, (reg_value << 16));
1934 break;
1935 case 1:
1936 clrsetbits_le32(&denali_ctl[140], 0x7 << 0, reg_value << 0);
1937 clrsetbits_le32(&denali_ctl[154], 0x7 << 0, reg_value << 0);
1938
1939 clrsetbits_le32(&denali_pi[129], 0x7 << 16, (reg_value << 16));
1940 clrsetbits_le32(&denali_pi[137], 0x7 << 0, (reg_value << 0));
1941 clrsetbits_le32(&denali_pi[144], 0x7 << 16, (reg_value << 16));
1942 clrsetbits_le32(&denali_pi[152], 0x7 << 0, (reg_value << 0));
1943 break;
1944 case 2:
1945 default:
1946 clrsetbits_le32(&denali_ctl[140], 0x7 << 8, (reg_value << 8));
1947 clrsetbits_le32(&denali_ctl[154], 0x7 << 8, (reg_value << 8));
1948
1949 clrsetbits_le32(&denali_pi[127], 0x7 << 0, (reg_value << 0));
1950 clrsetbits_le32(&denali_pi[134], 0x7 << 16, (reg_value << 16));
1951 clrsetbits_le32(&denali_pi[142], 0x7 << 0, (reg_value << 0));
1952 clrsetbits_le32(&denali_pi[149], 0x7 << 16, (reg_value << 16));
1953 break;
1954 }
1955}
1956
1957static void set_lpddr4_ca_odt(const struct chan_info *chan,
YouMin Chenf8088bf2019-11-15 11:04:46 +08001958 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Tekic36abd02019-07-16 17:27:40 +05301959 bool en, bool ctl_phy_reg, u32 mr5)
1960{
1961 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
1962 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
1963 struct io_setting *io;
1964 u32 reg_value;
1965
Jagan Tekic36abd02019-07-16 17:27:40 +05301966 io = lpddr4_get_io_settings(params, mr5);
YouMin Chenf8088bf2019-11-15 11:04:46 +08001967 if (en)
1968 reg_value = io->ca_odt;
1969 else
1970 reg_value = 0;
Jagan Tekic36abd02019-07-16 17:27:40 +05301971
YouMin Chenf8088bf2019-11-15 11:04:46 +08001972 switch (ctl_fn) {
Jagan Tekic36abd02019-07-16 17:27:40 +05301973 case 0:
1974 clrsetbits_le32(&denali_ctl[139], 0x7 << 28, reg_value << 28);
1975 clrsetbits_le32(&denali_ctl[153], 0x7 << 28, reg_value << 28);
1976
1977 clrsetbits_le32(&denali_pi[132], 0x7 << 4, reg_value << 4);
1978 clrsetbits_le32(&denali_pi[139], 0x7 << 20, reg_value << 20);
1979 clrsetbits_le32(&denali_pi[147], 0x7 << 4, reg_value << 4);
1980 clrsetbits_le32(&denali_pi[154], 0x7 << 20, reg_value << 20);
1981 break;
1982 case 1:
1983 clrsetbits_le32(&denali_ctl[140], 0x7 << 4, reg_value << 4);
1984 clrsetbits_le32(&denali_ctl[154], 0x7 << 4, reg_value << 4);
1985
1986 clrsetbits_le32(&denali_pi[129], 0x7 << 20, reg_value << 20);
1987 clrsetbits_le32(&denali_pi[137], 0x7 << 4, reg_value << 4);
1988 clrsetbits_le32(&denali_pi[144], 0x7 << 20, reg_value << 20);
1989 clrsetbits_le32(&denali_pi[152], 0x7 << 4, reg_value << 4);
1990 break;
1991 case 2:
1992 default:
1993 clrsetbits_le32(&denali_ctl[140], 0x7 << 12, (reg_value << 12));
1994 clrsetbits_le32(&denali_ctl[154], 0x7 << 12, (reg_value << 12));
1995
1996 clrsetbits_le32(&denali_pi[127], 0x7 << 4, reg_value << 4);
1997 clrsetbits_le32(&denali_pi[134], 0x7 << 20, reg_value << 20);
1998 clrsetbits_le32(&denali_pi[142], 0x7 << 4, reg_value << 4);
1999 clrsetbits_le32(&denali_pi[149], 0x7 << 20, reg_value << 20);
2000 break;
2001 }
2002}
2003
2004static void set_lpddr4_MR3(const struct chan_info *chan,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002005 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Tekic36abd02019-07-16 17:27:40 +05302006 bool ctl_phy_reg, u32 mr5)
2007{
2008 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
2009 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
2010 struct io_setting *io;
2011 u32 reg_value;
2012
2013 io = lpddr4_get_io_settings(params, mr5);
2014
2015 reg_value = ((io->pdds << 3) | 1);
2016
YouMin Chenf8088bf2019-11-15 11:04:46 +08002017 switch (ctl_fn) {
Jagan Tekic36abd02019-07-16 17:27:40 +05302018 case 0:
2019 clrsetbits_le32(&denali_ctl[138], 0xFFFF, reg_value);
2020 clrsetbits_le32(&denali_ctl[152], 0xFFFF, reg_value);
2021
2022 clrsetbits_le32(&denali_pi[131], 0xFFFF << 16, reg_value << 16);
2023 clrsetbits_le32(&denali_pi[139], 0xFFFF, reg_value);
2024 clrsetbits_le32(&denali_pi[146], 0xFFFF << 16, reg_value << 16);
2025 clrsetbits_le32(&denali_pi[154], 0xFFFF, reg_value);
2026 break;
2027 case 1:
2028 clrsetbits_le32(&denali_ctl[138], 0xFFFF << 16,
2029 reg_value << 16);
2030 clrsetbits_le32(&denali_ctl[152], 0xFFFF << 16,
2031 reg_value << 16);
2032
2033 clrsetbits_le32(&denali_pi[129], 0xFFFF, reg_value);
2034 clrsetbits_le32(&denali_pi[136], 0xFFFF << 16, reg_value << 16);
2035 clrsetbits_le32(&denali_pi[144], 0xFFFF, reg_value);
2036 clrsetbits_le32(&denali_pi[151], 0xFFFF << 16, reg_value << 16);
2037 break;
2038 case 2:
2039 default:
2040 clrsetbits_le32(&denali_ctl[139], 0xFFFF, reg_value);
2041 clrsetbits_le32(&denali_ctl[153], 0xFFFF, reg_value);
2042
2043 clrsetbits_le32(&denali_pi[126], 0xFFFF << 16, reg_value << 16);
2044 clrsetbits_le32(&denali_pi[134], 0xFFFF, reg_value);
2045 clrsetbits_le32(&denali_pi[141], 0xFFFF << 16, reg_value << 16);
2046 clrsetbits_le32(&denali_pi[149], 0xFFFF, reg_value);
2047 break;
2048 }
2049}
2050
2051static void set_lpddr4_MR12(const struct chan_info *chan,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002052 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Tekic36abd02019-07-16 17:27:40 +05302053 bool ctl_phy_reg, u32 mr5)
2054{
2055 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
2056 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
2057 struct io_setting *io;
2058 u32 reg_value;
2059
2060 io = lpddr4_get_io_settings(params, mr5);
2061
2062 reg_value = io->ca_vref;
2063
YouMin Chenf8088bf2019-11-15 11:04:46 +08002064 switch (ctl_fn) {
Jagan Tekic36abd02019-07-16 17:27:40 +05302065 case 0:
2066 clrsetbits_le32(&denali_ctl[140], 0xFFFF << 16,
2067 reg_value << 16);
2068 clrsetbits_le32(&denali_ctl[154], 0xFFFF << 16,
2069 reg_value << 16);
2070
2071 clrsetbits_le32(&denali_pi[132], 0xFF << 8, reg_value << 8);
2072 clrsetbits_le32(&denali_pi[139], 0xFF << 24, reg_value << 24);
2073 clrsetbits_le32(&denali_pi[147], 0xFF << 8, reg_value << 8);
2074 clrsetbits_le32(&denali_pi[154], 0xFF << 24, reg_value << 24);
2075 break;
2076 case 1:
2077 clrsetbits_le32(&denali_ctl[141], 0xFFFF, reg_value);
2078 clrsetbits_le32(&denali_ctl[155], 0xFFFF, reg_value);
2079
2080 clrsetbits_le32(&denali_pi[129], 0xFF << 24, reg_value << 24);
2081 clrsetbits_le32(&denali_pi[137], 0xFF << 8, reg_value << 8);
2082 clrsetbits_le32(&denali_pi[144], 0xFF << 24, reg_value << 24);
2083 clrsetbits_le32(&denali_pi[152], 0xFF << 8, reg_value << 8);
2084 break;
2085 case 2:
2086 default:
2087 clrsetbits_le32(&denali_ctl[141], 0xFFFF << 16,
2088 reg_value << 16);
2089 clrsetbits_le32(&denali_ctl[155], 0xFFFF << 16,
2090 reg_value << 16);
2091
2092 clrsetbits_le32(&denali_pi[127], 0xFF << 8, reg_value << 8);
2093 clrsetbits_le32(&denali_pi[134], 0xFF << 24, reg_value << 24);
2094 clrsetbits_le32(&denali_pi[142], 0xFF << 8, reg_value << 8);
2095 clrsetbits_le32(&denali_pi[149], 0xFF << 24, reg_value << 24);
2096 break;
2097 }
2098}
2099
2100static void set_lpddr4_MR14(const struct chan_info *chan,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002101 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Tekic36abd02019-07-16 17:27:40 +05302102 bool ctl_phy_reg, u32 mr5)
2103{
2104 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
2105 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
2106 struct io_setting *io;
2107 u32 reg_value;
2108
2109 io = lpddr4_get_io_settings(params, mr5);
2110
2111 reg_value = io->dq_vref;
2112
YouMin Chenf8088bf2019-11-15 11:04:46 +08002113 switch (ctl_fn) {
Jagan Tekic36abd02019-07-16 17:27:40 +05302114 case 0:
2115 clrsetbits_le32(&denali_ctl[142], 0xFFFF << 16,
2116 reg_value << 16);
2117 clrsetbits_le32(&denali_ctl[156], 0xFFFF << 16,
2118 reg_value << 16);
2119
2120 clrsetbits_le32(&denali_pi[132], 0xFF << 16, reg_value << 16);
2121 clrsetbits_le32(&denali_pi[140], 0xFF << 0, reg_value << 0);
2122 clrsetbits_le32(&denali_pi[147], 0xFF << 16, reg_value << 16);
2123 clrsetbits_le32(&denali_pi[155], 0xFF << 0, reg_value << 0);
2124 break;
2125 case 1:
2126 clrsetbits_le32(&denali_ctl[143], 0xFFFF, reg_value);
2127 clrsetbits_le32(&denali_ctl[157], 0xFFFF, reg_value);
2128
2129 clrsetbits_le32(&denali_pi[130], 0xFF << 0, reg_value << 0);
2130 clrsetbits_le32(&denali_pi[137], 0xFF << 16, reg_value << 16);
2131 clrsetbits_le32(&denali_pi[145], 0xFF << 0, reg_value << 0);
2132 clrsetbits_le32(&denali_pi[152], 0xFF << 16, reg_value << 16);
2133 break;
2134 case 2:
2135 default:
2136 clrsetbits_le32(&denali_ctl[143], 0xFFFF << 16,
2137 reg_value << 16);
2138 clrsetbits_le32(&denali_ctl[157], 0xFFFF << 16,
2139 reg_value << 16);
2140
2141 clrsetbits_le32(&denali_pi[127], 0xFF << 16, reg_value << 16);
2142 clrsetbits_le32(&denali_pi[135], 0xFF << 0, reg_value << 0);
2143 clrsetbits_le32(&denali_pi[142], 0xFF << 16, reg_value << 16);
2144 clrsetbits_le32(&denali_pi[150], 0xFF << 0, reg_value << 0);
2145 break;
2146 }
2147}
2148
YouMin Chen0cacc272019-11-15 11:04:48 +08002149void lpddr4_modify_param(const struct chan_info *chan,
2150 struct rk3399_sdram_params *params)
2151{
2152 struct rk3399_sdram_params *params_cfg;
2153 u32 *denali_ctl_params;
2154 u32 *denali_pi_params;
2155 u32 *denali_phy_params;
2156
2157 denali_ctl_params = params->pctl_regs.denali_ctl;
2158 denali_pi_params = params->pi_regs.denali_pi;
2159 denali_phy_params = params->phy_regs.denali_phy;
2160
2161 set_lpddr4_dq_odt(chan, params, 2, true, false, 0);
2162 set_lpddr4_ca_odt(chan, params, 2, true, false, 0);
2163 set_lpddr4_MR3(chan, params, 2, false, 0);
2164 set_lpddr4_MR12(chan, params, 2, false, 0);
2165 set_lpddr4_MR14(chan, params, 2, false, 0);
2166 params_cfg = lpddr4_get_phy_index_params(0, params);
2167 set_ds_odt(chan, params_cfg, false, 0);
2168 /* read two cycle preamble */
2169 clrsetbits_le32(&denali_ctl_params[200], 0x3 << 24, 0x3 << 24);
2170 clrsetbits_le32(&denali_phy_params[7], 0x3 << 24, 0x3 << 24);
2171 clrsetbits_le32(&denali_phy_params[135], 0x3 << 24, 0x3 << 24);
2172 clrsetbits_le32(&denali_phy_params[263], 0x3 << 24, 0x3 << 24);
2173 clrsetbits_le32(&denali_phy_params[391], 0x3 << 24, 0x3 << 24);
2174
2175 /* boot frequency two cycle preamble */
2176 clrsetbits_le32(&denali_phy_params[2], 0x3 << 16, 0x3 << 16);
2177 clrsetbits_le32(&denali_phy_params[130], 0x3 << 16, 0x3 << 16);
2178 clrsetbits_le32(&denali_phy_params[258], 0x3 << 16, 0x3 << 16);
2179 clrsetbits_le32(&denali_phy_params[386], 0x3 << 16, 0x3 << 16);
2180
2181 clrsetbits_le32(&denali_pi_params[45], 0x3 << 8, 0x3 << 8);
2182 clrsetbits_le32(&denali_pi_params[58], 0x1, 0x1);
2183
2184 /*
2185 * bypass mode need PHY_SLICE_PWR_RDC_DISABLE_x = 1,
2186 * boot frequency mode use bypass mode
2187 */
2188 setbits_le32(&denali_phy_params[10], 1 << 16);
2189 setbits_le32(&denali_phy_params[138], 1 << 16);
2190 setbits_le32(&denali_phy_params[266], 1 << 16);
2191 setbits_le32(&denali_phy_params[394], 1 << 16);
2192
2193 clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
2194 clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
2195 clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
2196 clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
2197}
2198
Jagan Tekic36abd02019-07-16 17:27:40 +05302199static void lpddr4_copy_phy(struct dram_info *dram,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002200 struct rk3399_sdram_params *params, u32 phy_fn,
2201 struct rk3399_sdram_params *params_cfg,
Jagan Tekic36abd02019-07-16 17:27:40 +05302202 u32 channel)
2203{
2204 u32 *denali_ctl, *denali_phy;
2205 u32 *denali_phy_params;
2206 u32 speed = 0;
YouMin Chenf8088bf2019-11-15 11:04:46 +08002207 u32 ctl_fn, mr5;
Jagan Tekic36abd02019-07-16 17:27:40 +05302208
2209 denali_ctl = dram->chan[channel].pctl->denali_ctl;
2210 denali_phy = dram->chan[channel].publ->denali_phy;
YouMin Chenf8088bf2019-11-15 11:04:46 +08002211 denali_phy_params = params_cfg->phy_regs.denali_phy;
Jagan Tekic36abd02019-07-16 17:27:40 +05302212
2213 /* switch index */
YouMin Chenf8088bf2019-11-15 11:04:46 +08002214 clrsetbits_le32(&denali_phy_params[896], 0x3 << 8,
2215 phy_fn << 8);
Jagan Tekic36abd02019-07-16 17:27:40 +05302216 writel(denali_phy_params[896], &denali_phy[896]);
2217
2218 /* phy_pll_ctrl_ca, phy_pll_ctrl */
2219 writel(denali_phy_params[911], &denali_phy[911]);
2220
2221 /* phy_low_freq_sel */
2222 clrsetbits_le32(&denali_phy[913], 0x1,
2223 denali_phy_params[913] & 0x1);
2224
2225 /* phy_grp_slave_delay_x, phy_cslvl_dly_step */
2226 writel(denali_phy_params[916], &denali_phy[916]);
2227 writel(denali_phy_params[917], &denali_phy[917]);
2228 writel(denali_phy_params[918], &denali_phy[918]);
2229
2230 /* phy_adrz_sw_wraddr_shift_x */
2231 writel(denali_phy_params[512], &denali_phy[512]);
2232 clrsetbits_le32(&denali_phy[513], 0xffff,
2233 denali_phy_params[513] & 0xffff);
2234 writel(denali_phy_params[640], &denali_phy[640]);
2235 clrsetbits_le32(&denali_phy[641], 0xffff,
2236 denali_phy_params[641] & 0xffff);
2237 writel(denali_phy_params[768], &denali_phy[768]);
2238 clrsetbits_le32(&denali_phy[769], 0xffff,
2239 denali_phy_params[769] & 0xffff);
2240
2241 writel(denali_phy_params[544], &denali_phy[544]);
2242 writel(denali_phy_params[545], &denali_phy[545]);
2243 writel(denali_phy_params[546], &denali_phy[546]);
2244 writel(denali_phy_params[547], &denali_phy[547]);
2245
2246 writel(denali_phy_params[672], &denali_phy[672]);
2247 writel(denali_phy_params[673], &denali_phy[673]);
2248 writel(denali_phy_params[674], &denali_phy[674]);
2249 writel(denali_phy_params[675], &denali_phy[675]);
2250
2251 writel(denali_phy_params[800], &denali_phy[800]);
2252 writel(denali_phy_params[801], &denali_phy[801]);
2253 writel(denali_phy_params[802], &denali_phy[802]);
2254 writel(denali_phy_params[803], &denali_phy[803]);
2255
2256 /*
2257 * phy_adr_master_delay_start_x
2258 * phy_adr_master_delay_step_x
2259 * phy_adr_master_delay_wait_x
2260 */
2261 writel(denali_phy_params[548], &denali_phy[548]);
2262 writel(denali_phy_params[676], &denali_phy[676]);
2263 writel(denali_phy_params[804], &denali_phy[804]);
2264
2265 /* phy_adr_calvl_dly_step_x */
2266 writel(denali_phy_params[549], &denali_phy[549]);
2267 writel(denali_phy_params[677], &denali_phy[677]);
2268 writel(denali_phy_params[805], &denali_phy[805]);
2269
2270 /*
2271 * phy_clk_wrdm_slave_delay_x
2272 * phy_clk_wrdqz_slave_delay_x
2273 * phy_clk_wrdqs_slave_delay_x
2274 */
YouMin Chena922d0d2019-11-15 11:04:45 +08002275 sdram_copy_to_reg((u32 *)&denali_phy[59],
2276 (u32 *)&denali_phy_params[59], (63 - 58) * 4);
2277 sdram_copy_to_reg((u32 *)&denali_phy[187],
2278 (u32 *)&denali_phy_params[187], (191 - 186) * 4);
2279 sdram_copy_to_reg((u32 *)&denali_phy[315],
2280 (u32 *)&denali_phy_params[315], (319 - 314) * 4);
2281 sdram_copy_to_reg((u32 *)&denali_phy[443],
2282 (u32 *)&denali_phy_params[443], (447 - 442) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302283
2284 /*
2285 * phy_dqs_tsel_wr_timing_x 8bits denali_phy_84/212/340/468 offset_8
2286 * dqs_tsel_wr_end[7:4] add half cycle
2287 * phy_dq_tsel_wr_timing_x 8bits denali_phy_83/211/339/467 offset_8
2288 * dq_tsel_wr_end[7:4] add half cycle
2289 */
2290 writel(denali_phy_params[83] + (0x10 << 16), &denali_phy[83]);
2291 writel(denali_phy_params[84] + (0x10 << 8), &denali_phy[84]);
2292 writel(denali_phy_params[85], &denali_phy[85]);
2293
2294 writel(denali_phy_params[211] + (0x10 << 16), &denali_phy[211]);
2295 writel(denali_phy_params[212] + (0x10 << 8), &denali_phy[212]);
2296 writel(denali_phy_params[213], &denali_phy[213]);
2297
2298 writel(denali_phy_params[339] + (0x10 << 16), &denali_phy[339]);
2299 writel(denali_phy_params[340] + (0x10 << 8), &denali_phy[340]);
2300 writel(denali_phy_params[341], &denali_phy[341]);
2301
2302 writel(denali_phy_params[467] + (0x10 << 16), &denali_phy[467]);
2303 writel(denali_phy_params[468] + (0x10 << 8), &denali_phy[468]);
2304 writel(denali_phy_params[469], &denali_phy[469]);
2305
2306 /*
2307 * phy_gtlvl_resp_wait_cnt_x
2308 * phy_gtlvl_dly_step_x
2309 * phy_wrlvl_resp_wait_cnt_x
2310 * phy_gtlvl_final_step_x
2311 * phy_gtlvl_back_step_x
2312 * phy_rdlvl_dly_step_x
2313 *
2314 * phy_master_delay_step_x
2315 * phy_master_delay_wait_x
2316 * phy_wrlvl_dly_step_x
2317 * phy_rptr_update_x
2318 * phy_wdqlvl_dly_step_x
2319 */
2320 writel(denali_phy_params[87], &denali_phy[87]);
2321 writel(denali_phy_params[88], &denali_phy[88]);
2322 writel(denali_phy_params[89], &denali_phy[89]);
2323 writel(denali_phy_params[90], &denali_phy[90]);
2324
2325 writel(denali_phy_params[215], &denali_phy[215]);
2326 writel(denali_phy_params[216], &denali_phy[216]);
2327 writel(denali_phy_params[217], &denali_phy[217]);
2328 writel(denali_phy_params[218], &denali_phy[218]);
2329
2330 writel(denali_phy_params[343], &denali_phy[343]);
2331 writel(denali_phy_params[344], &denali_phy[344]);
2332 writel(denali_phy_params[345], &denali_phy[345]);
2333 writel(denali_phy_params[346], &denali_phy[346]);
2334
2335 writel(denali_phy_params[471], &denali_phy[471]);
2336 writel(denali_phy_params[472], &denali_phy[472]);
2337 writel(denali_phy_params[473], &denali_phy[473]);
2338 writel(denali_phy_params[474], &denali_phy[474]);
2339
2340 /*
2341 * phy_gtlvl_lat_adj_start_x
2342 * phy_gtlvl_rddqs_slv_dly_start_x
2343 * phy_rdlvl_rddqs_dq_slv_dly_start_x
2344 * phy_wdqlvl_dqdm_slv_dly_start_x
2345 */
2346 writel(denali_phy_params[80], &denali_phy[80]);
2347 writel(denali_phy_params[81], &denali_phy[81]);
2348
2349 writel(denali_phy_params[208], &denali_phy[208]);
2350 writel(denali_phy_params[209], &denali_phy[209]);
2351
2352 writel(denali_phy_params[336], &denali_phy[336]);
2353 writel(denali_phy_params[337], &denali_phy[337]);
2354
2355 writel(denali_phy_params[464], &denali_phy[464]);
2356 writel(denali_phy_params[465], &denali_phy[465]);
2357
2358 /*
2359 * phy_master_delay_start_x
2360 * phy_sw_master_mode_x
2361 * phy_rddata_en_tsel_dly_x
2362 */
2363 writel(denali_phy_params[86], &denali_phy[86]);
2364 writel(denali_phy_params[214], &denali_phy[214]);
2365 writel(denali_phy_params[342], &denali_phy[342]);
2366 writel(denali_phy_params[470], &denali_phy[470]);
2367
2368 /*
2369 * phy_rddqz_slave_delay_x
2370 * phy_rddqs_dqz_fall_slave_delay_x
2371 * phy_rddqs_dqz_rise_slave_delay_x
2372 * phy_rddqs_dm_fall_slave_delay_x
2373 * phy_rddqs_dm_rise_slave_delay_x
2374 * phy_rddqs_gate_slave_delay_x
2375 * phy_wrlvl_delay_early_threshold_x
2376 * phy_write_path_lat_add_x
2377 * phy_rddqs_latency_adjust_x
2378 * phy_wrlvl_delay_period_threshold_x
2379 * phy_wrlvl_early_force_zero_x
2380 */
YouMin Chena922d0d2019-11-15 11:04:45 +08002381 sdram_copy_to_reg((u32 *)&denali_phy[64],
2382 (u32 *)&denali_phy_params[64], (67 - 63) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302383 clrsetbits_le32(&denali_phy[68], 0xfffffc00,
2384 denali_phy_params[68] & 0xfffffc00);
YouMin Chena922d0d2019-11-15 11:04:45 +08002385 sdram_copy_to_reg((u32 *)&denali_phy[69],
2386 (u32 *)&denali_phy_params[69], (79 - 68) * 4);
2387 sdram_copy_to_reg((u32 *)&denali_phy[192],
2388 (u32 *)&denali_phy_params[192], (195 - 191) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302389 clrsetbits_le32(&denali_phy[196], 0xfffffc00,
2390 denali_phy_params[196] & 0xfffffc00);
YouMin Chena922d0d2019-11-15 11:04:45 +08002391 sdram_copy_to_reg((u32 *)&denali_phy[197],
2392 (u32 *)&denali_phy_params[197], (207 - 196) * 4);
2393 sdram_copy_to_reg((u32 *)&denali_phy[320],
2394 (u32 *)&denali_phy_params[320], (323 - 319) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302395 clrsetbits_le32(&denali_phy[324], 0xfffffc00,
2396 denali_phy_params[324] & 0xfffffc00);
YouMin Chena922d0d2019-11-15 11:04:45 +08002397 sdram_copy_to_reg((u32 *)&denali_phy[325],
2398 (u32 *)&denali_phy_params[325], (335 - 324) * 4);
2399 sdram_copy_to_reg((u32 *)&denali_phy[448],
2400 (u32 *)&denali_phy_params[448], (451 - 447) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302401 clrsetbits_le32(&denali_phy[452], 0xfffffc00,
2402 denali_phy_params[452] & 0xfffffc00);
YouMin Chena922d0d2019-11-15 11:04:45 +08002403 sdram_copy_to_reg((u32 *)&denali_phy[453],
2404 (u32 *)&denali_phy_params[453], (463 - 452) * 4);
Jagan Tekic36abd02019-07-16 17:27:40 +05302405
2406 /* phy_two_cyc_preamble_x */
2407 clrsetbits_le32(&denali_phy[7], 0x3 << 24,
2408 denali_phy_params[7] & (0x3 << 24));
2409 clrsetbits_le32(&denali_phy[135], 0x3 << 24,
2410 denali_phy_params[135] & (0x3 << 24));
2411 clrsetbits_le32(&denali_phy[263], 0x3 << 24,
2412 denali_phy_params[263] & (0x3 << 24));
2413 clrsetbits_le32(&denali_phy[391], 0x3 << 24,
2414 denali_phy_params[391] & (0x3 << 24));
2415
2416 /* speed */
YouMin Chenf8088bf2019-11-15 11:04:46 +08002417 if (params_cfg->base.ddr_freq < 400)
Jagan Tekic36abd02019-07-16 17:27:40 +05302418 speed = 0x0;
YouMin Chenf8088bf2019-11-15 11:04:46 +08002419 else if (params_cfg->base.ddr_freq < 800)
Jagan Tekic36abd02019-07-16 17:27:40 +05302420 speed = 0x1;
YouMin Chenf8088bf2019-11-15 11:04:46 +08002421 else if (params_cfg->base.ddr_freq < 1200)
Jagan Tekic36abd02019-07-16 17:27:40 +05302422 speed = 0x2;
2423
2424 /* phy_924 phy_pad_fdbk_drive */
2425 clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
2426 /* phy_926 phy_pad_data_drive */
2427 clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
2428 /* phy_927 phy_pad_dqs_drive */
2429 clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
2430 /* phy_928 phy_pad_addr_drive */
2431 clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
2432 /* phy_929 phy_pad_clk_drive */
2433 clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
2434 /* phy_935 phy_pad_cke_drive */
2435 clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
2436 /* phy_937 phy_pad_rst_drive */
2437 clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
2438 /* phy_939 phy_pad_cs_drive */
2439 clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
2440
YouMin Chen0cacc272019-11-15 11:04:48 +08002441 if (params_cfg->base.dramtype == LPDDR4) {
2442 read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
2443 set_ds_odt(&dram->chan[channel], params_cfg, true, mr5);
Jagan Tekic36abd02019-07-16 17:27:40 +05302444
YouMin Chen0cacc272019-11-15 11:04:48 +08002445 ctl_fn = lpddr4_get_ctl_fn(params_cfg, phy_fn);
2446 set_lpddr4_dq_odt(&dram->chan[channel], params_cfg,
2447 ctl_fn, true, true, mr5);
2448 set_lpddr4_ca_odt(&dram->chan[channel], params_cfg,
2449 ctl_fn, true, true, mr5);
2450 set_lpddr4_MR3(&dram->chan[channel], params_cfg,
2451 ctl_fn, true, mr5);
2452 set_lpddr4_MR12(&dram->chan[channel], params_cfg,
2453 ctl_fn, true, mr5);
2454 set_lpddr4_MR14(&dram->chan[channel], params_cfg,
2455 ctl_fn, true, mr5);
Jagan Tekic36abd02019-07-16 17:27:40 +05302456
YouMin Chen0cacc272019-11-15 11:04:48 +08002457 /*
2458 * if phy_sw_master_mode_x not bypass mode,
2459 * clear phy_slice_pwr_rdc_disable.
2460 * note: need use timings, not ddr_publ_regs
2461 */
2462 if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
2463 clrbits_le32(&denali_phy[10], 1 << 16);
2464 clrbits_le32(&denali_phy[138], 1 << 16);
2465 clrbits_le32(&denali_phy[266], 1 << 16);
2466 clrbits_le32(&denali_phy[394], 1 << 16);
2467 }
Jagan Tekic36abd02019-07-16 17:27:40 +05302468
YouMin Chen0cacc272019-11-15 11:04:48 +08002469 /*
2470 * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
2471 * smaller than 8
2472 * NOTE: need use timings, not ddr_publ_regs
2473 */
2474 if ((denali_phy_params[84] >> 16) & 1) {
2475 if (((readl(&denali_ctl[217 + ctl_fn]) >>
2476 16) & 0x1f) < 8)
2477 clrsetbits_le32(&denali_ctl[217 + ctl_fn],
2478 0x1f << 16,
2479 8 << 16);
2480 }
Jagan Tekic36abd02019-07-16 17:27:40 +05302481 }
2482}
2483
2484static void lpddr4_set_phy(struct dram_info *dram,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002485 struct rk3399_sdram_params *params, u32 phy_fn,
2486 struct rk3399_sdram_params *params_cfg)
Jagan Tekic36abd02019-07-16 17:27:40 +05302487{
2488 u32 channel;
2489
2490 for (channel = 0; channel < 2; channel++)
YouMin Chenf8088bf2019-11-15 11:04:46 +08002491 lpddr4_copy_phy(dram, params, phy_fn, params_cfg,
2492 channel);
Jagan Tekic36abd02019-07-16 17:27:40 +05302493}
2494
2495static int lpddr4_set_ctl(struct dram_info *dram,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002496 struct rk3399_sdram_params *params,
2497 u32 fn, u32 hz)
Jagan Tekic36abd02019-07-16 17:27:40 +05302498{
2499 u32 channel;
2500 int ret_clk, ret;
2501
2502 /* cci idle req stall */
2503 writel(0x70007, &dram->grf->soc_con0);
2504
2505 /* enable all clk */
2506 setbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
2507
2508 /* idle */
2509 setbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
2510 while ((readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
2511 != (0x3 << 18))
2512 ;
2513
2514 /* change freq */
2515 writel((((0x3 << 4) | (1 << 2) | 1) << 16) |
YouMin Chenf8088bf2019-11-15 11:04:46 +08002516 (fn << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
Jagan Tekic36abd02019-07-16 17:27:40 +05302517 while (!(readl(&dram->cic->cic_status0) & (1 << 2)))
2518 ;
2519
2520 ret_clk = clk_set_rate(&dram->ddr_clk, hz);
2521 if (ret_clk < 0) {
2522 printf("%s clk set failed %d\n", __func__, ret_clk);
2523 return ret_clk;
2524 }
2525
2526 writel(0x20002, &dram->cic->cic_ctrl0);
2527 while (!(readl(&dram->cic->cic_status0) & (1 << 0)))
2528 ;
2529
2530 /* deidle */
2531 clrbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
2532 while (readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
2533 ;
2534
2535 /* clear enable all clk */
2536 clrbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
2537
2538 /* lpddr4 ctl2 can not do training, all training will fail */
YouMin Chenf8088bf2019-11-15 11:04:46 +08002539 if (!(params->base.dramtype == LPDDR4 && fn == 2)) {
Jagan Tekic36abd02019-07-16 17:27:40 +05302540 for (channel = 0; channel < 2; channel++) {
2541 if (!(params->ch[channel].cap_info.col))
2542 continue;
2543 ret = data_training(dram, channel, params,
YouMin Chenf8088bf2019-11-15 11:04:46 +08002544 PI_FULL_TRAINING);
Jagan Tekic36abd02019-07-16 17:27:40 +05302545 if (ret)
2546 printf("%s: channel %d training failed!\n",
2547 __func__, channel);
2548 else
2549 debug("%s: channel %d training pass\n",
2550 __func__, channel);
2551 }
2552 }
2553
2554 return 0;
2555}
2556
2557static int lpddr4_set_rate(struct dram_info *dram,
2558 struct rk3399_sdram_params *params)
2559{
YouMin Chenf8088bf2019-11-15 11:04:46 +08002560 u32 ctl_fn;
2561 u32 phy_fn;
Jagan Tekic36abd02019-07-16 17:27:40 +05302562
YouMin Chenf8088bf2019-11-15 11:04:46 +08002563 for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
2564 phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
Jagan Tekic36abd02019-07-16 17:27:40 +05302565
YouMin Chenf8088bf2019-11-15 11:04:46 +08002566 lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
2567 lpddr4_set_ctl(dram, params, ctl_fn,
2568 dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
Jagan Tekic36abd02019-07-16 17:27:40 +05302569
YouMin Chenf8088bf2019-11-15 11:04:46 +08002570 printf("%s: change freq to %d mhz %d, %d\n", __func__,
2571 dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, ctl_fn, phy_fn);
Jagan Tekic36abd02019-07-16 17:27:40 +05302572 }
2573
2574 return 0;
2575}
Jagan Tekia0ded6d2019-07-16 17:27:31 +05302576#endif /* CONFIG_RAM_RK3399_LPDDR4 */
2577
YouMin Chenf2b58f02019-11-15 11:04:49 +08002578/* CS0,n=1
2579 * CS1,n=2
2580 * CS0 & CS1, n=3
2581 * cs0_cap: MB unit
2582 */
2583static void dram_set_cs(const struct chan_info *chan, u32 cs_map, u32 cs0_cap,
2584 unsigned char dramtype)
2585{
2586 u32 *denali_ctl = chan->pctl->denali_ctl;
2587 u32 *denali_pi = chan->pi->denali_pi;
2588 struct msch_regs *ddr_msch_regs = chan->msch;
2589
2590 clrsetbits_le32(&denali_ctl[196], 0x3, cs_map);
2591 writel((cs0_cap / 32) | (((4096 - cs0_cap) / 32) << 8),
2592 &ddr_msch_regs->ddrsize);
2593 if (dramtype == LPDDR4) {
2594 if (cs_map == 1)
2595 cs_map = 0x5;
2596 else if (cs_map == 2)
2597 cs_map = 0xa;
2598 else
2599 cs_map = 0xF;
2600 }
2601 /*PI_41 PI_CS_MAP:RW:24:4*/
2602 clrsetbits_le32(&denali_pi[41],
2603 0xf << 24, cs_map << 24);
2604 if (cs_map == 1 && dramtype == DDR3)
2605 writel(0x2EC7FFFF, &denali_pi[34]);
2606}
2607
2608static void dram_set_bw(const struct chan_info *chan, u32 bw)
2609{
2610 u32 *denali_ctl = chan->pctl->denali_ctl;
2611
2612 if (bw == 2)
2613 clrbits_le32(&denali_ctl[196], 1 << 16);
2614 else
2615 setbits_le32(&denali_ctl[196], 1 << 16);
2616}
2617
2618static void dram_set_max_col(const struct chan_info *chan, u32 bw, u32 *pcol)
2619{
2620 u32 *denali_ctl = chan->pctl->denali_ctl;
2621 struct msch_regs *ddr_msch_regs = chan->msch;
2622 u32 *denali_pi = chan->pi->denali_pi;
2623 u32 ddrconfig;
2624
2625 clrbits_le32(&denali_ctl[191], 0xf);
2626 clrsetbits_le32(&denali_ctl[190],
2627 (7 << 24),
2628 ((16 - ((bw == 2) ? 14 : 15)) << 24));
2629 /*PI_199 PI_COL_DIFF:RW:0:4*/
2630 clrbits_le32(&denali_pi[199], 0xf);
2631 /*PI_155 PI_ROW_DIFF:RW:24:3*/
2632 clrsetbits_le32(&denali_pi[155],
2633 (7 << 24),
2634 ((16 - 12) << 24));
2635 ddrconfig = (bw == 2) ? 3 : 2;
2636 writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
2637 /* set max cs0 size */
2638 writel((4096 / 32) | ((0 / 32) << 8),
2639 &ddr_msch_regs->ddrsize);
2640
2641 *pcol = 12;
2642}
2643
2644static void dram_set_max_bank(const struct chan_info *chan, u32 bw, u32 *pbank,
2645 u32 *pcol)
2646{
2647 u32 *denali_ctl = chan->pctl->denali_ctl;
2648 u32 *denali_pi = chan->pi->denali_pi;
2649
2650 clrbits_le32(&denali_ctl[191], 0xf);
2651 clrbits_le32(&denali_ctl[190], (3 << 16));
2652 /*PI_199 PI_COL_DIFF:RW:0:4*/
2653 clrbits_le32(&denali_pi[199], 0xf);
2654 /*PI_155 PI_BANK_DIFF:RW:16:2*/
2655 clrbits_le32(&denali_pi[155], (3 << 16));
2656
2657 *pbank = 3;
2658 *pcol = 12;
2659}
2660
2661static void dram_set_max_row(const struct chan_info *chan, u32 bw, u32 *prow,
2662 u32 *pbank, u32 *pcol)
2663{
2664 u32 *denali_ctl = chan->pctl->denali_ctl;
2665 u32 *denali_pi = chan->pi->denali_pi;
2666 struct msch_regs *ddr_msch_regs = chan->msch;
2667
2668 clrsetbits_le32(&denali_ctl[191], 0xf, 12 - 10);
2669 clrbits_le32(&denali_ctl[190],
2670 (0x3 << 16) | (0x7 << 24));
2671 /*PI_199 PI_COL_DIFF:RW:0:4*/
2672 clrsetbits_le32(&denali_pi[199], 0xf, 12 - 10);
2673 /*PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2*/
2674 clrbits_le32(&denali_pi[155],
2675 (0x3 << 16) | (0x7 << 24));
2676 writel(1 | (1 << 8), &ddr_msch_regs->ddrconf);
2677 /* set max cs0 size */
2678 writel((4096 / 32) | ((0 / 32) << 8),
2679 &ddr_msch_regs->ddrsize);
2680
2681 *prow = 16;
2682 *pbank = 3;
2683 *pcol = (bw == 2) ? 10 : 11;
2684}
2685
2686static u64 dram_detect_cap(struct dram_info *dram,
2687 struct rk3399_sdram_params *params,
2688 unsigned char channel)
2689{
2690 const struct chan_info *chan = &dram->chan[channel];
2691 struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
2692 u32 bw;
2693 u32 col_tmp;
2694 u32 bk_tmp;
2695 u32 row_tmp;
2696 u32 cs0_cap;
2697 u32 training_flag;
2698 u32 ddrconfig;
2699
2700 /* detect bw */
2701 bw = 2;
2702 if (params->base.dramtype != LPDDR4) {
2703 dram_set_bw(chan, bw);
2704 cap_info->bw = bw;
2705 if (data_training(dram, channel, params,
2706 PI_READ_GATE_TRAINING)) {
2707 bw = 1;
2708 dram_set_bw(chan, 1);
2709 cap_info->bw = bw;
2710 if (data_training(dram, channel, params,
2711 PI_READ_GATE_TRAINING)) {
2712 printf("16bit error!!!\n");
2713 goto error;
2714 }
2715 }
2716 }
2717 /*
2718 * LPDDR3 CA training msut be trigger before other training.
2719 * DDR3 is not have CA training.
2720 */
2721 if (params->base.dramtype == LPDDR3)
2722 training_flag = PI_WRITE_LEVELING;
2723 else
2724 training_flag = PI_FULL_TRAINING;
2725
2726 if (params->base.dramtype != LPDDR4) {
2727 if (data_training(dram, channel, params, training_flag)) {
2728 printf("full training error!!!\n");
2729 goto error;
2730 }
2731 }
2732
2733 /* detect col */
2734 dram_set_max_col(chan, bw, &col_tmp);
2735 if (sdram_detect_col(cap_info, col_tmp) != 0)
2736 goto error;
2737
2738 /* detect bank */
2739 dram_set_max_bank(chan, bw, &bk_tmp, &col_tmp);
2740 sdram_detect_bank(cap_info, col_tmp, bk_tmp);
2741
2742 /* detect row */
2743 dram_set_max_row(chan, bw, &row_tmp, &bk_tmp, &col_tmp);
2744 if (sdram_detect_row(cap_info, col_tmp, bk_tmp, row_tmp) != 0)
2745 goto error;
2746
2747 /* detect row_3_4 */
2748 sdram_detect_row_3_4(cap_info, col_tmp, bk_tmp);
2749
2750 /* set ddrconfig */
2751 cs0_cap = (1 << (cap_info->cs0_row + cap_info->col + cap_info->bk +
2752 cap_info->bw - 20));
2753 if (cap_info->row_3_4)
2754 cs0_cap = cs0_cap * 3 / 4;
2755
2756 cap_info->cs1_row = cap_info->cs0_row;
2757 set_memory_map(chan, channel, params);
2758 ddrconfig = calculate_ddrconfig(params, channel);
2759 if (-1 == ddrconfig)
2760 goto error;
2761 set_ddrconfig(chan, params, channel,
2762 cap_info->ddrconfig);
2763
2764 /* detect cs1 row */
2765 sdram_detect_cs1_row(cap_info, params->base.dramtype);
2766
2767 /* detect die bw */
2768 sdram_detect_dbw(cap_info, params->base.dramtype);
2769
2770 return 0;
2771error:
2772 return (-1);
2773}
2774
Jagan Teki4b097192019-07-15 23:58:52 +05302775static unsigned char calculate_stride(struct rk3399_sdram_params *params)
2776{
2777 unsigned int stride = params->base.stride;
2778 unsigned int channel, chinfo = 0;
2779 unsigned int ch_cap[2] = {0, 0};
2780 u64 cap;
2781
2782 for (channel = 0; channel < 2; channel++) {
2783 unsigned int cs0_cap = 0;
2784 unsigned int cs1_cap = 0;
2785 struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
2786
2787 if (cap_info->col == 0)
2788 continue;
2789
2790 cs0_cap = (1 << (cap_info->cs0_row + cap_info->col +
2791 cap_info->bk + cap_info->bw - 20));
2792 if (cap_info->rank > 1)
2793 cs1_cap = cs0_cap >> (cap_info->cs0_row
2794 - cap_info->cs1_row);
2795 if (cap_info->row_3_4) {
2796 cs0_cap = cs0_cap * 3 / 4;
2797 cs1_cap = cs1_cap * 3 / 4;
2798 }
2799 ch_cap[channel] = cs0_cap + cs1_cap;
2800 chinfo |= 1 << channel;
2801 }
2802
Jagan Teki1ff52832019-07-15 23:58:53 +05302803 /* stride calculation for 1 channel */
2804 if (params->base.num_channels == 1 && chinfo & 1)
2805 return 0x17; /* channel a */
2806
Jagan Teki4b097192019-07-15 23:58:52 +05302807 /* stride calculation for 2 channels, default gstride type is 256B */
2808 if (ch_cap[0] == ch_cap[1]) {
2809 cap = ch_cap[0] + ch_cap[1];
2810 switch (cap) {
2811 /* 512MB */
2812 case 512:
2813 stride = 0;
2814 break;
2815 /* 1GB */
2816 case 1024:
2817 stride = 0x5;
2818 break;
2819 /*
2820 * 768MB + 768MB same as total 2GB memory
2821 * useful space: 0-768MB 1GB-1792MB
2822 */
2823 case 1536:
2824 /* 2GB */
2825 case 2048:
2826 stride = 0x9;
2827 break;
2828 /* 1536MB + 1536MB */
2829 case 3072:
2830 stride = 0x11;
2831 break;
2832 /* 4GB */
2833 case 4096:
2834 stride = 0xD;
2835 break;
2836 default:
2837 printf("%s: Unable to calculate stride for ", __func__);
2838 print_size((cap * (1 << 20)), " capacity\n");
2839 break;
2840 }
2841 }
2842
Jagan Tekia9191b82019-07-15 23:58:55 +05302843 sdram_print_stride(stride);
2844
Jagan Teki4b097192019-07-15 23:58:52 +05302845 return stride;
2846}
2847
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302848static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
2849{
2850 params->ch[channel].cap_info.rank = 0;
2851 params->ch[channel].cap_info.col = 0;
2852 params->ch[channel].cap_info.bk = 0;
2853 params->ch[channel].cap_info.bw = 32;
2854 params->ch[channel].cap_info.dbw = 32;
2855 params->ch[channel].cap_info.row_3_4 = 0;
2856 params->ch[channel].cap_info.cs0_row = 0;
2857 params->ch[channel].cap_info.cs1_row = 0;
2858 params->ch[channel].cap_info.ddrconfig = 0;
2859}
2860
Kever Yangfa437432017-02-22 16:56:35 +08002861static int sdram_init(struct dram_info *dram,
Jagan Teki4b097192019-07-15 23:58:52 +05302862 struct rk3399_sdram_params *params)
Kever Yangfa437432017-02-22 16:56:35 +08002863{
Jagan Tekifde7f452019-07-15 23:50:58 +05302864 unsigned char dramtype = params->base.dramtype;
2865 unsigned int ddr_freq = params->base.ddr_freq;
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302866 int channel, ch, rank;
YouMin Chenf2b58f02019-11-15 11:04:49 +08002867 u32 tmp, ret;
Kever Yangfa437432017-02-22 16:56:35 +08002868
2869 debug("Starting SDRAM initialization...\n");
2870
Philipp Tomsichfcb21582017-05-31 18:16:35 +02002871 if ((dramtype == DDR3 && ddr_freq > 933) ||
Kever Yangfa437432017-02-22 16:56:35 +08002872 (dramtype == LPDDR3 && ddr_freq > 933) ||
2873 (dramtype == LPDDR4 && ddr_freq > 800)) {
2874 debug("SDRAM frequency is to high!");
2875 return -E2BIG;
2876 }
2877
YouMin Chen0cacc272019-11-15 11:04:48 +08002878 /* detect rank */
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302879 for (ch = 0; ch < 2; ch++) {
2880 params->ch[ch].cap_info.rank = 2;
2881 for (rank = 2; rank != 0; rank--) {
YouMin Chen0cacc272019-11-15 11:04:48 +08002882 for (channel = 0; channel < 2; channel++) {
2883 const struct chan_info *chan =
2884 &dram->chan[channel];
2885 struct rk3399_cru *cru = dram->cru;
2886 struct rk3399_ddr_publ_regs *publ = chan->publ;
2887
2888 phy_pctrl_reset(cru, channel);
2889 phy_dll_bypass_set(publ, ddr_freq);
2890 pctl_cfg(dram, chan, channel, params);
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302891 }
2892
YouMin Chen0cacc272019-11-15 11:04:48 +08002893 /* start to trigger initialization */
2894 pctl_start(dram, params, 3);
2895
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302896 /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
2897 if (dramtype == LPDDR3)
2898 udelay(10);
2899
YouMin Chenf2b58f02019-11-15 11:04:49 +08002900 tmp = (rank == 2) ? 3 : 1;
2901 dram_set_cs(&dram->chan[ch], tmp, 2048,
2902 params->base.dramtype);
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302903 params->ch[ch].cap_info.rank = rank;
2904
YouMin Chenf8088bf2019-11-15 11:04:46 +08002905 ret = dram->ops->data_training_first(dram, ch,
2906 rank, params);
Jagan Teki299deec2019-07-16 17:27:30 +05302907 if (!ret) {
2908 debug("%s: data trained for rank %d, ch %d\n",
2909 __func__, rank, ch);
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302910 break;
Jagan Teki299deec2019-07-16 17:27:30 +05302911 }
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302912 }
2913 /* Computed rank with associated channel number */
2914 params->ch[ch].cap_info.rank = rank;
2915 }
2916
2917 params->base.num_channels = 0;
Kever Yangfa437432017-02-22 16:56:35 +08002918 for (channel = 0; channel < 2; channel++) {
2919 const struct chan_info *chan = &dram->chan[channel];
YouMin Chen0cacc272019-11-15 11:04:48 +08002920 struct sdram_cap_info *cap_info =
2921 &params->ch[channel].cap_info;
Kever Yangfa437432017-02-22 16:56:35 +08002922
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302923 if (cap_info->rank == 0) {
YouMin Chenf2b58f02019-11-15 11:04:49 +08002924 clear_channel_params(params, 1);
Kever Yangfa437432017-02-22 16:56:35 +08002925 continue;
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302926 } else {
2927 params->base.num_channels++;
Kever Yangfa437432017-02-22 16:56:35 +08002928 }
2929
YouMin Chenf8088bf2019-11-15 11:04:46 +08002930 printf("Channel ");
2931 printf(channel ? "1: " : "0: ");
Jagan Tekia0aebe82019-07-15 23:58:45 +05302932
YouMin Chenf2b58f02019-11-15 11:04:49 +08002933 if (channel == 0)
2934 set_ddr_stride(dram->pmusgrf, 0x17);
2935 else
2936 set_ddr_stride(dram->pmusgrf, 0x18);
Kever Yangfa437432017-02-22 16:56:35 +08002937
YouMin Chenf2b58f02019-11-15 11:04:49 +08002938 if (dram_detect_cap(dram, params, channel)) {
2939 printf("Cap error!\n");
2940 continue;
Kever Yangfa437432017-02-22 16:56:35 +08002941 }
2942
Jagan Tekia9191b82019-07-15 23:58:55 +05302943 sdram_print_ddr_info(cap_info, &params->base);
Kever Yange0f907e2019-08-12 20:02:29 +08002944 set_memory_map(chan, channel, params);
YouMin Chen0cacc272019-11-15 11:04:48 +08002945 cap_info->ddrconfig =
2946 calculate_ddrconfig(params, channel);
2947 if (-1 == cap_info->ddrconfig) {
2948 printf("no ddrconfig find, Cap not support!\n");
2949 continue;
2950 }
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302951 set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
Kever Yange0f907e2019-08-12 20:02:29 +08002952 set_cap_relate_config(chan, params, channel);
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302953 }
2954
2955 if (params->base.num_channels == 0) {
2956 printf("%s: ", __func__);
Jagan Tekia9191b82019-07-15 23:58:55 +05302957 sdram_print_dram_type(params->base.dramtype);
Jagan Tekid0ba88f2019-07-15 23:58:54 +05302958 printf(" - %dMHz failed!\n", params->base.ddr_freq);
2959 return -EINVAL;
Kever Yangfa437432017-02-22 16:56:35 +08002960 }
Jagan Teki4b097192019-07-15 23:58:52 +05302961
2962 params->base.stride = calculate_stride(params);
Jagan Tekifde7f452019-07-15 23:50:58 +05302963 dram_all_config(dram, params);
YouMin Chenf8088bf2019-11-15 11:04:46 +08002964
2965 dram->ops->set_rate_index(dram, params);
Kever Yangfa437432017-02-22 16:56:35 +08002966
2967 debug("Finish SDRAM initialization...\n");
2968 return 0;
2969}
2970
2971static int rk3399_dmc_ofdata_to_platdata(struct udevice *dev)
2972{
2973#if !CONFIG_IS_ENABLED(OF_PLATDATA)
2974 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
Kever Yangfa437432017-02-22 16:56:35 +08002975 int ret;
2976
Philipp Tomsich8f1034e2017-06-07 18:46:03 +02002977 ret = dev_read_u32_array(dev, "rockchip,sdram-params",
2978 (u32 *)&plat->sdram_params,
2979 sizeof(plat->sdram_params) / sizeof(u32));
Kever Yangfa437432017-02-22 16:56:35 +08002980 if (ret) {
2981 printf("%s: Cannot read rockchip,sdram-params %d\n",
2982 __func__, ret);
2983 return ret;
2984 }
Masahiro Yamadad3581232018-04-19 12:14:03 +09002985 ret = regmap_init_mem(dev_ofnode(dev), &plat->map);
Kever Yangfa437432017-02-22 16:56:35 +08002986 if (ret)
2987 printf("%s: regmap failed %d\n", __func__, ret);
2988
2989#endif
2990 return 0;
2991}
2992
2993#if CONFIG_IS_ENABLED(OF_PLATDATA)
2994static int conv_of_platdata(struct udevice *dev)
2995{
2996 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
2997 struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
2998 int ret;
2999
3000 ret = regmap_init_mem_platdata(dev, dtplat->reg,
Jagan Teki63f4d712019-07-15 23:50:56 +05303001 ARRAY_SIZE(dtplat->reg) / 2,
3002 &plat->map);
Kever Yangfa437432017-02-22 16:56:35 +08003003 if (ret)
3004 return ret;
3005
3006 return 0;
3007}
3008#endif
3009
Jagan Teki299deec2019-07-16 17:27:30 +05303010static const struct sdram_rk3399_ops rk3399_ops = {
Jagan Tekia0ded6d2019-07-16 17:27:31 +05303011#if !defined(CONFIG_RAM_RK3399_LPDDR4)
YouMin Chenf8088bf2019-11-15 11:04:46 +08003012 .data_training_first = data_training_first,
3013 .set_rate_index = switch_to_phy_index1,
YouMin Chen0cacc272019-11-15 11:04:48 +08003014 .modify_param = modify_param,
3015 .get_phy_index_params = get_phy_index_params,
Jagan Tekia0ded6d2019-07-16 17:27:31 +05303016#else
YouMin Chenf8088bf2019-11-15 11:04:46 +08003017 .data_training_first = lpddr4_mr_detect,
3018 .set_rate_index = lpddr4_set_rate,
YouMin Chen0cacc272019-11-15 11:04:48 +08003019 .modify_param = lpddr4_modify_param,
3020 .get_phy_index_params = lpddr4_get_phy_index_params,
Jagan Tekia0ded6d2019-07-16 17:27:31 +05303021#endif
Jagan Teki299deec2019-07-16 17:27:30 +05303022};
3023
Kever Yangfa437432017-02-22 16:56:35 +08003024static int rk3399_dmc_init(struct udevice *dev)
3025{
3026 struct dram_info *priv = dev_get_priv(dev);
3027 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
3028 int ret;
3029#if !CONFIG_IS_ENABLED(OF_PLATDATA)
3030 struct rk3399_sdram_params *params = &plat->sdram_params;
3031#else
3032 struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
3033 struct rk3399_sdram_params *params =
3034 (void *)dtplat->rockchip_sdram_params;
3035
3036 ret = conv_of_platdata(dev);
3037 if (ret)
3038 return ret;
3039#endif
3040
Jagan Teki299deec2019-07-16 17:27:30 +05303041 priv->ops = &rk3399_ops;
Kever Yangfa437432017-02-22 16:56:35 +08003042 priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
Jagan Tekia0aebe82019-07-15 23:58:45 +05303043 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Jagan Tekic36abd02019-07-16 17:27:40 +05303044 priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
Kever Yangfa437432017-02-22 16:56:35 +08003045 priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
3046 priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
3047 priv->pmucru = rockchip_get_pmucru();
3048 priv->cru = rockchip_get_cru();
3049 priv->chan[0].pctl = regmap_get_range(plat->map, 0);
3050 priv->chan[0].pi = regmap_get_range(plat->map, 1);
3051 priv->chan[0].publ = regmap_get_range(plat->map, 2);
3052 priv->chan[0].msch = regmap_get_range(plat->map, 3);
3053 priv->chan[1].pctl = regmap_get_range(plat->map, 4);
3054 priv->chan[1].pi = regmap_get_range(plat->map, 5);
3055 priv->chan[1].publ = regmap_get_range(plat->map, 6);
3056 priv->chan[1].msch = regmap_get_range(plat->map, 7);
3057
3058 debug("con reg %p %p %p %p %p %p %p %p\n",
3059 priv->chan[0].pctl, priv->chan[0].pi,
3060 priv->chan[0].publ, priv->chan[0].msch,
3061 priv->chan[1].pctl, priv->chan[1].pi,
3062 priv->chan[1].publ, priv->chan[1].msch);
Jagan Tekic36abd02019-07-16 17:27:40 +05303063 debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p, pmu %p\n", priv->cru,
3064 priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
Jagan Teki3eaf5392019-07-15 23:50:57 +05303065
Kever Yangfa437432017-02-22 16:56:35 +08003066#if CONFIG_IS_ENABLED(OF_PLATDATA)
3067 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
3068#else
3069 ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
3070#endif
3071 if (ret) {
3072 printf("%s clk get failed %d\n", __func__, ret);
3073 return ret;
3074 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05303075
Kever Yangfa437432017-02-22 16:56:35 +08003076 ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
3077 if (ret < 0) {
3078 printf("%s clk set failed %d\n", __func__, ret);
3079 return ret;
3080 }
Jagan Teki3eaf5392019-07-15 23:50:57 +05303081
Kever Yangfa437432017-02-22 16:56:35 +08003082 ret = sdram_init(priv, params);
3083 if (ret < 0) {
Jagan Teki3eaf5392019-07-15 23:50:57 +05303084 printf("%s DRAM init failed %d\n", __func__, ret);
Kever Yangfa437432017-02-22 16:56:35 +08003085 return ret;
3086 }
3087
3088 return 0;
3089}
3090#endif
3091
Kever Yangfa437432017-02-22 16:56:35 +08003092static int rk3399_dmc_probe(struct udevice *dev)
3093{
Kever Yang82763342019-04-01 17:20:53 +08003094#if defined(CONFIG_TPL_BUILD) || \
3095 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yangfa437432017-02-22 16:56:35 +08003096 if (rk3399_dmc_init(dev))
3097 return 0;
3098#else
3099 struct dram_info *priv = dev_get_priv(dev);
3100
3101 priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
Jagan Teki3eaf5392019-07-15 23:50:57 +05303102 debug("%s: pmugrf = %p\n", __func__, priv->pmugrf);
Kever Yang7805cdf2017-06-23 16:11:06 +08003103 priv->info.base = CONFIG_SYS_SDRAM_BASE;
Jagan Teki63f4d712019-07-15 23:50:56 +05303104 priv->info.size =
3105 rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg2);
Kever Yangfa437432017-02-22 16:56:35 +08003106#endif
3107 return 0;
3108}
3109
3110static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info)
3111{
3112 struct dram_info *priv = dev_get_priv(dev);
3113
Kever Yang76e16932017-04-19 16:01:14 +08003114 *info = priv->info;
Kever Yangfa437432017-02-22 16:56:35 +08003115
3116 return 0;
3117}
3118
3119static struct ram_ops rk3399_dmc_ops = {
3120 .get_info = rk3399_dmc_get_info,
3121};
3122
Kever Yangfa437432017-02-22 16:56:35 +08003123static const struct udevice_id rk3399_dmc_ids[] = {
3124 { .compatible = "rockchip,rk3399-dmc" },
3125 { }
3126};
3127
3128U_BOOT_DRIVER(dmc_rk3399) = {
3129 .name = "rockchip_rk3399_dmc",
3130 .id = UCLASS_RAM,
3131 .of_match = rk3399_dmc_ids,
3132 .ops = &rk3399_dmc_ops,
Kever Yang82763342019-04-01 17:20:53 +08003133#if defined(CONFIG_TPL_BUILD) || \
3134 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yangfa437432017-02-22 16:56:35 +08003135 .ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata,
3136#endif
3137 .probe = rk3399_dmc_probe,
Kever Yangfa437432017-02-22 16:56:35 +08003138 .priv_auto_alloc_size = sizeof(struct dram_info),
Kever Yang82763342019-04-01 17:20:53 +08003139#if defined(CONFIG_TPL_BUILD) || \
3140 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yangfa437432017-02-22 16:56:35 +08003141 .platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
3142#endif
3143};