blob: 7b95c954a6c54580663b2310afd7384489af6155 [file] [log] [blame]
Kever Yang6fc9ebf2018-12-20 11:33:42 +08001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
Kever Yang50fb9982017-02-22 16:56:35 +08002/*
3 * (C) Copyright 2016-2017 Rockchip Inc.
4 *
Kever Yang50fb9982017-02-22 16:56:35 +08005 * Adapted from coreboot.
6 */
Philipp Tomsichc69b3092017-05-31 18:16:34 +02007
Kever Yang50fb9982017-02-22 16:56:35 +08008#include <common.h>
9#include <clk.h>
10#include <dm.h>
11#include <dt-structs.h>
Simon Glass97589732020-05-10 11:40:02 -060012#include <init.h>
Kever Yang50fb9982017-02-22 16:56:35 +080013#include <ram.h>
14#include <regmap.h>
15#include <syscon.h>
16#include <asm/io.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080017#include <asm/arch-rockchip/clock.h>
Jagan Teki783acfd2020-01-09 14:22:17 +053018#include <asm/arch-rockchip/cru.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080019#include <asm/arch-rockchip/grf_rk3399.h>
Jagan Teki6ea82692019-07-16 17:27:40 +053020#include <asm/arch-rockchip/pmu_rk3399.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080021#include <asm/arch-rockchip/hardware.h>
Kever Yange47db832019-11-15 11:04:33 +080022#include <asm/arch-rockchip/sdram.h>
Jagan Tekiacf8e0f2019-07-15 23:50:57 +053023#include <asm/arch-rockchip/sdram_rk3399.h>
Kever Yang50fb9982017-02-22 16:56:35 +080024#include <linux/err.h>
Philipp Tomsichc69b3092017-05-31 18:16:34 +020025#include <time.h>
Kever Yang50fb9982017-02-22 16:56:35 +080026
Jagan Tekiacf8e0f2019-07-15 23:50:57 +053027#define PRESET_SGRF_HOLD(n) ((0x1 << (6 + 16)) | ((n) << 6))
28#define PRESET_GPIO0_HOLD(n) ((0x1 << (7 + 16)) | ((n) << 7))
29#define PRESET_GPIO1_HOLD(n) ((0x1 << (8 + 16)) | ((n) << 8))
30
31#define PHY_DRV_ODT_HI_Z 0x0
32#define PHY_DRV_ODT_240 0x1
33#define PHY_DRV_ODT_120 0x8
34#define PHY_DRV_ODT_80 0x9
35#define PHY_DRV_ODT_60 0xc
36#define PHY_DRV_ODT_48 0xd
37#define PHY_DRV_ODT_40 0xe
38#define PHY_DRV_ODT_34_3 0xf
39
Jagan Teki5d152172019-07-16 17:27:15 +053040#define PHY_BOOSTP_EN 0x1
41#define PHY_BOOSTN_EN 0x1
Jagan Tekid8681842019-07-16 17:27:16 +053042#define PHY_SLEWP_EN 0x1
43#define PHY_SLEWN_EN 0x1
Jagan Teki65535a22019-07-16 17:27:17 +053044#define PHY_RX_CM_INPUT 0x1
Jagan Teki0cb31122019-07-16 17:27:24 +053045#define CS0_MR22_VAL 0
46#define CS1_MR22_VAL 3
Jagan Teki5d152172019-07-16 17:27:15 +053047
YouMin Chen79f4d912019-11-15 11:04:53 +080048/* LPDDR3 DRAM DS */
49#define LPDDR3_DS_34 0x1
50#define LPDDR3_DS_40 0x2
51#define LPDDR3_DS_48 0x3
52
Jagan Tekice75cfb2019-07-15 23:58:43 +053053#define CRU_SFTRST_DDR_CTRL(ch, n) ((0x1 << (8 + 16 + (ch) * 4)) | \
54 ((n) << (8 + (ch) * 4)))
55#define CRU_SFTRST_DDR_PHY(ch, n) ((0x1 << (9 + 16 + (ch) * 4)) | \
56 ((n) << (9 + (ch) * 4)))
Kever Yang50fb9982017-02-22 16:56:35 +080057struct chan_info {
58 struct rk3399_ddr_pctl_regs *pctl;
59 struct rk3399_ddr_pi_regs *pi;
60 struct rk3399_ddr_publ_regs *publ;
YouMin Chen23ae72e2019-11-15 11:04:45 +080061 struct msch_regs *msch;
Kever Yang50fb9982017-02-22 16:56:35 +080062};
63
64struct dram_info {
Kever Yang7f347842019-04-01 17:20:53 +080065#if defined(CONFIG_TPL_BUILD) || \
66 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Jagan Tekic9151e22019-07-15 23:58:45 +053067 u32 pwrup_srefresh_exit[2];
Kever Yang50fb9982017-02-22 16:56:35 +080068 struct chan_info chan[2];
69 struct clk ddr_clk;
Jagan Teki783acfd2020-01-09 14:22:17 +053070 struct rockchip_cru *cru;
Jagan Tekic9151e22019-07-15 23:58:45 +053071 struct rk3399_grf_regs *grf;
Jagan Teki6ea82692019-07-16 17:27:40 +053072 struct rk3399_pmu_regs *pmu;
Kever Yang50fb9982017-02-22 16:56:35 +080073 struct rk3399_pmucru *pmucru;
74 struct rk3399_pmusgrf_regs *pmusgrf;
75 struct rk3399_ddr_cic_regs *cic;
Jagan Teki9eb935a2019-07-16 17:27:30 +053076 const struct sdram_rk3399_ops *ops;
Kever Yang50fb9982017-02-22 16:56:35 +080077#endif
78 struct ram_info info;
79 struct rk3399_pmugrf_regs *pmugrf;
80};
81
Jagan Teki9eb935a2019-07-16 17:27:30 +053082struct sdram_rk3399_ops {
YouMin Chende57fbf2019-11-15 11:04:46 +080083 int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
84 struct rk3399_sdram_params *sdram);
85 int (*set_rate_index)(struct dram_info *dram,
86 struct rk3399_sdram_params *params);
YouMin Chen99027372019-11-15 11:04:48 +080087 void (*modify_param)(const struct chan_info *chan,
88 struct rk3399_sdram_params *params);
89 struct rk3399_sdram_params *
90 (*get_phy_index_params)(u32 phy_fn,
91 struct rk3399_sdram_params *params);
Jagan Teki9eb935a2019-07-16 17:27:30 +053092};
93
Kever Yang7f347842019-04-01 17:20:53 +080094#if defined(CONFIG_TPL_BUILD) || \
95 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yang50fb9982017-02-22 16:56:35 +080096
97struct rockchip_dmc_plat {
98#if CONFIG_IS_ENABLED(OF_PLATDATA)
99 struct dtd_rockchip_rk3399_dmc dtplat;
100#else
101 struct rk3399_sdram_params sdram_params;
102#endif
103 struct regmap *map;
104};
105
Jagan Tekie3619d12019-07-16 17:27:21 +0530106struct io_setting {
107 u32 mhz;
108 u32 mr5;
109 /* dram side */
110 u32 dq_odt;
111 u32 ca_odt;
112 u32 pdds;
113 u32 dq_vref;
114 u32 ca_vref;
115 /* phy side */
116 u32 rd_odt;
117 u32 wr_dq_drv;
118 u32 wr_ca_drv;
119 u32 wr_ckcs_drv;
120 u32 rd_odt_en;
121 u32 rd_vref;
122} lpddr4_io_setting[] = {
123 {
124 50 * MHz,
125 0,
126 /* dram side */
127 0, /* dq_odt; */
128 0, /* ca_odt; */
129 6, /* pdds; */
130 0x72, /* dq_vref; */
131 0x72, /* ca_vref; */
132 /* phy side */
133 PHY_DRV_ODT_HI_Z, /* rd_odt; */
134 PHY_DRV_ODT_40, /* wr_dq_drv; */
135 PHY_DRV_ODT_40, /* wr_ca_drv; */
136 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
137 0, /* rd_odt_en;*/
138 41, /* rd_vref; (unit %, range 3.3% - 48.7%) */
139 },
140 {
141 600 * MHz,
142 0,
143 /* dram side */
144 1, /* dq_odt; */
145 0, /* ca_odt; */
146 6, /* pdds; */
147 0x72, /* dq_vref; */
148 0x72, /* ca_vref; */
149 /* phy side */
150 PHY_DRV_ODT_HI_Z, /* rd_odt; */
151 PHY_DRV_ODT_48, /* wr_dq_drv; */
152 PHY_DRV_ODT_40, /* wr_ca_drv; */
153 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
154 0, /* rd_odt_en; */
155 32, /* rd_vref; (unit %, range 3.3% - 48.7%) */
156 },
157 {
Kever Yangbc9b1562019-11-15 11:04:51 +0800158 933 * MHz,
Jagan Tekie3619d12019-07-16 17:27:21 +0530159 0,
160 /* dram side */
161 1, /* dq_odt; */
162 0, /* ca_odt; */
Kever Yangbc9b1562019-11-15 11:04:51 +0800163 3, /* pdds; */
Jagan Tekie3619d12019-07-16 17:27:21 +0530164 0x72, /* dq_vref; */
165 0x72, /* ca_vref; */
166 /* phy side */
Kever Yangbc9b1562019-11-15 11:04:51 +0800167 PHY_DRV_ODT_80, /* rd_odt; */
168 PHY_DRV_ODT_40, /* wr_dq_drv; */
Jagan Tekie3619d12019-07-16 17:27:21 +0530169 PHY_DRV_ODT_40, /* wr_ca_drv; */
170 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
171 1, /* rd_odt_en; */
Kever Yangbc9b1562019-11-15 11:04:51 +0800172 20, /* rd_vref; (unit %, range 3.3% - 48.7%) */
Jagan Tekie3619d12019-07-16 17:27:21 +0530173 },
174 {
175 1066 * MHz,
176 0,
177 /* dram side */
178 6, /* dq_odt; */
179 0, /* ca_odt; */
Kever Yangbc9b1562019-11-15 11:04:51 +0800180 3, /* pdds; */
Jagan Tekie3619d12019-07-16 17:27:21 +0530181 0x10, /* dq_vref; */
182 0x72, /* ca_vref; */
183 /* phy side */
Kever Yangbc9b1562019-11-15 11:04:51 +0800184 PHY_DRV_ODT_80, /* rd_odt; */
Jagan Tekie3619d12019-07-16 17:27:21 +0530185 PHY_DRV_ODT_60, /* wr_dq_drv; */
186 PHY_DRV_ODT_40, /* wr_ca_drv; */
187 PHY_DRV_ODT_40, /* wr_ckcs_drv; */
188 1, /* rd_odt_en; */
Kever Yangbc9b1562019-11-15 11:04:51 +0800189 20, /* rd_vref; (unit %, range 3.3% - 48.7%) */
Jagan Tekie3619d12019-07-16 17:27:21 +0530190 },
191};
192
Jagan Tekid33056b2019-07-16 17:27:22 +0530193static struct io_setting *
194lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
195{
196 struct io_setting *io = NULL;
197 u32 n;
198
199 for (n = 0; n < ARRAY_SIZE(lpddr4_io_setting); n++) {
200 io = &lpddr4_io_setting[n];
201
202 if (io->mr5 != 0) {
203 if (io->mhz >= params->base.ddr_freq &&
204 io->mr5 == mr5)
205 break;
206 } else {
207 if (io->mhz >= params->base.ddr_freq)
208 break;
209 }
210 }
211
212 return io;
213}
214
YouMin Chen23ae72e2019-11-15 11:04:45 +0800215static void *get_denali_ctl(const struct chan_info *chan,
Jagan Teki6ea82692019-07-16 17:27:40 +0530216 struct rk3399_sdram_params *params, bool reg)
217{
YouMin Chen23ae72e2019-11-15 11:04:45 +0800218 return reg ? &chan->pctl->denali_ctl : &params->pctl_regs.denali_ctl;
Jagan Teki6ea82692019-07-16 17:27:40 +0530219}
220
YouMin Chen23ae72e2019-11-15 11:04:45 +0800221static void *get_denali_phy(const struct chan_info *chan,
Jagan Teki6ea82692019-07-16 17:27:40 +0530222 struct rk3399_sdram_params *params, bool reg)
223{
YouMin Chen23ae72e2019-11-15 11:04:45 +0800224 return reg ? &chan->publ->denali_phy : &params->phy_regs.denali_phy;
Jagan Teki6ea82692019-07-16 17:27:40 +0530225}
226
Jagan Tekic9151e22019-07-15 23:58:45 +0530227static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
228{
YouMin Chencafbf9f2019-11-15 11:04:47 +0800229 return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc1_con0;
Jagan Tekic9151e22019-07-15 23:58:45 +0530230}
231
Jagan Teki783acfd2020-01-09 14:22:17 +0530232static void rkclk_ddr_reset(struct rockchip_cru *cru, u32 channel, u32 ctl,
Jagan Tekice75cfb2019-07-15 23:58:43 +0530233 u32 phy)
234{
235 channel &= 0x1;
236 ctl &= 0x1;
237 phy &= 0x1;
238 writel(CRU_SFTRST_DDR_CTRL(channel, ctl) |
239 CRU_SFTRST_DDR_PHY(channel, phy),
240 &cru->softrst_con[4]);
241}
242
Jagan Teki783acfd2020-01-09 14:22:17 +0530243static void phy_pctrl_reset(struct rockchip_cru *cru, u32 channel)
Jagan Tekice75cfb2019-07-15 23:58:43 +0530244{
245 rkclk_ddr_reset(cru, channel, 1, 1);
246 udelay(10);
247
248 rkclk_ddr_reset(cru, channel, 1, 0);
249 udelay(10);
250
251 rkclk_ddr_reset(cru, channel, 0, 0);
252 udelay(10);
253}
254
Kever Yang50fb9982017-02-22 16:56:35 +0800255static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs,
256 u32 freq)
257{
258 u32 *denali_phy = ddr_publ_regs->denali_phy;
259
260 /* From IP spec, only freq small than 125 can enter dll bypass mode */
261 if (freq <= 125) {
262 /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
263 setbits_le32(&denali_phy[86], (0x3 << 2) << 8);
264 setbits_le32(&denali_phy[214], (0x3 << 2) << 8);
265 setbits_le32(&denali_phy[342], (0x3 << 2) << 8);
266 setbits_le32(&denali_phy[470], (0x3 << 2) << 8);
267
268 /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
269 setbits_le32(&denali_phy[547], (0x3 << 2) << 16);
270 setbits_le32(&denali_phy[675], (0x3 << 2) << 16);
271 setbits_le32(&denali_phy[803], (0x3 << 2) << 16);
272 } else {
273 /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
274 clrbits_le32(&denali_phy[86], (0x3 << 2) << 8);
275 clrbits_le32(&denali_phy[214], (0x3 << 2) << 8);
276 clrbits_le32(&denali_phy[342], (0x3 << 2) << 8);
277 clrbits_le32(&denali_phy[470], (0x3 << 2) << 8);
278
279 /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
280 clrbits_le32(&denali_phy[547], (0x3 << 2) << 16);
281 clrbits_le32(&denali_phy[675], (0x3 << 2) << 16);
282 clrbits_le32(&denali_phy[803], (0x3 << 2) << 16);
283 }
284}
285
286static void set_memory_map(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +0530287 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +0800288{
Jagan Tekia58ff792019-07-15 23:50:58 +0530289 const struct rk3399_sdram_channel *sdram_ch = &params->ch[channel];
Kever Yang50fb9982017-02-22 16:56:35 +0800290 u32 *denali_ctl = chan->pctl->denali_ctl;
291 u32 *denali_pi = chan->pi->denali_pi;
292 u32 cs_map;
293 u32 reduc;
294 u32 row;
295
296 /* Get row number from ddrconfig setting */
Jagan Teki97867c82019-07-15 23:51:05 +0530297 if (sdram_ch->cap_info.ddrconfig < 2 ||
298 sdram_ch->cap_info.ddrconfig == 4)
Kever Yang50fb9982017-02-22 16:56:35 +0800299 row = 16;
YouMin Chen79f4d912019-11-15 11:04:53 +0800300 else if (sdram_ch->cap_info.ddrconfig == 3 ||
301 sdram_ch->cap_info.ddrconfig == 5)
Kever Yang50fb9982017-02-22 16:56:35 +0800302 row = 14;
303 else
304 row = 15;
305
Jagan Teki97867c82019-07-15 23:51:05 +0530306 cs_map = (sdram_ch->cap_info.rank > 1) ? 3 : 1;
307 reduc = (sdram_ch->cap_info.bw == 2) ? 0 : 1;
Kever Yang50fb9982017-02-22 16:56:35 +0800308
309 /* Set the dram configuration to ctrl */
Jagan Teki97867c82019-07-15 23:51:05 +0530310 clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->cap_info.col));
Kever Yang50fb9982017-02-22 16:56:35 +0800311 clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24),
Jagan Teki97867c82019-07-15 23:51:05 +0530312 ((3 - sdram_ch->cap_info.bk) << 16) |
Kever Yang50fb9982017-02-22 16:56:35 +0800313 ((16 - row) << 24));
314
315 clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16),
316 cs_map | (reduc << 16));
317
318 /* PI_199 PI_COL_DIFF:RW:0:4 */
Jagan Teki97867c82019-07-15 23:51:05 +0530319 clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->cap_info.col));
Kever Yang50fb9982017-02-22 16:56:35 +0800320
321 /* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */
322 clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24),
Jagan Teki97867c82019-07-15 23:51:05 +0530323 ((3 - sdram_ch->cap_info.bk) << 16) |
Kever Yang50fb9982017-02-22 16:56:35 +0800324 ((16 - row) << 24));
Jagan Teki9337cb32019-07-16 17:27:18 +0530325
YouMin Chende57fbf2019-11-15 11:04:46 +0800326 if (params->base.dramtype == LPDDR4) {
Jagan Teki9337cb32019-07-16 17:27:18 +0530327 if (cs_map == 1)
328 cs_map = 0x5;
329 else if (cs_map == 2)
330 cs_map = 0xa;
331 else
332 cs_map = 0xF;
333 }
334
Kever Yang50fb9982017-02-22 16:56:35 +0800335 /* PI_41 PI_CS_MAP:RW:24:4 */
336 clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24);
Jagan Teki97867c82019-07-15 23:51:05 +0530337 if (sdram_ch->cap_info.rank == 1 && params->base.dramtype == DDR3)
Kever Yang50fb9982017-02-22 16:56:35 +0800338 writel(0x2EC7FFFF, &denali_pi[34]);
339}
340
Thomas Hebbd8105ab2019-12-20 12:28:15 -0800341static int phy_io_config(u32 *denali_phy, u32 *denali_ctl,
Jagan Teki2dd3efc2019-07-16 17:27:26 +0530342 const struct rk3399_sdram_params *params, u32 mr5)
Jagan Tekib5d46632019-07-16 17:27:07 +0530343{
Jagan Tekib5d46632019-07-16 17:27:07 +0530344 u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
345 u32 mode_sel;
Jagan Tekib5d46632019-07-16 17:27:07 +0530346 u32 speed;
YouMin Chen79f4d912019-11-15 11:04:53 +0800347 u32 reg_value;
348 u32 ds_value, odt_value;
Jagan Tekib5d46632019-07-16 17:27:07 +0530349
Jagan Teki59a9a572019-07-16 17:27:27 +0530350 /* vref setting & mode setting */
Jagan Tekib5d46632019-07-16 17:27:07 +0530351 if (params->base.dramtype == LPDDR4) {
Jagan Teki2dd3efc2019-07-16 17:27:26 +0530352 struct io_setting *io = lpddr4_get_io_settings(params, mr5);
353 u32 rd_vref = io->rd_vref * 1000;
354
355 if (rd_vref < 36700) {
356 /* MODE_LV[2:0] = LPDDR4 (Range 2)*/
357 vref_mode_dq = 0x7;
Jagan Teki59a9a572019-07-16 17:27:27 +0530358 /* MODE[2:0]= LPDDR4 Range 2(0.4*VDDQ) */
359 mode_sel = 0x5;
Jagan Teki2dd3efc2019-07-16 17:27:26 +0530360 vref_value_dq = (rd_vref - 3300) / 521;
361 } else {
362 /* MODE_LV[2:0] = LPDDR4 (Range 1)*/
363 vref_mode_dq = 0x6;
Jagan Teki59a9a572019-07-16 17:27:27 +0530364 /* MODE[2:0]= LPDDR4 Range 1(0.33*VDDQ) */
365 mode_sel = 0x4;
Jagan Teki2dd3efc2019-07-16 17:27:26 +0530366 vref_value_dq = (rd_vref - 15300) / 521;
367 }
Jagan Tekib5d46632019-07-16 17:27:07 +0530368 vref_mode_ac = 0x6;
Jagan Tekia5b07192019-07-16 17:27:28 +0530369 /* VDDQ/3/2=16.8% */
370 vref_value_ac = 0x3;
Jagan Tekib5d46632019-07-16 17:27:07 +0530371 } else if (params->base.dramtype == LPDDR3) {
372 if (params->base.odt == 1) {
373 vref_mode_dq = 0x5; /* LPDDR3 ODT */
YouMin Chen79f4d912019-11-15 11:04:53 +0800374 ds_value = readl(&denali_ctl[138]) & 0xf;
Jagan Tekib5d46632019-07-16 17:27:07 +0530375 odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
YouMin Chen79f4d912019-11-15 11:04:53 +0800376 if (ds_value == LPDDR3_DS_48) {
Jagan Tekib5d46632019-07-16 17:27:07 +0530377 switch (odt_value) {
378 case PHY_DRV_ODT_240:
YouMin Chen79f4d912019-11-15 11:04:53 +0800379 vref_value_dq = 0x1B;
Jagan Tekib5d46632019-07-16 17:27:07 +0530380 break;
381 case PHY_DRV_ODT_120:
382 vref_value_dq = 0x26;
383 break;
384 case PHY_DRV_ODT_60:
385 vref_value_dq = 0x36;
386 break;
387 default:
388 debug("Invalid ODT value.\n");
389 return -EINVAL;
390 }
YouMin Chen79f4d912019-11-15 11:04:53 +0800391 } else if (ds_value == LPDDR3_DS_40) {
Jagan Tekib5d46632019-07-16 17:27:07 +0530392 switch (odt_value) {
393 case PHY_DRV_ODT_240:
394 vref_value_dq = 0x19;
395 break;
396 case PHY_DRV_ODT_120:
397 vref_value_dq = 0x23;
398 break;
399 case PHY_DRV_ODT_60:
400 vref_value_dq = 0x31;
401 break;
402 default:
403 debug("Invalid ODT value.\n");
404 return -EINVAL;
405 }
YouMin Chen79f4d912019-11-15 11:04:53 +0800406 } else if (ds_value == LPDDR3_DS_34) {
Jagan Tekib5d46632019-07-16 17:27:07 +0530407 switch (odt_value) {
408 case PHY_DRV_ODT_240:
409 vref_value_dq = 0x17;
410 break;
411 case PHY_DRV_ODT_120:
412 vref_value_dq = 0x20;
413 break;
414 case PHY_DRV_ODT_60:
415 vref_value_dq = 0x2e;
416 break;
417 default:
418 debug("Invalid ODT value.\n");
419 return -EINVAL;
420 }
421 } else {
422 debug("Invalid DRV value.\n");
423 return -EINVAL;
424 }
425 } else {
426 vref_mode_dq = 0x2; /* LPDDR3 */
427 vref_value_dq = 0x1f;
428 }
429 vref_mode_ac = 0x2;
430 vref_value_ac = 0x1f;
Jagan Teki213b9ba2019-07-16 17:27:11 +0530431 mode_sel = 0x0;
Jagan Tekib5d46632019-07-16 17:27:07 +0530432 } else if (params->base.dramtype == DDR3) {
433 /* DDR3L */
434 vref_mode_dq = 0x1;
435 vref_value_dq = 0x1f;
436 vref_mode_ac = 0x1;
437 vref_value_ac = 0x1f;
Jagan Teki213b9ba2019-07-16 17:27:11 +0530438 mode_sel = 0x1;
Jagan Tekib5d46632019-07-16 17:27:07 +0530439 } else {
440 debug("Unknown DRAM type.\n");
441 return -EINVAL;
442 }
443
444 reg_value = (vref_mode_dq << 9) | (0x1 << 8) | vref_value_dq;
445
446 /* PHY_913 PHY_PAD_VREF_CTRL_DQ_0 12bits offset_8 */
447 clrsetbits_le32(&denali_phy[913], 0xfff << 8, reg_value << 8);
448 /* PHY_914 PHY_PAD_VREF_CTRL_DQ_1 12bits offset_0 */
449 clrsetbits_le32(&denali_phy[914], 0xfff, reg_value);
450 /* PHY_914 PHY_PAD_VREF_CTRL_DQ_2 12bits offset_16 */
451 clrsetbits_le32(&denali_phy[914], 0xfff << 16, reg_value << 16);
452 /* PHY_915 PHY_PAD_VREF_CTRL_DQ_3 12bits offset_0 */
453 clrsetbits_le32(&denali_phy[915], 0xfff, reg_value);
454
455 reg_value = (vref_mode_ac << 9) | (0x1 << 8) | vref_value_ac;
456
457 /* PHY_915 PHY_PAD_VREF_CTRL_AC 12bits offset_16 */
458 clrsetbits_le32(&denali_phy[915], 0xfff << 16, reg_value << 16);
459
Jagan Tekib5d46632019-07-16 17:27:07 +0530460 /* PHY_924 PHY_PAD_FDBK_DRIVE */
461 clrsetbits_le32(&denali_phy[924], 0x7 << 15, mode_sel << 15);
462 /* PHY_926 PHY_PAD_DATA_DRIVE */
463 clrsetbits_le32(&denali_phy[926], 0x7 << 6, mode_sel << 6);
464 /* PHY_927 PHY_PAD_DQS_DRIVE */
465 clrsetbits_le32(&denali_phy[927], 0x7 << 6, mode_sel << 6);
466 /* PHY_928 PHY_PAD_ADDR_DRIVE */
467 clrsetbits_le32(&denali_phy[928], 0x7 << 14, mode_sel << 14);
468 /* PHY_929 PHY_PAD_CLK_DRIVE */
469 clrsetbits_le32(&denali_phy[929], 0x7 << 14, mode_sel << 14);
470 /* PHY_935 PHY_PAD_CKE_DRIVE */
471 clrsetbits_le32(&denali_phy[935], 0x7 << 14, mode_sel << 14);
472 /* PHY_937 PHY_PAD_RST_DRIVE */
473 clrsetbits_le32(&denali_phy[937], 0x7 << 14, mode_sel << 14);
474 /* PHY_939 PHY_PAD_CS_DRIVE */
475 clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
476
YouMin Chende57fbf2019-11-15 11:04:46 +0800477 if (params->base.dramtype == LPDDR4) {
Jagan Teki5d152172019-07-16 17:27:15 +0530478 /* BOOSTP_EN & BOOSTN_EN */
479 reg_value = ((PHY_BOOSTP_EN << 4) | PHY_BOOSTN_EN);
480 /* PHY_925 PHY_PAD_FDBK_DRIVE2 */
481 clrsetbits_le32(&denali_phy[925], 0xff << 8, reg_value << 8);
482 /* PHY_926 PHY_PAD_DATA_DRIVE */
483 clrsetbits_le32(&denali_phy[926], 0xff << 12, reg_value << 12);
484 /* PHY_927 PHY_PAD_DQS_DRIVE */
485 clrsetbits_le32(&denali_phy[927], 0xff << 14, reg_value << 14);
486 /* PHY_928 PHY_PAD_ADDR_DRIVE */
487 clrsetbits_le32(&denali_phy[928], 0xff << 20, reg_value << 20);
488 /* PHY_929 PHY_PAD_CLK_DRIVE */
489 clrsetbits_le32(&denali_phy[929], 0xff << 22, reg_value << 22);
490 /* PHY_935 PHY_PAD_CKE_DRIVE */
491 clrsetbits_le32(&denali_phy[935], 0xff << 20, reg_value << 20);
492 /* PHY_937 PHY_PAD_RST_DRIVE */
493 clrsetbits_le32(&denali_phy[937], 0xff << 20, reg_value << 20);
494 /* PHY_939 PHY_PAD_CS_DRIVE */
495 clrsetbits_le32(&denali_phy[939], 0xff << 20, reg_value << 20);
Jagan Tekid8681842019-07-16 17:27:16 +0530496
497 /* SLEWP_EN & SLEWN_EN */
498 reg_value = ((PHY_SLEWP_EN << 3) | PHY_SLEWN_EN);
499 /* PHY_924 PHY_PAD_FDBK_DRIVE */
500 clrsetbits_le32(&denali_phy[924], 0x3f << 8, reg_value << 8);
501 /* PHY_926 PHY_PAD_DATA_DRIVE */
502 clrsetbits_le32(&denali_phy[926], 0x3f, reg_value);
503 /* PHY_927 PHY_PAD_DQS_DRIVE */
504 clrsetbits_le32(&denali_phy[927], 0x3f, reg_value);
505 /* PHY_928 PHY_PAD_ADDR_DRIVE */
506 clrsetbits_le32(&denali_phy[928], 0x3f << 8, reg_value << 8);
507 /* PHY_929 PHY_PAD_CLK_DRIVE */
508 clrsetbits_le32(&denali_phy[929], 0x3f << 8, reg_value << 8);
509 /* PHY_935 PHY_PAD_CKE_DRIVE */
510 clrsetbits_le32(&denali_phy[935], 0x3f << 8, reg_value << 8);
511 /* PHY_937 PHY_PAD_RST_DRIVE */
512 clrsetbits_le32(&denali_phy[937], 0x3f << 8, reg_value << 8);
513 /* PHY_939 PHY_PAD_CS_DRIVE */
514 clrsetbits_le32(&denali_phy[939], 0x3f << 8, reg_value << 8);
Jagan Teki5d152172019-07-16 17:27:15 +0530515 }
516
Jagan Tekib5d46632019-07-16 17:27:07 +0530517 /* speed setting */
YouMin Chen79f4d912019-11-15 11:04:53 +0800518 speed = 0x2;
Jagan Tekib5d46632019-07-16 17:27:07 +0530519
520 /* PHY_924 PHY_PAD_FDBK_DRIVE */
521 clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
522 /* PHY_926 PHY_PAD_DATA_DRIVE */
523 clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
524 /* PHY_927 PHY_PAD_DQS_DRIVE */
525 clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
526 /* PHY_928 PHY_PAD_ADDR_DRIVE */
527 clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
528 /* PHY_929 PHY_PAD_CLK_DRIVE */
529 clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
530 /* PHY_935 PHY_PAD_CKE_DRIVE */
531 clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
532 /* PHY_937 PHY_PAD_RST_DRIVE */
533 clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
534 /* PHY_939 PHY_PAD_CS_DRIVE */
535 clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
536
YouMin Chende57fbf2019-11-15 11:04:46 +0800537 if (params->base.dramtype == LPDDR4) {
Jagan Teki65535a22019-07-16 17:27:17 +0530538 /* RX_CM_INPUT */
539 reg_value = PHY_RX_CM_INPUT;
540 /* PHY_924 PHY_PAD_FDBK_DRIVE */
541 clrsetbits_le32(&denali_phy[924], 0x1 << 14, reg_value << 14);
542 /* PHY_926 PHY_PAD_DATA_DRIVE */
543 clrsetbits_le32(&denali_phy[926], 0x1 << 11, reg_value << 11);
544 /* PHY_927 PHY_PAD_DQS_DRIVE */
545 clrsetbits_le32(&denali_phy[927], 0x1 << 13, reg_value << 13);
546 /* PHY_928 PHY_PAD_ADDR_DRIVE */
547 clrsetbits_le32(&denali_phy[928], 0x1 << 19, reg_value << 19);
548 /* PHY_929 PHY_PAD_CLK_DRIVE */
549 clrsetbits_le32(&denali_phy[929], 0x1 << 21, reg_value << 21);
550 /* PHY_935 PHY_PAD_CKE_DRIVE */
551 clrsetbits_le32(&denali_phy[935], 0x1 << 19, reg_value << 19);
552 /* PHY_937 PHY_PAD_RST_DRIVE */
553 clrsetbits_le32(&denali_phy[937], 0x1 << 19, reg_value << 19);
554 /* PHY_939 PHY_PAD_CS_DRIVE */
555 clrsetbits_le32(&denali_phy[939], 0x1 << 19, reg_value << 19);
556 }
557
Jagan Tekib5d46632019-07-16 17:27:07 +0530558 return 0;
559}
560
Kever Yang50fb9982017-02-22 16:56:35 +0800561static void set_ds_odt(const struct chan_info *chan,
Jagan Teki6ea82692019-07-16 17:27:40 +0530562 struct rk3399_sdram_params *params,
563 bool ctl_phy_reg, u32 mr5)
Kever Yang50fb9982017-02-22 16:56:35 +0800564{
Jagan Teki6ea82692019-07-16 17:27:40 +0530565 u32 *denali_phy = get_denali_phy(chan, params, ctl_phy_reg);
566 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
Kever Yang50fb9982017-02-22 16:56:35 +0800567 u32 tsel_idle_en, tsel_wr_en, tsel_rd_en;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530568 u32 tsel_idle_select_p, tsel_rd_select_p;
569 u32 tsel_idle_select_n, tsel_rd_select_n;
570 u32 tsel_wr_select_dq_p, tsel_wr_select_ca_p;
571 u32 tsel_wr_select_dq_n, tsel_wr_select_ca_n;
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530572 u32 tsel_ckcs_select_p, tsel_ckcs_select_n;
Jagan Tekid33056b2019-07-16 17:27:22 +0530573 struct io_setting *io = NULL;
Jagan Teki0cb31122019-07-16 17:27:24 +0530574 u32 soc_odt = 0;
Kever Yang50fb9982017-02-22 16:56:35 +0800575 u32 reg_value;
576
Jagan Tekia58ff792019-07-15 23:50:58 +0530577 if (params->base.dramtype == LPDDR4) {
Jagan Tekid33056b2019-07-16 17:27:22 +0530578 io = lpddr4_get_io_settings(params, mr5);
579
Jagan Tekif676c7c2019-07-15 23:50:56 +0530580 tsel_rd_select_p = PHY_DRV_ODT_HI_Z;
Jagan Tekid33056b2019-07-16 17:27:22 +0530581 tsel_rd_select_n = io->rd_odt;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530582
Jagan Tekif676c7c2019-07-15 23:50:56 +0530583 tsel_idle_select_p = PHY_DRV_ODT_HI_Z;
Kever Yangbc9b1562019-11-15 11:04:51 +0800584 tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
Kever Yang50fb9982017-02-22 16:56:35 +0800585
Jagan Tekid33056b2019-07-16 17:27:22 +0530586 tsel_wr_select_dq_p = io->wr_dq_drv;
Kever Yangbc9b1562019-11-15 11:04:51 +0800587 tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530588
Jagan Tekid33056b2019-07-16 17:27:22 +0530589 tsel_wr_select_ca_p = io->wr_ca_drv;
Kever Yangbc9b1562019-11-15 11:04:51 +0800590 tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530591
592 tsel_ckcs_select_p = io->wr_ckcs_drv;
593 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Kever Yangbc9b1562019-11-15 11:04:51 +0800594
Jagan Teki0cb31122019-07-16 17:27:24 +0530595 switch (tsel_rd_select_n) {
596 case PHY_DRV_ODT_240:
597 soc_odt = 1;
598 break;
599 case PHY_DRV_ODT_120:
600 soc_odt = 2;
601 break;
602 case PHY_DRV_ODT_80:
603 soc_odt = 3;
604 break;
605 case PHY_DRV_ODT_60:
606 soc_odt = 4;
607 break;
608 case PHY_DRV_ODT_48:
609 soc_odt = 5;
610 break;
611 case PHY_DRV_ODT_40:
612 soc_odt = 6;
613 break;
614 case PHY_DRV_ODT_34_3:
615 soc_odt = 6;
616 printf("%s: Unable to support LPDDR4 MR22 Soc ODT\n",
617 __func__);
618 break;
619 case PHY_DRV_ODT_HI_Z:
620 default:
621 soc_odt = 0;
622 break;
623 }
Jagan Tekia58ff792019-07-15 23:50:58 +0530624 } else if (params->base.dramtype == LPDDR3) {
Kever Yang50fb9982017-02-22 16:56:35 +0800625 tsel_rd_select_p = PHY_DRV_ODT_240;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530626 tsel_rd_select_n = PHY_DRV_ODT_HI_Z;
627
Kever Yang50fb9982017-02-22 16:56:35 +0800628 tsel_idle_select_p = PHY_DRV_ODT_240;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530629 tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
Kever Yang50fb9982017-02-22 16:56:35 +0800630
Jagan Teki5c3251f2019-07-15 23:51:04 +0530631 tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
Jagan Teki36667142019-07-15 23:51:00 +0530632 tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530633
Kever Yangbc9b1562019-11-15 11:04:51 +0800634 tsel_wr_select_ca_p = PHY_DRV_ODT_34_3;
635 tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530636
637 tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
638 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Kever Yang50fb9982017-02-22 16:56:35 +0800639 } else {
640 tsel_rd_select_p = PHY_DRV_ODT_240;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530641 tsel_rd_select_n = PHY_DRV_ODT_240;
642
Kever Yang50fb9982017-02-22 16:56:35 +0800643 tsel_idle_select_p = PHY_DRV_ODT_240;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530644 tsel_idle_select_n = PHY_DRV_ODT_240;
Kever Yang50fb9982017-02-22 16:56:35 +0800645
Jagan Teki5c3251f2019-07-15 23:51:04 +0530646 tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
Jagan Teki36667142019-07-15 23:51:00 +0530647 tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
Jagan Teki5c3251f2019-07-15 23:51:04 +0530648
649 tsel_wr_select_ca_p = PHY_DRV_ODT_34_3;
Jagan Teki0fd5efb2019-07-15 23:51:02 +0530650 tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530651
652 tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
653 tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
Kever Yang50fb9982017-02-22 16:56:35 +0800654 }
655
Jagan Tekib9584172019-07-16 17:27:25 +0530656 if (params->base.odt == 1) {
Kever Yang50fb9982017-02-22 16:56:35 +0800657 tsel_rd_en = 1;
Jagan Tekib9584172019-07-16 17:27:25 +0530658
659 if (params->base.dramtype == LPDDR4)
660 tsel_rd_en = io->rd_odt_en;
661 } else {
Kever Yang50fb9982017-02-22 16:56:35 +0800662 tsel_rd_en = 0;
Jagan Tekib9584172019-07-16 17:27:25 +0530663 }
Kever Yang50fb9982017-02-22 16:56:35 +0800664
665 tsel_wr_en = 0;
666 tsel_idle_en = 0;
667
Jagan Teki0cb31122019-07-16 17:27:24 +0530668 /* F0_0 */
669 clrsetbits_le32(&denali_ctl[145], 0xFF << 16,
670 (soc_odt | (CS0_MR22_VAL << 3)) << 16);
671 /* F2_0, F1_0 */
672 clrsetbits_le32(&denali_ctl[146], 0xFF00FF,
673 ((soc_odt | (CS0_MR22_VAL << 3)) << 16) |
674 (soc_odt | (CS0_MR22_VAL << 3)));
675 /* F0_1 */
676 clrsetbits_le32(&denali_ctl[159], 0xFF << 16,
677 (soc_odt | (CS1_MR22_VAL << 3)) << 16);
678 /* F2_1, F1_1 */
679 clrsetbits_le32(&denali_ctl[160], 0xFF00FF,
680 ((soc_odt | (CS1_MR22_VAL << 3)) << 16) |
681 (soc_odt | (CS1_MR22_VAL << 3)));
682
Kever Yang50fb9982017-02-22 16:56:35 +0800683 /*
684 * phy_dq_tsel_select_X 24bits DENALI_PHY_6/134/262/390 offset_0
685 * sets termination values for read/idle cycles and drive strength
686 * for write cycles for DQ/DM
687 */
688 reg_value = tsel_rd_select_n | (tsel_rd_select_p << 0x4) |
Jagan Tekib3b34392019-07-15 23:51:01 +0530689 (tsel_wr_select_dq_n << 8) | (tsel_wr_select_dq_p << 12) |
Kever Yang50fb9982017-02-22 16:56:35 +0800690 (tsel_idle_select_n << 16) | (tsel_idle_select_p << 20);
691 clrsetbits_le32(&denali_phy[6], 0xffffff, reg_value);
692 clrsetbits_le32(&denali_phy[134], 0xffffff, reg_value);
693 clrsetbits_le32(&denali_phy[262], 0xffffff, reg_value);
694 clrsetbits_le32(&denali_phy[390], 0xffffff, reg_value);
695
696 /*
697 * phy_dqs_tsel_select_X 24bits DENALI_PHY_7/135/263/391 offset_0
698 * sets termination values for read/idle cycles and drive strength
699 * for write cycles for DQS
700 */
701 clrsetbits_le32(&denali_phy[7], 0xffffff, reg_value);
702 clrsetbits_le32(&denali_phy[135], 0xffffff, reg_value);
703 clrsetbits_le32(&denali_phy[263], 0xffffff, reg_value);
704 clrsetbits_le32(&denali_phy[391], 0xffffff, reg_value);
705
706 /* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
Jagan Teki7caa3e92019-07-15 23:51:03 +0530707 reg_value = tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 0x4);
YouMin Chende57fbf2019-11-15 11:04:46 +0800708 if (params->base.dramtype == LPDDR4) {
Jagan Teki539ffed2019-07-16 17:27:19 +0530709 /* LPDDR4 these register read always return 0, so
710 * can not use clrsetbits_le32(), need to write32
711 */
712 writel((0x300 << 8) | reg_value, &denali_phy[544]);
713 writel((0x300 << 8) | reg_value, &denali_phy[672]);
714 writel((0x300 << 8) | reg_value, &denali_phy[800]);
715 } else {
716 clrsetbits_le32(&denali_phy[544], 0xff, reg_value);
717 clrsetbits_le32(&denali_phy[672], 0xff, reg_value);
718 clrsetbits_le32(&denali_phy[800], 0xff, reg_value);
719 }
Kever Yang50fb9982017-02-22 16:56:35 +0800720
721 /* phy_pad_addr_drive 8bits DENALI_PHY_928 offset_0 */
722 clrsetbits_le32(&denali_phy[928], 0xff, reg_value);
723
724 /* phy_pad_rst_drive 8bits DENALI_PHY_937 offset_0 */
Jagan Teki6ea82692019-07-16 17:27:40 +0530725 if (!ctl_phy_reg)
726 clrsetbits_le32(&denali_phy[937], 0xff, reg_value);
Kever Yang50fb9982017-02-22 16:56:35 +0800727
728 /* phy_pad_cke_drive 8bits DENALI_PHY_935 offset_0 */
729 clrsetbits_le32(&denali_phy[935], 0xff, reg_value);
730
731 /* phy_pad_cs_drive 8bits DENALI_PHY_939 offset_0 */
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530732 clrsetbits_le32(&denali_phy[939], 0xff,
733 tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
Kever Yang50fb9982017-02-22 16:56:35 +0800734
735 /* phy_pad_clk_drive 8bits DENALI_PHY_929 offset_0 */
Jagan Tekic7ffdb72019-07-16 17:27:23 +0530736 clrsetbits_le32(&denali_phy[929], 0xff,
737 tsel_ckcs_select_n | (tsel_ckcs_select_p << 0x4));
Kever Yang50fb9982017-02-22 16:56:35 +0800738
739 /* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
740 clrsetbits_le32(&denali_phy[924], 0xff,
YouMin Chen79f4d912019-11-15 11:04:53 +0800741 tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 4));
Kever Yang50fb9982017-02-22 16:56:35 +0800742 clrsetbits_le32(&denali_phy[925], 0xff,
YouMin Chen79f4d912019-11-15 11:04:53 +0800743 tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
Kever Yang50fb9982017-02-22 16:56:35 +0800744
745 /* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
746 reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
747 << 16;
748 clrsetbits_le32(&denali_phy[5], 0x7 << 16, reg_value);
749 clrsetbits_le32(&denali_phy[133], 0x7 << 16, reg_value);
750 clrsetbits_le32(&denali_phy[261], 0x7 << 16, reg_value);
751 clrsetbits_le32(&denali_phy[389], 0x7 << 16, reg_value);
752
753 /* phy_dqs_tsel_enable_X 3bits DENALI_PHY_6/134/262/390 offset_24 */
754 reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
755 << 24;
756 clrsetbits_le32(&denali_phy[6], 0x7 << 24, reg_value);
757 clrsetbits_le32(&denali_phy[134], 0x7 << 24, reg_value);
758 clrsetbits_le32(&denali_phy[262], 0x7 << 24, reg_value);
759 clrsetbits_le32(&denali_phy[390], 0x7 << 24, reg_value);
760
761 /* phy_adr_tsel_enable_ 1bit DENALI_PHY_518/646/774 offset_8 */
762 reg_value = tsel_wr_en << 8;
763 clrsetbits_le32(&denali_phy[518], 0x1 << 8, reg_value);
764 clrsetbits_le32(&denali_phy[646], 0x1 << 8, reg_value);
765 clrsetbits_le32(&denali_phy[774], 0x1 << 8, reg_value);
766
767 /* phy_pad_addr_term tsel 1bit DENALI_PHY_933 offset_17 */
768 reg_value = tsel_wr_en << 17;
769 clrsetbits_le32(&denali_phy[933], 0x1 << 17, reg_value);
770 /*
771 * pad_rst/cke/cs/clk_term tsel 1bits
772 * DENALI_PHY_938/936/940/934 offset_17
773 */
774 clrsetbits_le32(&denali_phy[938], 0x1 << 17, reg_value);
775 clrsetbits_le32(&denali_phy[936], 0x1 << 17, reg_value);
776 clrsetbits_le32(&denali_phy[940], 0x1 << 17, reg_value);
777 clrsetbits_le32(&denali_phy[934], 0x1 << 17, reg_value);
778
779 /* phy_pad_fdbk_term 1bit DENALI_PHY_930 offset_17 */
780 clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value);
Jagan Tekib5d46632019-07-16 17:27:07 +0530781
Thomas Hebbd8105ab2019-12-20 12:28:15 -0800782 phy_io_config(denali_phy, denali_ctl, params, mr5);
Kever Yang50fb9982017-02-22 16:56:35 +0800783}
784
YouMin Chen99027372019-11-15 11:04:48 +0800785static void pctl_start(struct dram_info *dram,
786 struct rk3399_sdram_params *params,
787 u32 channel_mask)
Jagan Tekic9151e22019-07-15 23:58:45 +0530788{
YouMin Chen99027372019-11-15 11:04:48 +0800789 const struct chan_info *chan_0 = &dram->chan[0];
790 const struct chan_info *chan_1 = &dram->chan[1];
791
792 u32 *denali_ctl_0 = chan_0->pctl->denali_ctl;
793 u32 *denali_phy_0 = chan_0->publ->denali_phy;
794 u32 *ddrc0_con_0 = get_ddrc0_con(dram, 0);
795 u32 *denali_ctl_1 = chan_1->pctl->denali_ctl;
796 u32 *denali_phy_1 = chan_1->publ->denali_phy;
797 u32 *ddrc1_con_0 = get_ddrc0_con(dram, 1);
Jagan Tekic9151e22019-07-15 23:58:45 +0530798 u32 count = 0;
799 u32 byte, tmp;
800
YouMin Chen99027372019-11-15 11:04:48 +0800801 /* PHY_DLL_RST_EN */
802 if (channel_mask & 1) {
803 writel(0x01000000, &ddrc0_con_0);
804 clrsetbits_le32(&denali_phy_0[957], 0x3 << 24, 0x2 << 24);
805 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530806
YouMin Chen99027372019-11-15 11:04:48 +0800807 if (channel_mask & 1) {
808 count = 0;
809 while (!(readl(&denali_ctl_0[203]) & (1 << 3))) {
810 if (count > 1000) {
811 printf("%s: Failed to init pctl channel 0\n",
812 __func__);
813 while (1)
814 ;
815 }
816 udelay(1);
817 count++;
818 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530819
YouMin Chen99027372019-11-15 11:04:48 +0800820 writel(0x01000100, &ddrc0_con_0);
821 for (byte = 0; byte < 4; byte++) {
822 tmp = 0x820;
823 writel((tmp << 16) | tmp,
824 &denali_phy_0[53 + (128 * byte)]);
825 writel((tmp << 16) | tmp,
826 &denali_phy_0[54 + (128 * byte)]);
827 writel((tmp << 16) | tmp,
828 &denali_phy_0[55 + (128 * byte)]);
829 writel((tmp << 16) | tmp,
830 &denali_phy_0[56 + (128 * byte)]);
831 writel((tmp << 16) | tmp,
832 &denali_phy_0[57 + (128 * byte)]);
833 clrsetbits_le32(&denali_phy_0[58 + (128 * byte)],
834 0xffff, tmp);
Jagan Tekic9151e22019-07-15 23:58:45 +0530835 }
YouMin Chen99027372019-11-15 11:04:48 +0800836 clrsetbits_le32(&denali_ctl_0[68], PWRUP_SREFRESH_EXIT,
837 dram->pwrup_srefresh_exit[0]);
838 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530839
YouMin Chen99027372019-11-15 11:04:48 +0800840 if (channel_mask & 2) {
841 writel(0x01000000, &ddrc1_con_0);
842 clrsetbits_le32(&denali_phy_1[957], 0x3 << 24, 0x2 << 24);
Jagan Tekic9151e22019-07-15 23:58:45 +0530843 }
YouMin Chen99027372019-11-15 11:04:48 +0800844 if (channel_mask & 2) {
845 count = 0;
846 while (!(readl(&denali_ctl_1[203]) & (1 << 3))) {
847 if (count > 1000) {
848 printf("%s: Failed to init pctl channel 1\n",
849 __func__);
850 while (1)
851 ;
852 }
853 udelay(1);
854 count++;
855 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530856
YouMin Chen99027372019-11-15 11:04:48 +0800857 writel(0x01000100, &ddrc1_con_0);
858 for (byte = 0; byte < 4; byte++) {
859 tmp = 0x820;
860 writel((tmp << 16) | tmp,
861 &denali_phy_1[53 + (128 * byte)]);
862 writel((tmp << 16) | tmp,
863 &denali_phy_1[54 + (128 * byte)]);
864 writel((tmp << 16) | tmp,
865 &denali_phy_1[55 + (128 * byte)]);
866 writel((tmp << 16) | tmp,
867 &denali_phy_1[56 + (128 * byte)]);
868 writel((tmp << 16) | tmp,
869 &denali_phy_1[57 + (128 * byte)]);
870 clrsetbits_le32(&denali_phy_1[58 + (128 * byte)],
871 0xffff, tmp);
872 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530873
YouMin Chen99027372019-11-15 11:04:48 +0800874 clrsetbits_le32(&denali_ctl_1[68], PWRUP_SREFRESH_EXIT,
875 dram->pwrup_srefresh_exit[1]);
Jagan Tekic9151e22019-07-15 23:58:45 +0530876
YouMin Chen99027372019-11-15 11:04:48 +0800877 /*
878 * restore channel 1 RESET original setting
879 * to avoid 240ohm too weak to prevent ESD test
880 */
881 if (params->base.dramtype == LPDDR4)
882 clrsetbits_le32(&denali_phy_1[937], 0xff,
883 params->phy_regs.denali_phy[937] &
884 0xFF);
Jagan Tekic9151e22019-07-15 23:58:45 +0530885 }
Jagan Tekic9151e22019-07-15 23:58:45 +0530886}
887
Jagan Teki4ef5c012019-07-15 23:58:44 +0530888static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
Jagan Tekid33056b2019-07-16 17:27:22 +0530889 u32 channel, struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +0800890{
891 u32 *denali_ctl = chan->pctl->denali_ctl;
892 u32 *denali_pi = chan->pi->denali_pi;
893 u32 *denali_phy = chan->publ->denali_phy;
Jagan Tekia58ff792019-07-15 23:50:58 +0530894 const u32 *params_ctl = params->pctl_regs.denali_ctl;
895 const u32 *params_phy = params->phy_regs.denali_phy;
Kever Yang50fb9982017-02-22 16:56:35 +0800896 u32 tmp, tmp1, tmp2;
YouMin Chen99027372019-11-15 11:04:48 +0800897 struct rk3399_sdram_params *params_cfg;
898 u32 byte;
Kever Yang50fb9982017-02-22 16:56:35 +0800899
YouMin Chen99027372019-11-15 11:04:48 +0800900 dram->ops->modify_param(chan, params);
Kever Yang50fb9982017-02-22 16:56:35 +0800901 /*
902 * work around controller bug:
903 * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
904 */
YouMin Chen23ae72e2019-11-15 11:04:45 +0800905 sdram_copy_to_reg(&denali_ctl[1], &params_ctl[1],
906 sizeof(struct rk3399_ddr_pctl_regs) - 4);
Kever Yang50fb9982017-02-22 16:56:35 +0800907 writel(params_ctl[0], &denali_ctl[0]);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +0530908
Jagan Tekicc9da9a2019-07-16 17:27:13 +0530909 /*
910 * two channel init at the same time, then ZQ Cal Start
911 * at the same time, it will use the same RZQ, but cannot
912 * start at the same time.
913 *
914 * So, increase tINIT3 for channel 1, will avoid two
915 * channel ZQ Cal Start at the same time
916 */
917 if (params->base.dramtype == LPDDR4 && channel == 1) {
918 tmp = ((params->base.ddr_freq * MHz + 999) / 1000);
919 tmp1 = readl(&denali_ctl[14]);
920 writel(tmp + tmp1, &denali_ctl[14]);
921 }
922
YouMin Chen23ae72e2019-11-15 11:04:45 +0800923 sdram_copy_to_reg(denali_pi, &params->pi_regs.denali_pi[0],
924 sizeof(struct rk3399_ddr_pi_regs));
Jagan Tekiacf8e0f2019-07-15 23:50:57 +0530925
Kever Yang50fb9982017-02-22 16:56:35 +0800926 /* rank count need to set for init */
Jagan Tekia58ff792019-07-15 23:50:58 +0530927 set_memory_map(chan, channel, params);
Kever Yang50fb9982017-02-22 16:56:35 +0800928
Jagan Tekia58ff792019-07-15 23:50:58 +0530929 writel(params->phy_regs.denali_phy[910], &denali_phy[910]);
930 writel(params->phy_regs.denali_phy[911], &denali_phy[911]);
931 writel(params->phy_regs.denali_phy[912], &denali_phy[912]);
Kever Yang50fb9982017-02-22 16:56:35 +0800932
YouMin Chende57fbf2019-11-15 11:04:46 +0800933 if (params->base.dramtype == LPDDR4) {
Jagan Tekib49b5dc2019-07-16 17:27:14 +0530934 writel(params->phy_regs.denali_phy[898], &denali_phy[898]);
935 writel(params->phy_regs.denali_phy[919], &denali_phy[919]);
936 }
937
Jagan Tekic9151e22019-07-15 23:58:45 +0530938 dram->pwrup_srefresh_exit[channel] = readl(&denali_ctl[68]) &
939 PWRUP_SREFRESH_EXIT;
Kever Yang50fb9982017-02-22 16:56:35 +0800940 clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT);
941
942 /* PHY_DLL_RST_EN */
943 clrsetbits_le32(&denali_phy[957], 0x3 << 24, 1 << 24);
944
945 setbits_le32(&denali_pi[0], START);
946 setbits_le32(&denali_ctl[0], START);
947
Jagan Teki5e927182019-07-16 17:27:12 +0530948 /**
949 * LPDDR4 use PLL bypass mode for init
950 * not need to wait for the PLL to lock
951 */
952 if (params->base.dramtype != LPDDR4) {
953 /* Waiting for phy DLL lock */
954 while (1) {
955 tmp = readl(&denali_phy[920]);
956 tmp1 = readl(&denali_phy[921]);
957 tmp2 = readl(&denali_phy[922]);
958 if ((((tmp >> 16) & 0x1) == 0x1) &&
959 (((tmp1 >> 16) & 0x1) == 0x1) &&
960 (((tmp1 >> 0) & 0x1) == 0x1) &&
961 (((tmp2 >> 0) & 0x1) == 0x1))
962 break;
963 }
Kever Yang50fb9982017-02-22 16:56:35 +0800964 }
965
YouMin Chen23ae72e2019-11-15 11:04:45 +0800966 sdram_copy_to_reg(&denali_phy[896], &params_phy[896], (958 - 895) * 4);
967 sdram_copy_to_reg(&denali_phy[0], &params_phy[0], (90 - 0 + 1) * 4);
968 sdram_copy_to_reg(&denali_phy[128], &params_phy[128],
969 (218 - 128 + 1) * 4);
970 sdram_copy_to_reg(&denali_phy[256], &params_phy[256],
971 (346 - 256 + 1) * 4);
972 sdram_copy_to_reg(&denali_phy[384], &params_phy[384],
973 (474 - 384 + 1) * 4);
974 sdram_copy_to_reg(&denali_phy[512], &params_phy[512],
975 (549 - 512 + 1) * 4);
976 sdram_copy_to_reg(&denali_phy[640], &params_phy[640],
977 (677 - 640 + 1) * 4);
978 sdram_copy_to_reg(&denali_phy[768], &params_phy[768],
979 (805 - 768 + 1) * 4);
980
YouMin Chen99027372019-11-15 11:04:48 +0800981 if (params->base.dramtype == LPDDR4)
982 params_cfg = dram->ops->get_phy_index_params(1, params);
983 else
984 params_cfg = dram->ops->get_phy_index_params(0, params);
Kever Yang50fb9982017-02-22 16:56:35 +0800985
YouMin Chen99027372019-11-15 11:04:48 +0800986 clrsetbits_le32(&params_cfg->phy_regs.denali_phy[896], 0x3 << 8,
987 0 << 8);
988 writel(params_cfg->phy_regs.denali_phy[896], &denali_phy[896]);
Kever Yang50fb9982017-02-22 16:56:35 +0800989
YouMin Chen99027372019-11-15 11:04:48 +0800990 writel(params->phy_regs.denali_phy[83] + (0x10 << 16),
991 &denali_phy[83]);
992 writel(params->phy_regs.denali_phy[84] + (0x10 << 8),
993 &denali_phy[84]);
994 writel(params->phy_regs.denali_phy[211] + (0x10 << 16),
995 &denali_phy[211]);
996 writel(params->phy_regs.denali_phy[212] + (0x10 << 8),
997 &denali_phy[212]);
998 writel(params->phy_regs.denali_phy[339] + (0x10 << 16),
999 &denali_phy[339]);
1000 writel(params->phy_regs.denali_phy[340] + (0x10 << 8),
1001 &denali_phy[340]);
1002 writel(params->phy_regs.denali_phy[467] + (0x10 << 16),
1003 &denali_phy[467]);
1004 writel(params->phy_regs.denali_phy[468] + (0x10 << 8),
1005 &denali_phy[468]);
1006
1007 if (params->base.dramtype == LPDDR4) {
1008 /*
1009 * to improve write dqs and dq phase from 1.5ns to 3.5ns
1010 * at 50MHz. this's the measure result from oscilloscope
1011 * of dqs and dq write signal.
1012 */
1013 for (byte = 0; byte < 4; byte++) {
1014 tmp = 0x680;
1015 clrsetbits_le32(&denali_phy[1 + (128 * byte)],
1016 0xfff << 8, tmp << 8);
1017 }
1018 /*
1019 * to workaround 366ball two channel's RESET connect to
1020 * one RESET signal of die
1021 */
1022 if (channel == 1)
1023 clrsetbits_le32(&denali_phy[937], 0xff,
1024 PHY_DRV_ODT_240 |
1025 (PHY_DRV_ODT_240 << 0x4));
1026 }
Kever Yang50fb9982017-02-22 16:56:35 +08001027
Kever Yang50fb9982017-02-22 16:56:35 +08001028 return 0;
1029}
1030
1031static void select_per_cs_training_index(const struct chan_info *chan,
1032 u32 rank)
1033{
1034 u32 *denali_phy = chan->publ->denali_phy;
1035
1036 /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
Jagan Tekif676c7c2019-07-15 23:50:56 +05301037 if ((readl(&denali_phy[84]) >> 16) & 1) {
Kever Yang50fb9982017-02-22 16:56:35 +08001038 /*
1039 * PHY_8/136/264/392
1040 * phy_per_cs_training_index_X 1bit offset_24
1041 */
1042 clrsetbits_le32(&denali_phy[8], 0x1 << 24, rank << 24);
1043 clrsetbits_le32(&denali_phy[136], 0x1 << 24, rank << 24);
1044 clrsetbits_le32(&denali_phy[264], 0x1 << 24, rank << 24);
1045 clrsetbits_le32(&denali_phy[392], 0x1 << 24, rank << 24);
1046 }
1047}
1048
1049static void override_write_leveling_value(const struct chan_info *chan)
1050{
1051 u32 *denali_ctl = chan->pctl->denali_ctl;
1052 u32 *denali_phy = chan->publ->denali_phy;
1053 u32 byte;
1054
1055 /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
1056 setbits_le32(&denali_phy[896], 1);
1057
1058 /*
1059 * PHY_8/136/264/392
1060 * phy_per_cs_training_multicast_en_X 1bit offset_16
1061 */
1062 clrsetbits_le32(&denali_phy[8], 0x1 << 16, 1 << 16);
1063 clrsetbits_le32(&denali_phy[136], 0x1 << 16, 1 << 16);
1064 clrsetbits_le32(&denali_phy[264], 0x1 << 16, 1 << 16);
1065 clrsetbits_le32(&denali_phy[392], 0x1 << 16, 1 << 16);
1066
1067 for (byte = 0; byte < 4; byte++)
1068 clrsetbits_le32(&denali_phy[63 + (128 * byte)], 0xffff << 16,
1069 0x200 << 16);
1070
1071 /* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
1072 clrbits_le32(&denali_phy[896], 1);
1073
1074 /* CTL_200 ctrlupd_req 1bit offset_8 */
1075 clrsetbits_le32(&denali_ctl[200], 0x1 << 8, 0x1 << 8);
1076}
1077
1078static int data_training_ca(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301079 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001080{
1081 u32 *denali_pi = chan->pi->denali_pi;
1082 u32 *denali_phy = chan->publ->denali_phy;
1083 u32 i, tmp;
1084 u32 obs_0, obs_1, obs_2, obs_err = 0;
Jagan Teki97867c82019-07-15 23:51:05 +05301085 u32 rank = params->ch[channel].cap_info.rank;
Jagan Tekibafcc142019-07-15 23:58:41 +05301086 u32 rank_mask;
Kever Yang50fb9982017-02-22 16:56:35 +08001087
Jagan Tekia6079612019-07-15 23:58:40 +05301088 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1089 writel(0x00003f7c, (&denali_pi[175]));
1090
Jagan Tekif05675e2019-07-16 17:27:09 +05301091 if (params->base.dramtype == LPDDR4)
1092 rank_mask = (rank == 1) ? 0x5 : 0xf;
1093 else
1094 rank_mask = (rank == 1) ? 0x1 : 0x3;
Jagan Tekibafcc142019-07-15 23:58:41 +05301095
1096 for (i = 0; i < 4; i++) {
1097 if (!(rank_mask & (1 << i)))
1098 continue;
1099
Kever Yang50fb9982017-02-22 16:56:35 +08001100 select_per_cs_training_index(chan, i);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301101
Kever Yang50fb9982017-02-22 16:56:35 +08001102 /* PI_100 PI_CALVL_EN:RW:8:2 */
1103 clrsetbits_le32(&denali_pi[100], 0x3 << 8, 0x2 << 8);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301104
Kever Yang50fb9982017-02-22 16:56:35 +08001105 /* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
1106 clrsetbits_le32(&denali_pi[92],
1107 (0x1 << 16) | (0x3 << 24),
1108 (0x1 << 16) | (i << 24));
1109
1110 /* Waiting for training complete */
1111 while (1) {
1112 /* PI_174 PI_INT_STATUS:RD:8:18 */
1113 tmp = readl(&denali_pi[174]) >> 8;
1114 /*
1115 * check status obs
1116 * PHY_532/660/789 phy_adr_calvl_obs1_:0:32
1117 */
1118 obs_0 = readl(&denali_phy[532]);
1119 obs_1 = readl(&denali_phy[660]);
1120 obs_2 = readl(&denali_phy[788]);
1121 if (((obs_0 >> 30) & 0x3) ||
1122 ((obs_1 >> 30) & 0x3) ||
1123 ((obs_2 >> 30) & 0x3))
1124 obs_err = 1;
1125 if ((((tmp >> 11) & 0x1) == 0x1) &&
1126 (((tmp >> 13) & 0x1) == 0x1) &&
1127 (((tmp >> 5) & 0x1) == 0x0) &&
Jagan Tekif676c7c2019-07-15 23:50:56 +05301128 obs_err == 0)
Kever Yang50fb9982017-02-22 16:56:35 +08001129 break;
1130 else if ((((tmp >> 5) & 0x1) == 0x1) ||
1131 (obs_err == 1))
1132 return -EIO;
1133 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301134
Kever Yang50fb9982017-02-22 16:56:35 +08001135 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1136 writel(0x00003f7c, (&denali_pi[175]));
1137 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301138
Kever Yang50fb9982017-02-22 16:56:35 +08001139 clrbits_le32(&denali_pi[100], 0x3 << 8);
1140
1141 return 0;
1142}
1143
1144static int data_training_wl(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301145 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001146{
1147 u32 *denali_pi = chan->pi->denali_pi;
1148 u32 *denali_phy = chan->publ->denali_phy;
1149 u32 i, tmp;
1150 u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
Jagan Teki97867c82019-07-15 23:51:05 +05301151 u32 rank = params->ch[channel].cap_info.rank;
Kever Yang50fb9982017-02-22 16:56:35 +08001152
Jagan Tekia6079612019-07-15 23:58:40 +05301153 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1154 writel(0x00003f7c, (&denali_pi[175]));
1155
Kever Yang50fb9982017-02-22 16:56:35 +08001156 for (i = 0; i < rank; i++) {
1157 select_per_cs_training_index(chan, i);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301158
Kever Yang50fb9982017-02-22 16:56:35 +08001159 /* PI_60 PI_WRLVL_EN:RW:8:2 */
1160 clrsetbits_le32(&denali_pi[60], 0x3 << 8, 0x2 << 8);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301161
Kever Yang50fb9982017-02-22 16:56:35 +08001162 /* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
1163 clrsetbits_le32(&denali_pi[59],
1164 (0x1 << 8) | (0x3 << 16),
1165 (0x1 << 8) | (i << 16));
1166
1167 /* Waiting for training complete */
1168 while (1) {
1169 /* PI_174 PI_INT_STATUS:RD:8:18 */
1170 tmp = readl(&denali_pi[174]) >> 8;
1171
1172 /*
1173 * check status obs, if error maybe can not
1174 * get leveling done PHY_40/168/296/424
1175 * phy_wrlvl_status_obs_X:0:13
1176 */
1177 obs_0 = readl(&denali_phy[40]);
1178 obs_1 = readl(&denali_phy[168]);
1179 obs_2 = readl(&denali_phy[296]);
1180 obs_3 = readl(&denali_phy[424]);
1181 if (((obs_0 >> 12) & 0x1) ||
1182 ((obs_1 >> 12) & 0x1) ||
1183 ((obs_2 >> 12) & 0x1) ||
1184 ((obs_3 >> 12) & 0x1))
1185 obs_err = 1;
1186 if ((((tmp >> 10) & 0x1) == 0x1) &&
1187 (((tmp >> 13) & 0x1) == 0x1) &&
1188 (((tmp >> 4) & 0x1) == 0x0) &&
Jagan Tekif676c7c2019-07-15 23:50:56 +05301189 obs_err == 0)
Kever Yang50fb9982017-02-22 16:56:35 +08001190 break;
1191 else if ((((tmp >> 4) & 0x1) == 0x1) ||
1192 (obs_err == 1))
1193 return -EIO;
1194 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301195
Kever Yang50fb9982017-02-22 16:56:35 +08001196 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1197 writel(0x00003f7c, (&denali_pi[175]));
1198 }
1199
1200 override_write_leveling_value(chan);
1201 clrbits_le32(&denali_pi[60], 0x3 << 8);
1202
1203 return 0;
1204}
1205
1206static int data_training_rg(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301207 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001208{
1209 u32 *denali_pi = chan->pi->denali_pi;
1210 u32 *denali_phy = chan->publ->denali_phy;
1211 u32 i, tmp;
1212 u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0;
Jagan Teki97867c82019-07-15 23:51:05 +05301213 u32 rank = params->ch[channel].cap_info.rank;
Kever Yang50fb9982017-02-22 16:56:35 +08001214
Jagan Tekia6079612019-07-15 23:58:40 +05301215 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1216 writel(0x00003f7c, (&denali_pi[175]));
1217
Kever Yang50fb9982017-02-22 16:56:35 +08001218 for (i = 0; i < rank; i++) {
1219 select_per_cs_training_index(chan, i);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301220
Kever Yang50fb9982017-02-22 16:56:35 +08001221 /* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
1222 clrsetbits_le32(&denali_pi[80], 0x3 << 24, 0x2 << 24);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301223
Kever Yang50fb9982017-02-22 16:56:35 +08001224 /*
1225 * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
1226 * PI_RDLVL_CS:RW:24:2
1227 */
1228 clrsetbits_le32(&denali_pi[74],
1229 (0x1 << 16) | (0x3 << 24),
1230 (0x1 << 16) | (i << 24));
1231
1232 /* Waiting for training complete */
1233 while (1) {
1234 /* PI_174 PI_INT_STATUS:RD:8:18 */
1235 tmp = readl(&denali_pi[174]) >> 8;
1236
1237 /*
1238 * check status obs
1239 * PHY_43/171/299/427
1240 * PHY_GTLVL_STATUS_OBS_x:16:8
1241 */
1242 obs_0 = readl(&denali_phy[43]);
1243 obs_1 = readl(&denali_phy[171]);
1244 obs_2 = readl(&denali_phy[299]);
1245 obs_3 = readl(&denali_phy[427]);
1246 if (((obs_0 >> (16 + 6)) & 0x3) ||
1247 ((obs_1 >> (16 + 6)) & 0x3) ||
1248 ((obs_2 >> (16 + 6)) & 0x3) ||
1249 ((obs_3 >> (16 + 6)) & 0x3))
1250 obs_err = 1;
1251 if ((((tmp >> 9) & 0x1) == 0x1) &&
1252 (((tmp >> 13) & 0x1) == 0x1) &&
1253 (((tmp >> 3) & 0x1) == 0x0) &&
Jagan Tekif676c7c2019-07-15 23:50:56 +05301254 obs_err == 0)
Kever Yang50fb9982017-02-22 16:56:35 +08001255 break;
1256 else if ((((tmp >> 3) & 0x1) == 0x1) ||
1257 (obs_err == 1))
1258 return -EIO;
1259 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301260
Kever Yang50fb9982017-02-22 16:56:35 +08001261 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1262 writel(0x00003f7c, (&denali_pi[175]));
1263 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301264
Kever Yang50fb9982017-02-22 16:56:35 +08001265 clrbits_le32(&denali_pi[80], 0x3 << 24);
1266
1267 return 0;
1268}
1269
1270static int data_training_rl(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301271 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001272{
1273 u32 *denali_pi = chan->pi->denali_pi;
1274 u32 i, tmp;
Jagan Teki97867c82019-07-15 23:51:05 +05301275 u32 rank = params->ch[channel].cap_info.rank;
Kever Yang50fb9982017-02-22 16:56:35 +08001276
Jagan Tekia6079612019-07-15 23:58:40 +05301277 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1278 writel(0x00003f7c, (&denali_pi[175]));
1279
Kever Yang50fb9982017-02-22 16:56:35 +08001280 for (i = 0; i < rank; i++) {
1281 select_per_cs_training_index(chan, i);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301282
Kever Yang50fb9982017-02-22 16:56:35 +08001283 /* PI_80 PI_RDLVL_EN:RW:16:2 */
1284 clrsetbits_le32(&denali_pi[80], 0x3 << 16, 0x2 << 16);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301285
Kever Yang50fb9982017-02-22 16:56:35 +08001286 /* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
1287 clrsetbits_le32(&denali_pi[74],
1288 (0x1 << 8) | (0x3 << 24),
1289 (0x1 << 8) | (i << 24));
1290
1291 /* Waiting for training complete */
1292 while (1) {
1293 /* PI_174 PI_INT_STATUS:RD:8:18 */
1294 tmp = readl(&denali_pi[174]) >> 8;
1295
1296 /*
1297 * make sure status obs not report error bit
1298 * PHY_46/174/302/430
1299 * phy_rdlvl_status_obs_X:16:8
1300 */
1301 if ((((tmp >> 8) & 0x1) == 0x1) &&
1302 (((tmp >> 13) & 0x1) == 0x1) &&
1303 (((tmp >> 2) & 0x1) == 0x0))
1304 break;
1305 else if (((tmp >> 2) & 0x1) == 0x1)
1306 return -EIO;
1307 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301308
Kever Yang50fb9982017-02-22 16:56:35 +08001309 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1310 writel(0x00003f7c, (&denali_pi[175]));
1311 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301312
Kever Yang50fb9982017-02-22 16:56:35 +08001313 clrbits_le32(&denali_pi[80], 0x3 << 16);
1314
1315 return 0;
1316}
1317
1318static int data_training_wdql(const struct chan_info *chan, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301319 const struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001320{
1321 u32 *denali_pi = chan->pi->denali_pi;
1322 u32 i, tmp;
Jagan Teki97867c82019-07-15 23:51:05 +05301323 u32 rank = params->ch[channel].cap_info.rank;
Jagan Teki87723592019-07-15 23:58:42 +05301324 u32 rank_mask;
Kever Yang50fb9982017-02-22 16:56:35 +08001325
Jagan Tekia6079612019-07-15 23:58:40 +05301326 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1327 writel(0x00003f7c, (&denali_pi[175]));
1328
Jagan Tekid7504c02019-07-16 17:27:10 +05301329 if (params->base.dramtype == LPDDR4)
1330 rank_mask = (rank == 1) ? 0x5 : 0xf;
1331 else
1332 rank_mask = (rank == 1) ? 0x1 : 0x3;
Jagan Teki87723592019-07-15 23:58:42 +05301333
1334 for (i = 0; i < 4; i++) {
1335 if (!(rank_mask & (1 << i)))
1336 continue;
1337
Kever Yang50fb9982017-02-22 16:56:35 +08001338 select_per_cs_training_index(chan, i);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301339
Kever Yang50fb9982017-02-22 16:56:35 +08001340 /*
1341 * disable PI_WDQLVL_VREF_EN before wdq leveling?
YouMin Chen79f4d912019-11-15 11:04:53 +08001342 * PI_117 PI_WDQLVL_VREF_EN:RW:8:1
Kever Yang50fb9982017-02-22 16:56:35 +08001343 */
YouMin Chen79f4d912019-11-15 11:04:53 +08001344 clrbits_le32(&denali_pi[117], 0x1 << 8);
Kever Yang50fb9982017-02-22 16:56:35 +08001345 /* PI_124 PI_WDQLVL_EN:RW:16:2 */
1346 clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301347
Kever Yang50fb9982017-02-22 16:56:35 +08001348 /* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
1349 clrsetbits_le32(&denali_pi[121],
1350 (0x1 << 8) | (0x3 << 16),
1351 (0x1 << 8) | (i << 16));
1352
1353 /* Waiting for training complete */
1354 while (1) {
1355 /* PI_174 PI_INT_STATUS:RD:8:18 */
1356 tmp = readl(&denali_pi[174]) >> 8;
1357 if ((((tmp >> 12) & 0x1) == 0x1) &&
1358 (((tmp >> 13) & 0x1) == 0x1) &&
1359 (((tmp >> 6) & 0x1) == 0x0))
1360 break;
1361 else if (((tmp >> 6) & 0x1) == 0x1)
1362 return -EIO;
1363 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301364
Kever Yang50fb9982017-02-22 16:56:35 +08001365 /* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
1366 writel(0x00003f7c, (&denali_pi[175]));
1367 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05301368
Kever Yang50fb9982017-02-22 16:56:35 +08001369 clrbits_le32(&denali_pi[124], 0x3 << 16);
1370
1371 return 0;
1372}
1373
Jagan Teki5ff7abe2019-07-16 17:27:29 +05301374static int data_training(struct dram_info *dram, u32 channel,
Jagan Tekia58ff792019-07-15 23:50:58 +05301375 const struct rk3399_sdram_params *params,
Kever Yang50fb9982017-02-22 16:56:35 +08001376 u32 training_flag)
1377{
Jagan Teki5ff7abe2019-07-16 17:27:29 +05301378 struct chan_info *chan = &dram->chan[channel];
Kever Yang50fb9982017-02-22 16:56:35 +08001379 u32 *denali_phy = chan->publ->denali_phy;
Jagan Teki6214ff22019-07-15 23:58:39 +05301380 int ret;
Kever Yang50fb9982017-02-22 16:56:35 +08001381
1382 /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
1383 setbits_le32(&denali_phy[927], (1 << 22));
1384
1385 if (training_flag == PI_FULL_TRAINING) {
Jagan Tekia58ff792019-07-15 23:50:58 +05301386 if (params->base.dramtype == LPDDR4) {
Jagan Teki6ea82692019-07-16 17:27:40 +05301387 training_flag = PI_WRITE_LEVELING |
Kever Yang50fb9982017-02-22 16:56:35 +08001388 PI_READ_GATE_TRAINING |
1389 PI_READ_LEVELING | PI_WDQ_LEVELING;
Jagan Tekia58ff792019-07-15 23:50:58 +05301390 } else if (params->base.dramtype == LPDDR3) {
Kever Yang50fb9982017-02-22 16:56:35 +08001391 training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
1392 PI_READ_GATE_TRAINING;
Jagan Tekia58ff792019-07-15 23:50:58 +05301393 } else if (params->base.dramtype == DDR3) {
Kever Yang50fb9982017-02-22 16:56:35 +08001394 training_flag = PI_WRITE_LEVELING |
1395 PI_READ_GATE_TRAINING |
1396 PI_READ_LEVELING;
1397 }
1398 }
1399
1400 /* ca training(LPDDR4,LPDDR3 support) */
Jagan Teki6214ff22019-07-15 23:58:39 +05301401 if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) {
1402 ret = data_training_ca(chan, channel, params);
1403 if (ret < 0) {
1404 debug("%s: data training ca failed\n", __func__);
1405 return ret;
1406 }
1407 }
Kever Yang50fb9982017-02-22 16:56:35 +08001408
1409 /* write leveling(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki6214ff22019-07-15 23:58:39 +05301410 if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) {
1411 ret = data_training_wl(chan, channel, params);
1412 if (ret < 0) {
1413 debug("%s: data training wl failed\n", __func__);
1414 return ret;
1415 }
1416 }
Kever Yang50fb9982017-02-22 16:56:35 +08001417
1418 /* read gate training(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki6214ff22019-07-15 23:58:39 +05301419 if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) {
1420 ret = data_training_rg(chan, channel, params);
1421 if (ret < 0) {
1422 debug("%s: data training rg failed\n", __func__);
1423 return ret;
1424 }
1425 }
Kever Yang50fb9982017-02-22 16:56:35 +08001426
1427 /* read leveling(LPDDR4,LPDDR3,DDR3 support) */
Jagan Teki6214ff22019-07-15 23:58:39 +05301428 if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) {
1429 ret = data_training_rl(chan, channel, params);
1430 if (ret < 0) {
1431 debug("%s: data training rl failed\n", __func__);
1432 return ret;
1433 }
1434 }
Kever Yang50fb9982017-02-22 16:56:35 +08001435
1436 /* wdq leveling(LPDDR4 support) */
Jagan Teki6214ff22019-07-15 23:58:39 +05301437 if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) {
1438 ret = data_training_wdql(chan, channel, params);
1439 if (ret < 0) {
1440 debug("%s: data training wdql failed\n", __func__);
1441 return ret;
1442 }
1443 }
Kever Yang50fb9982017-02-22 16:56:35 +08001444
1445 /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */
1446 clrbits_le32(&denali_phy[927], (1 << 22));
1447
1448 return 0;
1449}
1450
1451static void set_ddrconfig(const struct chan_info *chan,
Jagan Tekia58ff792019-07-15 23:50:58 +05301452 const struct rk3399_sdram_params *params,
Kever Yang50fb9982017-02-22 16:56:35 +08001453 unsigned char channel, u32 ddrconfig)
1454{
1455 /* only need to set ddrconfig */
YouMin Chen23ae72e2019-11-15 11:04:45 +08001456 struct msch_regs *ddr_msch_regs = chan->msch;
Kever Yang50fb9982017-02-22 16:56:35 +08001457 unsigned int cs0_cap = 0;
1458 unsigned int cs1_cap = 0;
1459
Jagan Teki97867c82019-07-15 23:51:05 +05301460 cs0_cap = (1 << (params->ch[channel].cap_info.cs0_row
1461 + params->ch[channel].cap_info.col
1462 + params->ch[channel].cap_info.bk
1463 + params->ch[channel].cap_info.bw - 20));
1464 if (params->ch[channel].cap_info.rank > 1)
1465 cs1_cap = cs0_cap >> (params->ch[channel].cap_info.cs0_row
1466 - params->ch[channel].cap_info.cs1_row);
1467 if (params->ch[channel].cap_info.row_3_4) {
Kever Yang50fb9982017-02-22 16:56:35 +08001468 cs0_cap = cs0_cap * 3 / 4;
1469 cs1_cap = cs1_cap * 3 / 4;
1470 }
1471
1472 writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
1473 writel(((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8),
1474 &ddr_msch_regs->ddrsize);
1475}
1476
YouMin Chen23ae72e2019-11-15 11:04:45 +08001477static void sdram_msch_config(struct msch_regs *msch,
1478 struct sdram_msch_timings *noc_timings)
1479{
1480 writel(noc_timings->ddrtiminga0.d32,
1481 &msch->ddrtiminga0.d32);
1482 writel(noc_timings->ddrtimingb0.d32,
1483 &msch->ddrtimingb0.d32);
1484 writel(noc_timings->ddrtimingc0.d32,
1485 &msch->ddrtimingc0.d32);
1486 writel(noc_timings->devtodev0.d32,
1487 &msch->devtodev0.d32);
1488 writel(noc_timings->ddrmode.d32,
1489 &msch->ddrmode.d32);
1490}
1491
Kever Yang50fb9982017-02-22 16:56:35 +08001492static void dram_all_config(struct dram_info *dram,
YouMin Chen23ae72e2019-11-15 11:04:45 +08001493 struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001494{
Jagan Teki2d337122019-07-16 17:27:00 +05301495 u32 sys_reg2 = 0;
Jagan Teki9d8769c2019-07-16 17:27:01 +05301496 u32 sys_reg3 = 0;
Kever Yang50fb9982017-02-22 16:56:35 +08001497 unsigned int channel, idx;
1498
Kever Yang50fb9982017-02-22 16:56:35 +08001499 for (channel = 0, idx = 0;
Jagan Tekia58ff792019-07-15 23:50:58 +05301500 (idx < params->base.num_channels) && (channel < 2);
Kever Yang50fb9982017-02-22 16:56:35 +08001501 channel++) {
YouMin Chen23ae72e2019-11-15 11:04:45 +08001502 struct msch_regs *ddr_msch_regs;
1503 struct sdram_msch_timings *noc_timing;
Kever Yang50fb9982017-02-22 16:56:35 +08001504
Jagan Teki97867c82019-07-15 23:51:05 +05301505 if (params->ch[channel].cap_info.col == 0)
Kever Yang50fb9982017-02-22 16:56:35 +08001506 continue;
1507 idx++;
YouMin Chen23ae72e2019-11-15 11:04:45 +08001508 sdram_org_config(&params->ch[channel].cap_info,
1509 &params->base, &sys_reg2,
1510 &sys_reg3, channel);
Kever Yang50fb9982017-02-22 16:56:35 +08001511 ddr_msch_regs = dram->chan[channel].msch;
Jagan Tekia58ff792019-07-15 23:50:58 +05301512 noc_timing = &params->ch[channel].noc_timings;
YouMin Chen23ae72e2019-11-15 11:04:45 +08001513 sdram_msch_config(ddr_msch_regs, noc_timing);
Kever Yang50fb9982017-02-22 16:56:35 +08001514
Jagan Tekib02c5482019-07-16 17:27:20 +05301515 /**
1516 * rank 1 memory clock disable (dfi_dram_clk_disable = 1)
1517 *
1518 * The hardware for LPDDR4 with
1519 * - CLK0P/N connect to lower 16-bits
1520 * - CLK1P/N connect to higher 16-bits
1521 *
1522 * dfi dram clk is configured via CLK1P/N, so disabling
1523 * dfi dram clk will disable the CLK1P/N as well for lpddr4.
1524 */
1525 if (params->ch[channel].cap_info.rank == 1 &&
1526 params->base.dramtype != LPDDR4)
Kever Yang50fb9982017-02-22 16:56:35 +08001527 setbits_le32(&dram->chan[channel].pctl->denali_ctl[276],
1528 1 << 17);
1529 }
1530
Jagan Teki2d337122019-07-16 17:27:00 +05301531 writel(sys_reg2, &dram->pmugrf->os_reg2);
Jagan Teki9d8769c2019-07-16 17:27:01 +05301532 writel(sys_reg3, &dram->pmugrf->os_reg3);
Kever Yang50fb9982017-02-22 16:56:35 +08001533 rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10,
Jagan Tekia58ff792019-07-15 23:50:58 +05301534 params->base.stride << 10);
Kever Yang50fb9982017-02-22 16:56:35 +08001535
1536 /* reboot hold register set */
1537 writel(PRESET_SGRF_HOLD(0) | PRESET_GPIO0_HOLD(1) |
1538 PRESET_GPIO1_HOLD(1),
1539 &dram->pmucru->pmucru_rstnhold_con[1]);
1540 clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
1541}
1542
Kever Yange723a552019-08-12 20:02:29 +08001543static void set_cap_relate_config(const struct chan_info *chan,
1544 struct rk3399_sdram_params *params,
1545 unsigned int channel)
1546{
1547 u32 *denali_ctl = chan->pctl->denali_ctl;
1548 u32 tmp;
YouMin Chen23ae72e2019-11-15 11:04:45 +08001549 struct sdram_msch_timings *noc_timing;
Kever Yange723a552019-08-12 20:02:29 +08001550
1551 if (params->base.dramtype == LPDDR3) {
1552 tmp = (8 << params->ch[channel].cap_info.bw) /
1553 (8 << params->ch[channel].cap_info.dbw);
1554
1555 /**
1556 * memdata_ratio
1557 * 1 -> 0, 2 -> 1, 4 -> 2
1558 */
1559 clrsetbits_le32(&denali_ctl[197], 0x7,
1560 (tmp >> 1));
1561 clrsetbits_le32(&denali_ctl[198], 0x7 << 8,
1562 (tmp >> 1) << 8);
1563 }
1564
1565 noc_timing = &params->ch[channel].noc_timings;
1566
1567 /*
1568 * noc timing bw relate timing is 32 bit, and real bw is 16bit
1569 * actually noc reg is setting at function dram_all_config
1570 */
1571 if (params->ch[channel].cap_info.bw == 16 &&
1572 noc_timing->ddrmode.b.mwrsize == 2) {
1573 if (noc_timing->ddrmode.b.burstsize)
1574 noc_timing->ddrmode.b.burstsize -= 1;
1575 noc_timing->ddrmode.b.mwrsize -= 1;
1576 noc_timing->ddrtimingc0.b.burstpenalty *= 2;
1577 noc_timing->ddrtimingc0.b.wrtomwr *= 2;
1578 }
1579}
1580
1581static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
1582{
1583 unsigned int cs0_row = params->ch[channel].cap_info.cs0_row;
1584 unsigned int col = params->ch[channel].cap_info.col;
1585 unsigned int bw = params->ch[channel].cap_info.bw;
1586 u16 ddr_cfg_2_rbc[] = {
1587 /*
1588 * [6] highest bit col
1589 * [5:3] max row(14+n)
1590 * [2] insertion row
1591 * [1:0] col(9+n),col, data bus 32bit
1592 *
1593 * highbitcol, max_row, insertion_row, col
1594 */
1595 ((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */
1596 ((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */
1597 ((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */
1598 ((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */
1599 ((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */
1600 ((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */
1601 ((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */
1602 ((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */
1603 };
1604 u32 i;
1605
1606 col -= (bw == 2) ? 0 : 1;
1607 col -= 9;
1608
1609 for (i = 0; i < 4; i++) {
1610 if ((col == (ddr_cfg_2_rbc[i] & 0x3)) &&
1611 (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14)))
1612 break;
1613 }
1614
1615 if (i >= 4)
1616 i = -EINVAL;
1617
1618 return i;
1619}
1620
YouMin Chen6ba388f2019-11-15 11:04:49 +08001621static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
1622{
1623 rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
1624}
1625
Jagan Tekicc117bb2019-07-16 17:27:31 +05301626#if !defined(CONFIG_RAM_RK3399_LPDDR4)
YouMin Chende57fbf2019-11-15 11:04:46 +08001627static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
1628 struct rk3399_sdram_params *params)
Jagan Teki9eb935a2019-07-16 17:27:30 +05301629{
1630 u8 training_flag = PI_READ_GATE_TRAINING;
1631
1632 /*
1633 * LPDDR3 CA training msut be trigger before
1634 * other training.
1635 * DDR3 is not have CA training.
1636 */
1637
1638 if (params->base.dramtype == LPDDR3)
1639 training_flag |= PI_CA_TRAINING;
1640
1641 return data_training(dram, channel, params, training_flag);
1642}
1643
Kever Yang50fb9982017-02-22 16:56:35 +08001644static int switch_to_phy_index1(struct dram_info *dram,
Jagan Teki6ea82692019-07-16 17:27:40 +05301645 struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08001646{
1647 u32 channel;
1648 u32 *denali_phy;
Jagan Tekia58ff792019-07-15 23:50:58 +05301649 u32 ch_count = params->base.num_channels;
Kever Yang50fb9982017-02-22 16:56:35 +08001650 int ret;
1651 int i = 0;
1652
1653 writel(RK_CLRSETBITS(0x03 << 4 | 1 << 2 | 1,
1654 1 << 4 | 1 << 2 | 1),
1655 &dram->cic->cic_ctrl0);
1656 while (!(readl(&dram->cic->cic_status0) & (1 << 2))) {
1657 mdelay(10);
1658 i++;
1659 if (i > 10) {
1660 debug("index1 frequency change overtime\n");
1661 return -ETIME;
1662 }
1663 }
1664
1665 i = 0;
1666 writel(RK_CLRSETBITS(1 << 1, 1 << 1), &dram->cic->cic_ctrl0);
1667 while (!(readl(&dram->cic->cic_status0) & (1 << 0))) {
1668 mdelay(10);
Heinrich Schuchardt80516592018-03-18 12:10:55 +01001669 i++;
Kever Yang50fb9982017-02-22 16:56:35 +08001670 if (i > 10) {
1671 debug("index1 frequency done overtime\n");
1672 return -ETIME;
1673 }
1674 }
1675
1676 for (channel = 0; channel < ch_count; channel++) {
1677 denali_phy = dram->chan[channel].publ->denali_phy;
1678 clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8);
Jagan Teki5ff7abe2019-07-16 17:27:29 +05301679 ret = data_training(dram, channel, params, PI_FULL_TRAINING);
Jagan Teki6214ff22019-07-15 23:58:39 +05301680 if (ret < 0) {
Kever Yang50fb9982017-02-22 16:56:35 +08001681 debug("index1 training failed\n");
1682 return ret;
1683 }
1684 }
1685
1686 return 0;
1687}
1688
YouMin Chen99027372019-11-15 11:04:48 +08001689struct rk3399_sdram_params
1690 *get_phy_index_params(u32 phy_fn,
1691 struct rk3399_sdram_params *params)
1692{
1693 if (phy_fn == 0)
1694 return params;
1695 else
1696 return NULL;
1697}
1698
1699void modify_param(const struct chan_info *chan,
1700 struct rk3399_sdram_params *params)
1701{
1702 struct rk3399_sdram_params *params_cfg;
1703 u32 *denali_pi_params;
1704
1705 denali_pi_params = params->pi_regs.denali_pi;
1706
1707 /* modify PHY F0/F1/F2 params */
1708 params_cfg = get_phy_index_params(0, params);
1709 set_ds_odt(chan, params_cfg, false, 0);
1710
1711 clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
1712 clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
1713 clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
1714 clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
1715}
Jagan Teki940d1252019-07-16 17:27:39 +05301716#else
1717
YouMin Chende57fbf2019-11-15 11:04:46 +08001718struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
1719#include "sdram-rk3399-lpddr4-400.inc"
1720#include "sdram-rk3399-lpddr4-800.inc"
Jagan Teki6ea82692019-07-16 17:27:40 +05301721};
1722
YouMin Chen99027372019-11-15 11:04:48 +08001723static struct rk3399_sdram_params
1724 *lpddr4_get_phy_index_params(u32 phy_fn,
1725 struct rk3399_sdram_params *params)
1726{
1727 if (phy_fn == 0)
1728 return params;
1729 else if (phy_fn == 1)
1730 return &dfs_cfgs_lpddr4[1];
1731 else if (phy_fn == 2)
1732 return &dfs_cfgs_lpddr4[0];
1733 else
1734 return NULL;
1735}
1736
Jagan Teki6ea82692019-07-16 17:27:40 +05301737static void *get_denali_pi(const struct chan_info *chan,
1738 struct rk3399_sdram_params *params, bool reg)
1739{
1740 return reg ? &chan->pi->denali_pi : &params->pi_regs.denali_pi;
1741}
1742
YouMin Chende57fbf2019-11-15 11:04:46 +08001743static u32 lpddr4_get_phy_fn(struct rk3399_sdram_params *params, u32 ctl_fn)
Jagan Teki6ea82692019-07-16 17:27:40 +05301744{
YouMin Chende57fbf2019-11-15 11:04:46 +08001745 u32 lpddr4_phy_fn[] = {1, 0, 0xb};
Jagan Teki6ea82692019-07-16 17:27:40 +05301746
YouMin Chende57fbf2019-11-15 11:04:46 +08001747 return lpddr4_phy_fn[ctl_fn];
Jagan Teki6ea82692019-07-16 17:27:40 +05301748}
1749
YouMin Chende57fbf2019-11-15 11:04:46 +08001750static u32 lpddr4_get_ctl_fn(struct rk3399_sdram_params *params, u32 phy_fn)
Jagan Teki6ea82692019-07-16 17:27:40 +05301751{
YouMin Chende57fbf2019-11-15 11:04:46 +08001752 u32 lpddr4_ctl_fn[] = {1, 0, 2};
Jagan Teki6ea82692019-07-16 17:27:40 +05301753
YouMin Chende57fbf2019-11-15 11:04:46 +08001754 return lpddr4_ctl_fn[phy_fn];
Jagan Teki6ea82692019-07-16 17:27:40 +05301755}
1756
Jagan Tekicc117bb2019-07-16 17:27:31 +05301757static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
1758{
1759 return ((readl(&pmusgrf->soc_con4) >> 10) & 0x1F);
1760}
1761
YouMin Chen6ba388f2019-11-15 11:04:49 +08001762/*
Jagan Tekicc117bb2019-07-16 17:27:31 +05301763 * read mr_num mode register
1764 * rank = 1: cs0
1765 * rank = 2: cs1
1766 */
1767static int read_mr(struct rk3399_ddr_pctl_regs *ddr_pctl_regs, u32 rank,
1768 u32 mr_num, u32 *buf)
1769{
1770 s32 timeout = 100;
1771
1772 writel(((1 << 16) | (((rank == 2) ? 1 : 0) << 8) | mr_num) << 8,
1773 &ddr_pctl_regs->denali_ctl[118]);
1774
1775 while (0 == (readl(&ddr_pctl_regs->denali_ctl[203]) &
1776 ((1 << 21) | (1 << 12)))) {
1777 udelay(1);
1778
1779 if (timeout <= 0) {
1780 printf("%s: pctl timeout!\n", __func__);
1781 return -ETIMEDOUT;
1782 }
1783
1784 timeout--;
1785 }
1786
1787 if (!(readl(&ddr_pctl_regs->denali_ctl[203]) & (1 << 12))) {
1788 *buf = readl(&ddr_pctl_regs->denali_ctl[119]) & 0xFF;
1789 } else {
1790 printf("%s: read mr failed with 0x%x status\n", __func__,
1791 readl(&ddr_pctl_regs->denali_ctl[17]) & 0x3);
1792 *buf = 0;
1793 }
1794
1795 setbits_le32(&ddr_pctl_regs->denali_ctl[205], (1 << 21) | (1 << 12));
1796
1797 return 0;
1798}
1799
1800static int lpddr4_mr_detect(struct dram_info *dram, u32 channel, u8 rank,
1801 struct rk3399_sdram_params *params)
1802{
1803 u64 cs0_cap;
1804 u32 stride;
1805 u32 cs = 0, col = 0, bk = 0, bw = 0, row_3_4 = 0;
1806 u32 cs0_row = 0, cs1_row = 0, ddrconfig = 0;
1807 u32 mr5, mr12, mr14;
1808 struct chan_info *chan = &dram->chan[channel];
1809 struct rk3399_ddr_pctl_regs *ddr_pctl_regs = chan->pctl;
1810 void __iomem *addr = NULL;
1811 int ret = 0;
1812 u32 val;
1813
1814 stride = get_ddr_stride(dram->pmusgrf);
1815
1816 if (params->ch[channel].cap_info.col == 0) {
1817 ret = -EPERM;
1818 goto end;
1819 }
1820
1821 cs = params->ch[channel].cap_info.rank;
1822 col = params->ch[channel].cap_info.col;
1823 bk = params->ch[channel].cap_info.bk;
1824 bw = params->ch[channel].cap_info.bw;
1825 row_3_4 = params->ch[channel].cap_info.row_3_4;
1826 cs0_row = params->ch[channel].cap_info.cs0_row;
1827 cs1_row = params->ch[channel].cap_info.cs1_row;
1828 ddrconfig = params->ch[channel].cap_info.ddrconfig;
1829
1830 /* 2GB */
1831 params->ch[channel].cap_info.rank = 2;
1832 params->ch[channel].cap_info.col = 10;
1833 params->ch[channel].cap_info.bk = 3;
1834 params->ch[channel].cap_info.bw = 2;
1835 params->ch[channel].cap_info.row_3_4 = 0;
1836 params->ch[channel].cap_info.cs0_row = 15;
1837 params->ch[channel].cap_info.cs1_row = 15;
1838 params->ch[channel].cap_info.ddrconfig = 1;
1839
1840 set_memory_map(chan, channel, params);
1841 params->ch[channel].cap_info.ddrconfig =
1842 calculate_ddrconfig(params, channel);
1843 set_ddrconfig(chan, params, channel,
1844 params->ch[channel].cap_info.ddrconfig);
1845 set_cap_relate_config(chan, params, channel);
1846
1847 cs0_cap = (1 << (params->ch[channel].cap_info.bw
1848 + params->ch[channel].cap_info.col
1849 + params->ch[channel].cap_info.bk
1850 + params->ch[channel].cap_info.cs0_row));
1851
1852 if (params->ch[channel].cap_info.row_3_4)
1853 cs0_cap = cs0_cap * 3 / 4;
1854
1855 if (channel == 0)
1856 set_ddr_stride(dram->pmusgrf, 0x17);
1857 else
1858 set_ddr_stride(dram->pmusgrf, 0x18);
1859
1860 /* read and write data to DRAM, avoid be optimized by compiler. */
1861 if (rank == 1)
1862 addr = (void __iomem *)0x100;
1863 else if (rank == 2)
1864 addr = (void __iomem *)(cs0_cap + 0x100);
1865
1866 val = readl(addr);
1867 writel(val + 1, addr);
1868
1869 read_mr(ddr_pctl_regs, rank, 5, &mr5);
1870 read_mr(ddr_pctl_regs, rank, 12, &mr12);
1871 read_mr(ddr_pctl_regs, rank, 14, &mr14);
1872
1873 if (mr5 == 0 || mr12 != 0x4d || mr14 != 0x4d) {
1874 ret = -EINVAL;
1875 goto end;
1876 }
1877end:
1878 params->ch[channel].cap_info.rank = cs;
1879 params->ch[channel].cap_info.col = col;
1880 params->ch[channel].cap_info.bk = bk;
1881 params->ch[channel].cap_info.bw = bw;
1882 params->ch[channel].cap_info.row_3_4 = row_3_4;
1883 params->ch[channel].cap_info.cs0_row = cs0_row;
1884 params->ch[channel].cap_info.cs1_row = cs1_row;
1885 params->ch[channel].cap_info.ddrconfig = ddrconfig;
1886
1887 set_ddr_stride(dram->pmusgrf, stride);
1888
1889 return ret;
1890}
Jagan Teki6ea82692019-07-16 17:27:40 +05301891
1892static void set_lpddr4_dq_odt(const struct chan_info *chan,
YouMin Chende57fbf2019-11-15 11:04:46 +08001893 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Teki6ea82692019-07-16 17:27:40 +05301894 bool en, bool ctl_phy_reg, u32 mr5)
1895{
1896 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
1897 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
1898 struct io_setting *io;
1899 u32 reg_value;
1900
Jagan Teki6ea82692019-07-16 17:27:40 +05301901 io = lpddr4_get_io_settings(params, mr5);
YouMin Chende57fbf2019-11-15 11:04:46 +08001902 if (en)
1903 reg_value = io->dq_odt;
1904 else
1905 reg_value = 0;
Jagan Teki6ea82692019-07-16 17:27:40 +05301906
YouMin Chende57fbf2019-11-15 11:04:46 +08001907 switch (ctl_fn) {
Jagan Teki6ea82692019-07-16 17:27:40 +05301908 case 0:
1909 clrsetbits_le32(&denali_ctl[139], 0x7 << 24, reg_value << 24);
1910 clrsetbits_le32(&denali_ctl[153], 0x7 << 24, reg_value << 24);
1911
1912 clrsetbits_le32(&denali_pi[132], 0x7 << 0, (reg_value << 0));
1913 clrsetbits_le32(&denali_pi[139], 0x7 << 16, (reg_value << 16));
1914 clrsetbits_le32(&denali_pi[147], 0x7 << 0, (reg_value << 0));
1915 clrsetbits_le32(&denali_pi[154], 0x7 << 16, (reg_value << 16));
1916 break;
1917 case 1:
1918 clrsetbits_le32(&denali_ctl[140], 0x7 << 0, reg_value << 0);
1919 clrsetbits_le32(&denali_ctl[154], 0x7 << 0, reg_value << 0);
1920
1921 clrsetbits_le32(&denali_pi[129], 0x7 << 16, (reg_value << 16));
1922 clrsetbits_le32(&denali_pi[137], 0x7 << 0, (reg_value << 0));
1923 clrsetbits_le32(&denali_pi[144], 0x7 << 16, (reg_value << 16));
1924 clrsetbits_le32(&denali_pi[152], 0x7 << 0, (reg_value << 0));
1925 break;
1926 case 2:
1927 default:
1928 clrsetbits_le32(&denali_ctl[140], 0x7 << 8, (reg_value << 8));
1929 clrsetbits_le32(&denali_ctl[154], 0x7 << 8, (reg_value << 8));
1930
1931 clrsetbits_le32(&denali_pi[127], 0x7 << 0, (reg_value << 0));
1932 clrsetbits_le32(&denali_pi[134], 0x7 << 16, (reg_value << 16));
1933 clrsetbits_le32(&denali_pi[142], 0x7 << 0, (reg_value << 0));
1934 clrsetbits_le32(&denali_pi[149], 0x7 << 16, (reg_value << 16));
1935 break;
1936 }
1937}
1938
1939static void set_lpddr4_ca_odt(const struct chan_info *chan,
YouMin Chende57fbf2019-11-15 11:04:46 +08001940 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Teki6ea82692019-07-16 17:27:40 +05301941 bool en, bool ctl_phy_reg, u32 mr5)
1942{
1943 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
1944 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
1945 struct io_setting *io;
1946 u32 reg_value;
1947
Jagan Teki6ea82692019-07-16 17:27:40 +05301948 io = lpddr4_get_io_settings(params, mr5);
YouMin Chende57fbf2019-11-15 11:04:46 +08001949 if (en)
1950 reg_value = io->ca_odt;
1951 else
1952 reg_value = 0;
Jagan Teki6ea82692019-07-16 17:27:40 +05301953
YouMin Chende57fbf2019-11-15 11:04:46 +08001954 switch (ctl_fn) {
Jagan Teki6ea82692019-07-16 17:27:40 +05301955 case 0:
1956 clrsetbits_le32(&denali_ctl[139], 0x7 << 28, reg_value << 28);
1957 clrsetbits_le32(&denali_ctl[153], 0x7 << 28, reg_value << 28);
1958
1959 clrsetbits_le32(&denali_pi[132], 0x7 << 4, reg_value << 4);
1960 clrsetbits_le32(&denali_pi[139], 0x7 << 20, reg_value << 20);
1961 clrsetbits_le32(&denali_pi[147], 0x7 << 4, reg_value << 4);
1962 clrsetbits_le32(&denali_pi[154], 0x7 << 20, reg_value << 20);
1963 break;
1964 case 1:
1965 clrsetbits_le32(&denali_ctl[140], 0x7 << 4, reg_value << 4);
1966 clrsetbits_le32(&denali_ctl[154], 0x7 << 4, reg_value << 4);
1967
1968 clrsetbits_le32(&denali_pi[129], 0x7 << 20, reg_value << 20);
1969 clrsetbits_le32(&denali_pi[137], 0x7 << 4, reg_value << 4);
1970 clrsetbits_le32(&denali_pi[144], 0x7 << 20, reg_value << 20);
1971 clrsetbits_le32(&denali_pi[152], 0x7 << 4, reg_value << 4);
1972 break;
1973 case 2:
1974 default:
1975 clrsetbits_le32(&denali_ctl[140], 0x7 << 12, (reg_value << 12));
1976 clrsetbits_le32(&denali_ctl[154], 0x7 << 12, (reg_value << 12));
1977
1978 clrsetbits_le32(&denali_pi[127], 0x7 << 4, reg_value << 4);
1979 clrsetbits_le32(&denali_pi[134], 0x7 << 20, reg_value << 20);
1980 clrsetbits_le32(&denali_pi[142], 0x7 << 4, reg_value << 4);
1981 clrsetbits_le32(&denali_pi[149], 0x7 << 20, reg_value << 20);
1982 break;
1983 }
1984}
1985
1986static void set_lpddr4_MR3(const struct chan_info *chan,
YouMin Chende57fbf2019-11-15 11:04:46 +08001987 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Teki6ea82692019-07-16 17:27:40 +05301988 bool ctl_phy_reg, u32 mr5)
1989{
1990 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
1991 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
1992 struct io_setting *io;
1993 u32 reg_value;
1994
1995 io = lpddr4_get_io_settings(params, mr5);
1996
1997 reg_value = ((io->pdds << 3) | 1);
1998
YouMin Chende57fbf2019-11-15 11:04:46 +08001999 switch (ctl_fn) {
Jagan Teki6ea82692019-07-16 17:27:40 +05302000 case 0:
2001 clrsetbits_le32(&denali_ctl[138], 0xFFFF, reg_value);
2002 clrsetbits_le32(&denali_ctl[152], 0xFFFF, reg_value);
2003
2004 clrsetbits_le32(&denali_pi[131], 0xFFFF << 16, reg_value << 16);
2005 clrsetbits_le32(&denali_pi[139], 0xFFFF, reg_value);
2006 clrsetbits_le32(&denali_pi[146], 0xFFFF << 16, reg_value << 16);
2007 clrsetbits_le32(&denali_pi[154], 0xFFFF, reg_value);
2008 break;
2009 case 1:
2010 clrsetbits_le32(&denali_ctl[138], 0xFFFF << 16,
2011 reg_value << 16);
2012 clrsetbits_le32(&denali_ctl[152], 0xFFFF << 16,
2013 reg_value << 16);
2014
2015 clrsetbits_le32(&denali_pi[129], 0xFFFF, reg_value);
2016 clrsetbits_le32(&denali_pi[136], 0xFFFF << 16, reg_value << 16);
2017 clrsetbits_le32(&denali_pi[144], 0xFFFF, reg_value);
2018 clrsetbits_le32(&denali_pi[151], 0xFFFF << 16, reg_value << 16);
2019 break;
2020 case 2:
2021 default:
2022 clrsetbits_le32(&denali_ctl[139], 0xFFFF, reg_value);
2023 clrsetbits_le32(&denali_ctl[153], 0xFFFF, reg_value);
2024
2025 clrsetbits_le32(&denali_pi[126], 0xFFFF << 16, reg_value << 16);
2026 clrsetbits_le32(&denali_pi[134], 0xFFFF, reg_value);
2027 clrsetbits_le32(&denali_pi[141], 0xFFFF << 16, reg_value << 16);
2028 clrsetbits_le32(&denali_pi[149], 0xFFFF, reg_value);
2029 break;
2030 }
2031}
2032
2033static void set_lpddr4_MR12(const struct chan_info *chan,
YouMin Chende57fbf2019-11-15 11:04:46 +08002034 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Teki6ea82692019-07-16 17:27:40 +05302035 bool ctl_phy_reg, u32 mr5)
2036{
2037 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
2038 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
2039 struct io_setting *io;
2040 u32 reg_value;
2041
2042 io = lpddr4_get_io_settings(params, mr5);
2043
2044 reg_value = io->ca_vref;
2045
YouMin Chende57fbf2019-11-15 11:04:46 +08002046 switch (ctl_fn) {
Jagan Teki6ea82692019-07-16 17:27:40 +05302047 case 0:
2048 clrsetbits_le32(&denali_ctl[140], 0xFFFF << 16,
2049 reg_value << 16);
2050 clrsetbits_le32(&denali_ctl[154], 0xFFFF << 16,
2051 reg_value << 16);
2052
2053 clrsetbits_le32(&denali_pi[132], 0xFF << 8, reg_value << 8);
2054 clrsetbits_le32(&denali_pi[139], 0xFF << 24, reg_value << 24);
2055 clrsetbits_le32(&denali_pi[147], 0xFF << 8, reg_value << 8);
2056 clrsetbits_le32(&denali_pi[154], 0xFF << 24, reg_value << 24);
2057 break;
2058 case 1:
2059 clrsetbits_le32(&denali_ctl[141], 0xFFFF, reg_value);
2060 clrsetbits_le32(&denali_ctl[155], 0xFFFF, reg_value);
2061
2062 clrsetbits_le32(&denali_pi[129], 0xFF << 24, reg_value << 24);
2063 clrsetbits_le32(&denali_pi[137], 0xFF << 8, reg_value << 8);
2064 clrsetbits_le32(&denali_pi[144], 0xFF << 24, reg_value << 24);
2065 clrsetbits_le32(&denali_pi[152], 0xFF << 8, reg_value << 8);
2066 break;
2067 case 2:
2068 default:
2069 clrsetbits_le32(&denali_ctl[141], 0xFFFF << 16,
2070 reg_value << 16);
2071 clrsetbits_le32(&denali_ctl[155], 0xFFFF << 16,
2072 reg_value << 16);
2073
2074 clrsetbits_le32(&denali_pi[127], 0xFF << 8, reg_value << 8);
2075 clrsetbits_le32(&denali_pi[134], 0xFF << 24, reg_value << 24);
2076 clrsetbits_le32(&denali_pi[142], 0xFF << 8, reg_value << 8);
2077 clrsetbits_le32(&denali_pi[149], 0xFF << 24, reg_value << 24);
2078 break;
2079 }
2080}
2081
2082static void set_lpddr4_MR14(const struct chan_info *chan,
YouMin Chende57fbf2019-11-15 11:04:46 +08002083 struct rk3399_sdram_params *params, u32 ctl_fn,
Jagan Teki6ea82692019-07-16 17:27:40 +05302084 bool ctl_phy_reg, u32 mr5)
2085{
2086 u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
2087 u32 *denali_pi = get_denali_pi(chan, params, ctl_phy_reg);
2088 struct io_setting *io;
2089 u32 reg_value;
2090
2091 io = lpddr4_get_io_settings(params, mr5);
2092
2093 reg_value = io->dq_vref;
2094
YouMin Chende57fbf2019-11-15 11:04:46 +08002095 switch (ctl_fn) {
Jagan Teki6ea82692019-07-16 17:27:40 +05302096 case 0:
2097 clrsetbits_le32(&denali_ctl[142], 0xFFFF << 16,
2098 reg_value << 16);
2099 clrsetbits_le32(&denali_ctl[156], 0xFFFF << 16,
2100 reg_value << 16);
2101
2102 clrsetbits_le32(&denali_pi[132], 0xFF << 16, reg_value << 16);
2103 clrsetbits_le32(&denali_pi[140], 0xFF << 0, reg_value << 0);
2104 clrsetbits_le32(&denali_pi[147], 0xFF << 16, reg_value << 16);
2105 clrsetbits_le32(&denali_pi[155], 0xFF << 0, reg_value << 0);
2106 break;
2107 case 1:
2108 clrsetbits_le32(&denali_ctl[143], 0xFFFF, reg_value);
2109 clrsetbits_le32(&denali_ctl[157], 0xFFFF, reg_value);
2110
2111 clrsetbits_le32(&denali_pi[130], 0xFF << 0, reg_value << 0);
2112 clrsetbits_le32(&denali_pi[137], 0xFF << 16, reg_value << 16);
2113 clrsetbits_le32(&denali_pi[145], 0xFF << 0, reg_value << 0);
2114 clrsetbits_le32(&denali_pi[152], 0xFF << 16, reg_value << 16);
2115 break;
2116 case 2:
2117 default:
2118 clrsetbits_le32(&denali_ctl[143], 0xFFFF << 16,
2119 reg_value << 16);
2120 clrsetbits_le32(&denali_ctl[157], 0xFFFF << 16,
2121 reg_value << 16);
2122
2123 clrsetbits_le32(&denali_pi[127], 0xFF << 16, reg_value << 16);
2124 clrsetbits_le32(&denali_pi[135], 0xFF << 0, reg_value << 0);
2125 clrsetbits_le32(&denali_pi[142], 0xFF << 16, reg_value << 16);
2126 clrsetbits_le32(&denali_pi[150], 0xFF << 0, reg_value << 0);
2127 break;
2128 }
2129}
2130
YouMin Chen99027372019-11-15 11:04:48 +08002131void lpddr4_modify_param(const struct chan_info *chan,
2132 struct rk3399_sdram_params *params)
2133{
2134 struct rk3399_sdram_params *params_cfg;
2135 u32 *denali_ctl_params;
2136 u32 *denali_pi_params;
2137 u32 *denali_phy_params;
2138
2139 denali_ctl_params = params->pctl_regs.denali_ctl;
2140 denali_pi_params = params->pi_regs.denali_pi;
2141 denali_phy_params = params->phy_regs.denali_phy;
2142
2143 set_lpddr4_dq_odt(chan, params, 2, true, false, 0);
2144 set_lpddr4_ca_odt(chan, params, 2, true, false, 0);
2145 set_lpddr4_MR3(chan, params, 2, false, 0);
2146 set_lpddr4_MR12(chan, params, 2, false, 0);
2147 set_lpddr4_MR14(chan, params, 2, false, 0);
2148 params_cfg = lpddr4_get_phy_index_params(0, params);
2149 set_ds_odt(chan, params_cfg, false, 0);
2150 /* read two cycle preamble */
2151 clrsetbits_le32(&denali_ctl_params[200], 0x3 << 24, 0x3 << 24);
2152 clrsetbits_le32(&denali_phy_params[7], 0x3 << 24, 0x3 << 24);
2153 clrsetbits_le32(&denali_phy_params[135], 0x3 << 24, 0x3 << 24);
2154 clrsetbits_le32(&denali_phy_params[263], 0x3 << 24, 0x3 << 24);
2155 clrsetbits_le32(&denali_phy_params[391], 0x3 << 24, 0x3 << 24);
2156
2157 /* boot frequency two cycle preamble */
2158 clrsetbits_le32(&denali_phy_params[2], 0x3 << 16, 0x3 << 16);
2159 clrsetbits_le32(&denali_phy_params[130], 0x3 << 16, 0x3 << 16);
2160 clrsetbits_le32(&denali_phy_params[258], 0x3 << 16, 0x3 << 16);
2161 clrsetbits_le32(&denali_phy_params[386], 0x3 << 16, 0x3 << 16);
2162
2163 clrsetbits_le32(&denali_pi_params[45], 0x3 << 8, 0x3 << 8);
2164 clrsetbits_le32(&denali_pi_params[58], 0x1, 0x1);
2165
2166 /*
2167 * bypass mode need PHY_SLICE_PWR_RDC_DISABLE_x = 1,
2168 * boot frequency mode use bypass mode
2169 */
2170 setbits_le32(&denali_phy_params[10], 1 << 16);
2171 setbits_le32(&denali_phy_params[138], 1 << 16);
2172 setbits_le32(&denali_phy_params[266], 1 << 16);
2173 setbits_le32(&denali_phy_params[394], 1 << 16);
2174
2175 clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
2176 clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
2177 clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
2178 clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
2179}
2180
Jagan Teki6ea82692019-07-16 17:27:40 +05302181static void lpddr4_copy_phy(struct dram_info *dram,
YouMin Chende57fbf2019-11-15 11:04:46 +08002182 struct rk3399_sdram_params *params, u32 phy_fn,
2183 struct rk3399_sdram_params *params_cfg,
Jagan Teki6ea82692019-07-16 17:27:40 +05302184 u32 channel)
2185{
2186 u32 *denali_ctl, *denali_phy;
2187 u32 *denali_phy_params;
2188 u32 speed = 0;
YouMin Chende57fbf2019-11-15 11:04:46 +08002189 u32 ctl_fn, mr5;
Jagan Teki6ea82692019-07-16 17:27:40 +05302190
2191 denali_ctl = dram->chan[channel].pctl->denali_ctl;
2192 denali_phy = dram->chan[channel].publ->denali_phy;
YouMin Chende57fbf2019-11-15 11:04:46 +08002193 denali_phy_params = params_cfg->phy_regs.denali_phy;
Jagan Teki6ea82692019-07-16 17:27:40 +05302194
2195 /* switch index */
YouMin Chende57fbf2019-11-15 11:04:46 +08002196 clrsetbits_le32(&denali_phy_params[896], 0x3 << 8,
2197 phy_fn << 8);
Jagan Teki6ea82692019-07-16 17:27:40 +05302198 writel(denali_phy_params[896], &denali_phy[896]);
2199
2200 /* phy_pll_ctrl_ca, phy_pll_ctrl */
2201 writel(denali_phy_params[911], &denali_phy[911]);
2202
2203 /* phy_low_freq_sel */
2204 clrsetbits_le32(&denali_phy[913], 0x1,
2205 denali_phy_params[913] & 0x1);
2206
2207 /* phy_grp_slave_delay_x, phy_cslvl_dly_step */
2208 writel(denali_phy_params[916], &denali_phy[916]);
2209 writel(denali_phy_params[917], &denali_phy[917]);
2210 writel(denali_phy_params[918], &denali_phy[918]);
2211
2212 /* phy_adrz_sw_wraddr_shift_x */
2213 writel(denali_phy_params[512], &denali_phy[512]);
2214 clrsetbits_le32(&denali_phy[513], 0xffff,
2215 denali_phy_params[513] & 0xffff);
2216 writel(denali_phy_params[640], &denali_phy[640]);
2217 clrsetbits_le32(&denali_phy[641], 0xffff,
2218 denali_phy_params[641] & 0xffff);
2219 writel(denali_phy_params[768], &denali_phy[768]);
2220 clrsetbits_le32(&denali_phy[769], 0xffff,
2221 denali_phy_params[769] & 0xffff);
2222
2223 writel(denali_phy_params[544], &denali_phy[544]);
2224 writel(denali_phy_params[545], &denali_phy[545]);
2225 writel(denali_phy_params[546], &denali_phy[546]);
2226 writel(denali_phy_params[547], &denali_phy[547]);
2227
2228 writel(denali_phy_params[672], &denali_phy[672]);
2229 writel(denali_phy_params[673], &denali_phy[673]);
2230 writel(denali_phy_params[674], &denali_phy[674]);
2231 writel(denali_phy_params[675], &denali_phy[675]);
2232
2233 writel(denali_phy_params[800], &denali_phy[800]);
2234 writel(denali_phy_params[801], &denali_phy[801]);
2235 writel(denali_phy_params[802], &denali_phy[802]);
2236 writel(denali_phy_params[803], &denali_phy[803]);
2237
2238 /*
2239 * phy_adr_master_delay_start_x
2240 * phy_adr_master_delay_step_x
2241 * phy_adr_master_delay_wait_x
2242 */
2243 writel(denali_phy_params[548], &denali_phy[548]);
2244 writel(denali_phy_params[676], &denali_phy[676]);
2245 writel(denali_phy_params[804], &denali_phy[804]);
2246
2247 /* phy_adr_calvl_dly_step_x */
2248 writel(denali_phy_params[549], &denali_phy[549]);
2249 writel(denali_phy_params[677], &denali_phy[677]);
2250 writel(denali_phy_params[805], &denali_phy[805]);
2251
2252 /*
2253 * phy_clk_wrdm_slave_delay_x
2254 * phy_clk_wrdqz_slave_delay_x
2255 * phy_clk_wrdqs_slave_delay_x
2256 */
YouMin Chen23ae72e2019-11-15 11:04:45 +08002257 sdram_copy_to_reg((u32 *)&denali_phy[59],
2258 (u32 *)&denali_phy_params[59], (63 - 58) * 4);
2259 sdram_copy_to_reg((u32 *)&denali_phy[187],
2260 (u32 *)&denali_phy_params[187], (191 - 186) * 4);
2261 sdram_copy_to_reg((u32 *)&denali_phy[315],
2262 (u32 *)&denali_phy_params[315], (319 - 314) * 4);
2263 sdram_copy_to_reg((u32 *)&denali_phy[443],
2264 (u32 *)&denali_phy_params[443], (447 - 442) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302265
2266 /*
2267 * phy_dqs_tsel_wr_timing_x 8bits denali_phy_84/212/340/468 offset_8
2268 * dqs_tsel_wr_end[7:4] add half cycle
2269 * phy_dq_tsel_wr_timing_x 8bits denali_phy_83/211/339/467 offset_8
2270 * dq_tsel_wr_end[7:4] add half cycle
2271 */
2272 writel(denali_phy_params[83] + (0x10 << 16), &denali_phy[83]);
2273 writel(denali_phy_params[84] + (0x10 << 8), &denali_phy[84]);
2274 writel(denali_phy_params[85], &denali_phy[85]);
2275
2276 writel(denali_phy_params[211] + (0x10 << 16), &denali_phy[211]);
2277 writel(denali_phy_params[212] + (0x10 << 8), &denali_phy[212]);
2278 writel(denali_phy_params[213], &denali_phy[213]);
2279
2280 writel(denali_phy_params[339] + (0x10 << 16), &denali_phy[339]);
2281 writel(denali_phy_params[340] + (0x10 << 8), &denali_phy[340]);
2282 writel(denali_phy_params[341], &denali_phy[341]);
2283
2284 writel(denali_phy_params[467] + (0x10 << 16), &denali_phy[467]);
2285 writel(denali_phy_params[468] + (0x10 << 8), &denali_phy[468]);
2286 writel(denali_phy_params[469], &denali_phy[469]);
2287
2288 /*
2289 * phy_gtlvl_resp_wait_cnt_x
2290 * phy_gtlvl_dly_step_x
2291 * phy_wrlvl_resp_wait_cnt_x
2292 * phy_gtlvl_final_step_x
2293 * phy_gtlvl_back_step_x
2294 * phy_rdlvl_dly_step_x
2295 *
2296 * phy_master_delay_step_x
2297 * phy_master_delay_wait_x
2298 * phy_wrlvl_dly_step_x
2299 * phy_rptr_update_x
2300 * phy_wdqlvl_dly_step_x
2301 */
2302 writel(denali_phy_params[87], &denali_phy[87]);
2303 writel(denali_phy_params[88], &denali_phy[88]);
2304 writel(denali_phy_params[89], &denali_phy[89]);
2305 writel(denali_phy_params[90], &denali_phy[90]);
2306
2307 writel(denali_phy_params[215], &denali_phy[215]);
2308 writel(denali_phy_params[216], &denali_phy[216]);
2309 writel(denali_phy_params[217], &denali_phy[217]);
2310 writel(denali_phy_params[218], &denali_phy[218]);
2311
2312 writel(denali_phy_params[343], &denali_phy[343]);
2313 writel(denali_phy_params[344], &denali_phy[344]);
2314 writel(denali_phy_params[345], &denali_phy[345]);
2315 writel(denali_phy_params[346], &denali_phy[346]);
2316
2317 writel(denali_phy_params[471], &denali_phy[471]);
2318 writel(denali_phy_params[472], &denali_phy[472]);
2319 writel(denali_phy_params[473], &denali_phy[473]);
2320 writel(denali_phy_params[474], &denali_phy[474]);
2321
2322 /*
2323 * phy_gtlvl_lat_adj_start_x
2324 * phy_gtlvl_rddqs_slv_dly_start_x
2325 * phy_rdlvl_rddqs_dq_slv_dly_start_x
2326 * phy_wdqlvl_dqdm_slv_dly_start_x
2327 */
2328 writel(denali_phy_params[80], &denali_phy[80]);
2329 writel(denali_phy_params[81], &denali_phy[81]);
2330
2331 writel(denali_phy_params[208], &denali_phy[208]);
2332 writel(denali_phy_params[209], &denali_phy[209]);
2333
2334 writel(denali_phy_params[336], &denali_phy[336]);
2335 writel(denali_phy_params[337], &denali_phy[337]);
2336
2337 writel(denali_phy_params[464], &denali_phy[464]);
2338 writel(denali_phy_params[465], &denali_phy[465]);
2339
2340 /*
2341 * phy_master_delay_start_x
2342 * phy_sw_master_mode_x
2343 * phy_rddata_en_tsel_dly_x
2344 */
2345 writel(denali_phy_params[86], &denali_phy[86]);
2346 writel(denali_phy_params[214], &denali_phy[214]);
2347 writel(denali_phy_params[342], &denali_phy[342]);
2348 writel(denali_phy_params[470], &denali_phy[470]);
2349
2350 /*
2351 * phy_rddqz_slave_delay_x
2352 * phy_rddqs_dqz_fall_slave_delay_x
2353 * phy_rddqs_dqz_rise_slave_delay_x
2354 * phy_rddqs_dm_fall_slave_delay_x
2355 * phy_rddqs_dm_rise_slave_delay_x
2356 * phy_rddqs_gate_slave_delay_x
2357 * phy_wrlvl_delay_early_threshold_x
2358 * phy_write_path_lat_add_x
2359 * phy_rddqs_latency_adjust_x
2360 * phy_wrlvl_delay_period_threshold_x
2361 * phy_wrlvl_early_force_zero_x
2362 */
YouMin Chen23ae72e2019-11-15 11:04:45 +08002363 sdram_copy_to_reg((u32 *)&denali_phy[64],
2364 (u32 *)&denali_phy_params[64], (67 - 63) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302365 clrsetbits_le32(&denali_phy[68], 0xfffffc00,
2366 denali_phy_params[68] & 0xfffffc00);
YouMin Chen23ae72e2019-11-15 11:04:45 +08002367 sdram_copy_to_reg((u32 *)&denali_phy[69],
2368 (u32 *)&denali_phy_params[69], (79 - 68) * 4);
2369 sdram_copy_to_reg((u32 *)&denali_phy[192],
2370 (u32 *)&denali_phy_params[192], (195 - 191) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302371 clrsetbits_le32(&denali_phy[196], 0xfffffc00,
2372 denali_phy_params[196] & 0xfffffc00);
YouMin Chen23ae72e2019-11-15 11:04:45 +08002373 sdram_copy_to_reg((u32 *)&denali_phy[197],
2374 (u32 *)&denali_phy_params[197], (207 - 196) * 4);
2375 sdram_copy_to_reg((u32 *)&denali_phy[320],
2376 (u32 *)&denali_phy_params[320], (323 - 319) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302377 clrsetbits_le32(&denali_phy[324], 0xfffffc00,
2378 denali_phy_params[324] & 0xfffffc00);
YouMin Chen23ae72e2019-11-15 11:04:45 +08002379 sdram_copy_to_reg((u32 *)&denali_phy[325],
2380 (u32 *)&denali_phy_params[325], (335 - 324) * 4);
2381 sdram_copy_to_reg((u32 *)&denali_phy[448],
2382 (u32 *)&denali_phy_params[448], (451 - 447) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302383 clrsetbits_le32(&denali_phy[452], 0xfffffc00,
2384 denali_phy_params[452] & 0xfffffc00);
YouMin Chen23ae72e2019-11-15 11:04:45 +08002385 sdram_copy_to_reg((u32 *)&denali_phy[453],
2386 (u32 *)&denali_phy_params[453], (463 - 452) * 4);
Jagan Teki6ea82692019-07-16 17:27:40 +05302387
2388 /* phy_two_cyc_preamble_x */
2389 clrsetbits_le32(&denali_phy[7], 0x3 << 24,
2390 denali_phy_params[7] & (0x3 << 24));
2391 clrsetbits_le32(&denali_phy[135], 0x3 << 24,
2392 denali_phy_params[135] & (0x3 << 24));
2393 clrsetbits_le32(&denali_phy[263], 0x3 << 24,
2394 denali_phy_params[263] & (0x3 << 24));
2395 clrsetbits_le32(&denali_phy[391], 0x3 << 24,
2396 denali_phy_params[391] & (0x3 << 24));
2397
2398 /* speed */
YouMin Chende57fbf2019-11-15 11:04:46 +08002399 if (params_cfg->base.ddr_freq < 400)
Jagan Teki6ea82692019-07-16 17:27:40 +05302400 speed = 0x0;
YouMin Chende57fbf2019-11-15 11:04:46 +08002401 else if (params_cfg->base.ddr_freq < 800)
Jagan Teki6ea82692019-07-16 17:27:40 +05302402 speed = 0x1;
YouMin Chende57fbf2019-11-15 11:04:46 +08002403 else if (params_cfg->base.ddr_freq < 1200)
Jagan Teki6ea82692019-07-16 17:27:40 +05302404 speed = 0x2;
2405
2406 /* phy_924 phy_pad_fdbk_drive */
2407 clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
2408 /* phy_926 phy_pad_data_drive */
2409 clrsetbits_le32(&denali_phy[926], 0x3 << 9, speed << 9);
2410 /* phy_927 phy_pad_dqs_drive */
2411 clrsetbits_le32(&denali_phy[927], 0x3 << 9, speed << 9);
2412 /* phy_928 phy_pad_addr_drive */
2413 clrsetbits_le32(&denali_phy[928], 0x3 << 17, speed << 17);
2414 /* phy_929 phy_pad_clk_drive */
2415 clrsetbits_le32(&denali_phy[929], 0x3 << 17, speed << 17);
2416 /* phy_935 phy_pad_cke_drive */
2417 clrsetbits_le32(&denali_phy[935], 0x3 << 17, speed << 17);
2418 /* phy_937 phy_pad_rst_drive */
2419 clrsetbits_le32(&denali_phy[937], 0x3 << 17, speed << 17);
2420 /* phy_939 phy_pad_cs_drive */
2421 clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
2422
YouMin Chen99027372019-11-15 11:04:48 +08002423 if (params_cfg->base.dramtype == LPDDR4) {
2424 read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
2425 set_ds_odt(&dram->chan[channel], params_cfg, true, mr5);
Jagan Teki6ea82692019-07-16 17:27:40 +05302426
YouMin Chen99027372019-11-15 11:04:48 +08002427 ctl_fn = lpddr4_get_ctl_fn(params_cfg, phy_fn);
2428 set_lpddr4_dq_odt(&dram->chan[channel], params_cfg,
2429 ctl_fn, true, true, mr5);
2430 set_lpddr4_ca_odt(&dram->chan[channel], params_cfg,
2431 ctl_fn, true, true, mr5);
2432 set_lpddr4_MR3(&dram->chan[channel], params_cfg,
2433 ctl_fn, true, mr5);
2434 set_lpddr4_MR12(&dram->chan[channel], params_cfg,
2435 ctl_fn, true, mr5);
2436 set_lpddr4_MR14(&dram->chan[channel], params_cfg,
2437 ctl_fn, true, mr5);
Jagan Teki6ea82692019-07-16 17:27:40 +05302438
YouMin Chen99027372019-11-15 11:04:48 +08002439 /*
2440 * if phy_sw_master_mode_x not bypass mode,
2441 * clear phy_slice_pwr_rdc_disable.
2442 * note: need use timings, not ddr_publ_regs
2443 */
2444 if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
2445 clrbits_le32(&denali_phy[10], 1 << 16);
2446 clrbits_le32(&denali_phy[138], 1 << 16);
2447 clrbits_le32(&denali_phy[266], 1 << 16);
2448 clrbits_le32(&denali_phy[394], 1 << 16);
2449 }
Jagan Teki6ea82692019-07-16 17:27:40 +05302450
YouMin Chen99027372019-11-15 11:04:48 +08002451 /*
2452 * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
2453 * smaller than 8
2454 * NOTE: need use timings, not ddr_publ_regs
2455 */
2456 if ((denali_phy_params[84] >> 16) & 1) {
2457 if (((readl(&denali_ctl[217 + ctl_fn]) >>
2458 16) & 0x1f) < 8)
2459 clrsetbits_le32(&denali_ctl[217 + ctl_fn],
2460 0x1f << 16,
2461 8 << 16);
2462 }
Jagan Teki6ea82692019-07-16 17:27:40 +05302463 }
2464}
2465
2466static void lpddr4_set_phy(struct dram_info *dram,
YouMin Chende57fbf2019-11-15 11:04:46 +08002467 struct rk3399_sdram_params *params, u32 phy_fn,
2468 struct rk3399_sdram_params *params_cfg)
Jagan Teki6ea82692019-07-16 17:27:40 +05302469{
2470 u32 channel;
2471
2472 for (channel = 0; channel < 2; channel++)
YouMin Chende57fbf2019-11-15 11:04:46 +08002473 lpddr4_copy_phy(dram, params, phy_fn, params_cfg,
2474 channel);
Jagan Teki6ea82692019-07-16 17:27:40 +05302475}
2476
2477static int lpddr4_set_ctl(struct dram_info *dram,
YouMin Chende57fbf2019-11-15 11:04:46 +08002478 struct rk3399_sdram_params *params,
2479 u32 fn, u32 hz)
Jagan Teki6ea82692019-07-16 17:27:40 +05302480{
2481 u32 channel;
2482 int ret_clk, ret;
2483
2484 /* cci idle req stall */
2485 writel(0x70007, &dram->grf->soc_con0);
2486
2487 /* enable all clk */
2488 setbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
2489
2490 /* idle */
2491 setbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
2492 while ((readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
2493 != (0x3 << 18))
2494 ;
2495
2496 /* change freq */
2497 writel((((0x3 << 4) | (1 << 2) | 1) << 16) |
YouMin Chende57fbf2019-11-15 11:04:46 +08002498 (fn << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
Jagan Teki6ea82692019-07-16 17:27:40 +05302499 while (!(readl(&dram->cic->cic_status0) & (1 << 2)))
2500 ;
2501
2502 ret_clk = clk_set_rate(&dram->ddr_clk, hz);
2503 if (ret_clk < 0) {
2504 printf("%s clk set failed %d\n", __func__, ret_clk);
2505 return ret_clk;
2506 }
2507
2508 writel(0x20002, &dram->cic->cic_ctrl0);
2509 while (!(readl(&dram->cic->cic_status0) & (1 << 0)))
2510 ;
2511
2512 /* deidle */
2513 clrbits_le32(&dram->pmu->pmu_bus_idle_req, (0x3 << 18));
2514 while (readl(&dram->pmu->pmu_bus_idle_st) & (0x3 << 18))
2515 ;
2516
2517 /* clear enable all clk */
2518 clrbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
2519
2520 /* lpddr4 ctl2 can not do training, all training will fail */
YouMin Chende57fbf2019-11-15 11:04:46 +08002521 if (!(params->base.dramtype == LPDDR4 && fn == 2)) {
Jagan Teki6ea82692019-07-16 17:27:40 +05302522 for (channel = 0; channel < 2; channel++) {
2523 if (!(params->ch[channel].cap_info.col))
2524 continue;
2525 ret = data_training(dram, channel, params,
YouMin Chende57fbf2019-11-15 11:04:46 +08002526 PI_FULL_TRAINING);
Jagan Teki6ea82692019-07-16 17:27:40 +05302527 if (ret)
2528 printf("%s: channel %d training failed!\n",
2529 __func__, channel);
2530 else
2531 debug("%s: channel %d training pass\n",
2532 __func__, channel);
2533 }
2534 }
2535
2536 return 0;
2537}
2538
2539static int lpddr4_set_rate(struct dram_info *dram,
2540 struct rk3399_sdram_params *params)
2541{
YouMin Chende57fbf2019-11-15 11:04:46 +08002542 u32 ctl_fn;
2543 u32 phy_fn;
Jagan Teki6ea82692019-07-16 17:27:40 +05302544
YouMin Chende57fbf2019-11-15 11:04:46 +08002545 for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
2546 phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
Jagan Teki6ea82692019-07-16 17:27:40 +05302547
YouMin Chende57fbf2019-11-15 11:04:46 +08002548 lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
2549 lpddr4_set_ctl(dram, params, ctl_fn,
2550 dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
Jagan Teki6ea82692019-07-16 17:27:40 +05302551
YouMin Chende57fbf2019-11-15 11:04:46 +08002552 printf("%s: change freq to %d mhz %d, %d\n", __func__,
2553 dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, ctl_fn, phy_fn);
Jagan Teki6ea82692019-07-16 17:27:40 +05302554 }
2555
2556 return 0;
2557}
Jagan Tekicc117bb2019-07-16 17:27:31 +05302558#endif /* CONFIG_RAM_RK3399_LPDDR4 */
2559
YouMin Chen6ba388f2019-11-15 11:04:49 +08002560/* CS0,n=1
2561 * CS1,n=2
2562 * CS0 & CS1, n=3
2563 * cs0_cap: MB unit
2564 */
2565static void dram_set_cs(const struct chan_info *chan, u32 cs_map, u32 cs0_cap,
2566 unsigned char dramtype)
2567{
2568 u32 *denali_ctl = chan->pctl->denali_ctl;
2569 u32 *denali_pi = chan->pi->denali_pi;
2570 struct msch_regs *ddr_msch_regs = chan->msch;
2571
2572 clrsetbits_le32(&denali_ctl[196], 0x3, cs_map);
2573 writel((cs0_cap / 32) | (((4096 - cs0_cap) / 32) << 8),
2574 &ddr_msch_regs->ddrsize);
2575 if (dramtype == LPDDR4) {
2576 if (cs_map == 1)
2577 cs_map = 0x5;
2578 else if (cs_map == 2)
2579 cs_map = 0xa;
2580 else
2581 cs_map = 0xF;
2582 }
2583 /*PI_41 PI_CS_MAP:RW:24:4*/
2584 clrsetbits_le32(&denali_pi[41],
2585 0xf << 24, cs_map << 24);
2586 if (cs_map == 1 && dramtype == DDR3)
2587 writel(0x2EC7FFFF, &denali_pi[34]);
2588}
2589
2590static void dram_set_bw(const struct chan_info *chan, u32 bw)
2591{
2592 u32 *denali_ctl = chan->pctl->denali_ctl;
2593
2594 if (bw == 2)
2595 clrbits_le32(&denali_ctl[196], 1 << 16);
2596 else
2597 setbits_le32(&denali_ctl[196], 1 << 16);
2598}
2599
2600static void dram_set_max_col(const struct chan_info *chan, u32 bw, u32 *pcol)
2601{
2602 u32 *denali_ctl = chan->pctl->denali_ctl;
2603 struct msch_regs *ddr_msch_regs = chan->msch;
2604 u32 *denali_pi = chan->pi->denali_pi;
2605 u32 ddrconfig;
2606
2607 clrbits_le32(&denali_ctl[191], 0xf);
2608 clrsetbits_le32(&denali_ctl[190],
2609 (7 << 24),
2610 ((16 - ((bw == 2) ? 14 : 15)) << 24));
2611 /*PI_199 PI_COL_DIFF:RW:0:4*/
2612 clrbits_le32(&denali_pi[199], 0xf);
2613 /*PI_155 PI_ROW_DIFF:RW:24:3*/
2614 clrsetbits_le32(&denali_pi[155],
2615 (7 << 24),
2616 ((16 - 12) << 24));
2617 ddrconfig = (bw == 2) ? 3 : 2;
2618 writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
2619 /* set max cs0 size */
2620 writel((4096 / 32) | ((0 / 32) << 8),
2621 &ddr_msch_regs->ddrsize);
2622
2623 *pcol = 12;
2624}
2625
2626static void dram_set_max_bank(const struct chan_info *chan, u32 bw, u32 *pbank,
2627 u32 *pcol)
2628{
2629 u32 *denali_ctl = chan->pctl->denali_ctl;
2630 u32 *denali_pi = chan->pi->denali_pi;
2631
2632 clrbits_le32(&denali_ctl[191], 0xf);
2633 clrbits_le32(&denali_ctl[190], (3 << 16));
2634 /*PI_199 PI_COL_DIFF:RW:0:4*/
2635 clrbits_le32(&denali_pi[199], 0xf);
2636 /*PI_155 PI_BANK_DIFF:RW:16:2*/
2637 clrbits_le32(&denali_pi[155], (3 << 16));
2638
2639 *pbank = 3;
2640 *pcol = 12;
2641}
2642
2643static void dram_set_max_row(const struct chan_info *chan, u32 bw, u32 *prow,
2644 u32 *pbank, u32 *pcol)
2645{
2646 u32 *denali_ctl = chan->pctl->denali_ctl;
2647 u32 *denali_pi = chan->pi->denali_pi;
2648 struct msch_regs *ddr_msch_regs = chan->msch;
2649
2650 clrsetbits_le32(&denali_ctl[191], 0xf, 12 - 10);
2651 clrbits_le32(&denali_ctl[190],
2652 (0x3 << 16) | (0x7 << 24));
2653 /*PI_199 PI_COL_DIFF:RW:0:4*/
2654 clrsetbits_le32(&denali_pi[199], 0xf, 12 - 10);
2655 /*PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2*/
2656 clrbits_le32(&denali_pi[155],
2657 (0x3 << 16) | (0x7 << 24));
2658 writel(1 | (1 << 8), &ddr_msch_regs->ddrconf);
2659 /* set max cs0 size */
2660 writel((4096 / 32) | ((0 / 32) << 8),
2661 &ddr_msch_regs->ddrsize);
2662
2663 *prow = 16;
2664 *pbank = 3;
2665 *pcol = (bw == 2) ? 10 : 11;
2666}
2667
2668static u64 dram_detect_cap(struct dram_info *dram,
2669 struct rk3399_sdram_params *params,
2670 unsigned char channel)
2671{
2672 const struct chan_info *chan = &dram->chan[channel];
2673 struct sdram_cap_info *cap_info = &params->ch[channel].cap_info;
2674 u32 bw;
2675 u32 col_tmp;
2676 u32 bk_tmp;
2677 u32 row_tmp;
2678 u32 cs0_cap;
2679 u32 training_flag;
2680 u32 ddrconfig;
2681
2682 /* detect bw */
2683 bw = 2;
2684 if (params->base.dramtype != LPDDR4) {
2685 dram_set_bw(chan, bw);
2686 cap_info->bw = bw;
2687 if (data_training(dram, channel, params,
2688 PI_READ_GATE_TRAINING)) {
2689 bw = 1;
2690 dram_set_bw(chan, 1);
2691 cap_info->bw = bw;
2692 if (data_training(dram, channel, params,
2693 PI_READ_GATE_TRAINING)) {
2694 printf("16bit error!!!\n");
2695 goto error;
2696 }
2697 }
2698 }
2699 /*
2700 * LPDDR3 CA training msut be trigger before other training.
2701 * DDR3 is not have CA training.
2702 */
2703 if (params->base.dramtype == LPDDR3)
2704 training_flag = PI_WRITE_LEVELING;
2705 else
2706 training_flag = PI_FULL_TRAINING;
2707
2708 if (params->base.dramtype != LPDDR4) {
2709 if (data_training(dram, channel, params, training_flag)) {
2710 printf("full training error!!!\n");
2711 goto error;
2712 }
2713 }
2714
2715 /* detect col */
2716 dram_set_max_col(chan, bw, &col_tmp);
2717 if (sdram_detect_col(cap_info, col_tmp) != 0)
2718 goto error;
2719
2720 /* detect bank */
2721 dram_set_max_bank(chan, bw, &bk_tmp, &col_tmp);
2722 sdram_detect_bank(cap_info, col_tmp, bk_tmp);
2723
2724 /* detect row */
2725 dram_set_max_row(chan, bw, &row_tmp, &bk_tmp, &col_tmp);
2726 if (sdram_detect_row(cap_info, col_tmp, bk_tmp, row_tmp) != 0)
2727 goto error;
2728
2729 /* detect row_3_4 */
2730 sdram_detect_row_3_4(cap_info, col_tmp, bk_tmp);
2731
2732 /* set ddrconfig */
2733 cs0_cap = (1 << (cap_info->cs0_row + cap_info->col + cap_info->bk +
2734 cap_info->bw - 20));
2735 if (cap_info->row_3_4)
2736 cs0_cap = cs0_cap * 3 / 4;
2737
2738 cap_info->cs1_row = cap_info->cs0_row;
2739 set_memory_map(chan, channel, params);
2740 ddrconfig = calculate_ddrconfig(params, channel);
2741 if (-1 == ddrconfig)
2742 goto error;
2743 set_ddrconfig(chan, params, channel,
2744 cap_info->ddrconfig);
2745
2746 /* detect cs1 row */
2747 sdram_detect_cs1_row(cap_info, params->base.dramtype);
2748
2749 /* detect die bw */
2750 sdram_detect_dbw(cap_info, params->base.dramtype);
2751
2752 return 0;
2753error:
2754 return (-1);
2755}
2756
Jagan Teki2525fae2019-07-15 23:58:52 +05302757static unsigned char calculate_stride(struct rk3399_sdram_params *params)
2758{
Kever Yange2b64fd2019-11-15 11:04:52 +08002759 unsigned int gstride_type;
2760 unsigned int channel;
2761 unsigned int chinfo = 0;
2762 unsigned int cap = 0;
2763 unsigned int stride = -1;
Jagan Teki2525fae2019-07-15 23:58:52 +05302764 unsigned int ch_cap[2] = {0, 0};
Kever Yange2b64fd2019-11-15 11:04:52 +08002765
2766 gstride_type = STRIDE_256B;
Jagan Teki2525fae2019-07-15 23:58:52 +05302767
2768 for (channel = 0; channel < 2; channel++) {
2769 unsigned int cs0_cap = 0;
2770 unsigned int cs1_cap = 0;
Kever Yange2b64fd2019-11-15 11:04:52 +08002771 struct sdram_cap_info *cap_info =
2772 &params->ch[channel].cap_info;
Jagan Teki2525fae2019-07-15 23:58:52 +05302773
2774 if (cap_info->col == 0)
2775 continue;
2776
2777 cs0_cap = (1 << (cap_info->cs0_row + cap_info->col +
2778 cap_info->bk + cap_info->bw - 20));
2779 if (cap_info->rank > 1)
2780 cs1_cap = cs0_cap >> (cap_info->cs0_row
2781 - cap_info->cs1_row);
2782 if (cap_info->row_3_4) {
2783 cs0_cap = cs0_cap * 3 / 4;
2784 cs1_cap = cs1_cap * 3 / 4;
2785 }
2786 ch_cap[channel] = cs0_cap + cs1_cap;
2787 chinfo |= 1 << channel;
2788 }
2789
Kever Yange2b64fd2019-11-15 11:04:52 +08002790 cap = ch_cap[0] + ch_cap[1];
2791 if (params->base.num_channels == 1) {
2792 if (chinfo & 1) /* channel a only */
2793 stride = 0x17;
2794 else /* channel b only */
2795 stride = 0x18;
2796 } else {/* 2 channel */
2797 if (ch_cap[0] == ch_cap[1]) {
2798 /* interleaved */
2799 if (gstride_type == PART_STRIDE) {
2800 /*
2801 * first 64MB no interleaved other 256B interleaved
2802 * if 786M+768M.useful space from 0-1280MB and
2803 * 1536MB-1792MB
2804 * if 1.5G+1.5G(continuous).useful space from 0-2560MB
2805 * and 3072MB-3584MB
2806 */
2807 stride = 0x1F;
2808 } else {
2809 switch (cap) {
2810 /* 512MB */
2811 case 512:
2812 stride = 0;
2813 break;
2814 /* 1GB unstride or 256B stride*/
2815 case 1024:
2816 stride = (gstride_type == UN_STRIDE) ?
2817 0x1 : 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 unstride or 256B or 512B stride */
2825 case 2048:
2826 stride = (gstride_type == UN_STRIDE) ?
2827 0x2 :
2828 ((gstride_type == STRIDE_512B) ?
2829 0xA : 0x9);
2830 break;
2831 /* 1536MB + 1536MB */
2832 case 3072:
2833 stride = (gstride_type == UN_STRIDE) ?
2834 0x3 :
2835 ((gstride_type == STRIDE_512B) ?
2836 0x12 : 0x11);
2837 break;
2838 /* 4GB unstride or 128B,256B,512B,4KB stride */
2839 case 4096:
2840 stride = (gstride_type == UN_STRIDE) ?
2841 0x3 : (0xC + gstride_type);
2842 break;
2843 }
2844 }
2845 }
2846 if (ch_cap[0] == 2048 && ch_cap[1] == 1024) {
2847 /* 2GB + 1GB */
2848 stride = (gstride_type == UN_STRIDE) ? 0x3 : 0x19;
2849 }
Jagan Teki2525fae2019-07-15 23:58:52 +05302850 /*
Kever Yange2b64fd2019-11-15 11:04:52 +08002851 * remain two channel capability not equal OR capability
2852 * power function of 2
Jagan Teki2525fae2019-07-15 23:58:52 +05302853 */
Kever Yange2b64fd2019-11-15 11:04:52 +08002854 if (stride == (-1)) {
2855 switch ((ch_cap[0] > ch_cap[1]) ?
2856 ch_cap[0] : ch_cap[1]) {
2857 case 256: /* 256MB + 128MB */
2858 stride = 0;
2859 break;
2860 case 512: /* 512MB + 256MB */
2861 stride = 1;
2862 break;
2863 case 1024:/* 1GB + 128MB/256MB/384MB/512MB/768MB */
2864 stride = 2;
2865 break;
2866 case 2048: /* 2GB + 128MB/256MB/384MB/512MB/768MB/1GB */
2867 stride = 3;
2868 break;
2869 default:
2870 break;
2871 }
Jagan Teki2525fae2019-07-15 23:58:52 +05302872 }
Kever Yange2b64fd2019-11-15 11:04:52 +08002873 if (stride == (-1))
2874 goto error;
2875 }
2876 switch (stride) {
2877 case 0xc:
2878 printf("128B stride\n");
2879 break;
2880 case 5:
2881 case 9:
2882 case 0xd:
2883 case 0x11:
2884 case 0x19:
2885 printf("256B stride\n");
2886 break;
2887 case 0xa:
2888 case 0xe:
2889 case 0x12:
2890 printf("512B stride\n");
2891 break;
2892 case 0xf:
2893 printf("4K stride\n");
2894 break;
2895 case 0x1f:
2896 printf("32MB + 256B stride\n");
2897 break;
2898 default:
2899 printf("no stride\n");
Jagan Teki2525fae2019-07-15 23:58:52 +05302900 }
2901
Jagan Teki8eed4a42019-07-15 23:58:55 +05302902 sdram_print_stride(stride);
2903
Jagan Teki2525fae2019-07-15 23:58:52 +05302904 return stride;
Kever Yange2b64fd2019-11-15 11:04:52 +08002905error:
2906 printf("Cap not support!\n");
2907 return (-1);
Jagan Teki2525fae2019-07-15 23:58:52 +05302908}
2909
Jagan Teki43485e12019-07-15 23:58:54 +05302910static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
2911{
2912 params->ch[channel].cap_info.rank = 0;
2913 params->ch[channel].cap_info.col = 0;
2914 params->ch[channel].cap_info.bk = 0;
2915 params->ch[channel].cap_info.bw = 32;
2916 params->ch[channel].cap_info.dbw = 32;
2917 params->ch[channel].cap_info.row_3_4 = 0;
2918 params->ch[channel].cap_info.cs0_row = 0;
2919 params->ch[channel].cap_info.cs1_row = 0;
2920 params->ch[channel].cap_info.ddrconfig = 0;
2921}
2922
Kever Yang50fb9982017-02-22 16:56:35 +08002923static int sdram_init(struct dram_info *dram,
Jagan Teki2525fae2019-07-15 23:58:52 +05302924 struct rk3399_sdram_params *params)
Kever Yang50fb9982017-02-22 16:56:35 +08002925{
Jagan Tekia58ff792019-07-15 23:50:58 +05302926 unsigned char dramtype = params->base.dramtype;
2927 unsigned int ddr_freq = params->base.ddr_freq;
Jagan Teki43485e12019-07-15 23:58:54 +05302928 int channel, ch, rank;
YouMin Chen6ba388f2019-11-15 11:04:49 +08002929 u32 tmp, ret;
Kever Yang50fb9982017-02-22 16:56:35 +08002930
2931 debug("Starting SDRAM initialization...\n");
2932
Philipp Tomsich39dce4a2017-05-31 18:16:35 +02002933 if ((dramtype == DDR3 && ddr_freq > 933) ||
Kever Yang50fb9982017-02-22 16:56:35 +08002934 (dramtype == LPDDR3 && ddr_freq > 933) ||
2935 (dramtype == LPDDR4 && ddr_freq > 800)) {
2936 debug("SDRAM frequency is to high!");
2937 return -E2BIG;
2938 }
2939
YouMin Chen99027372019-11-15 11:04:48 +08002940 /* detect rank */
Jagan Teki43485e12019-07-15 23:58:54 +05302941 for (ch = 0; ch < 2; ch++) {
2942 params->ch[ch].cap_info.rank = 2;
2943 for (rank = 2; rank != 0; rank--) {
YouMin Chen99027372019-11-15 11:04:48 +08002944 for (channel = 0; channel < 2; channel++) {
2945 const struct chan_info *chan =
2946 &dram->chan[channel];
Jagan Teki783acfd2020-01-09 14:22:17 +05302947 struct rockchip_cru *cru = dram->cru;
YouMin Chen99027372019-11-15 11:04:48 +08002948 struct rk3399_ddr_publ_regs *publ = chan->publ;
2949
2950 phy_pctrl_reset(cru, channel);
2951 phy_dll_bypass_set(publ, ddr_freq);
2952 pctl_cfg(dram, chan, channel, params);
Jagan Teki43485e12019-07-15 23:58:54 +05302953 }
2954
YouMin Chen99027372019-11-15 11:04:48 +08002955 /* start to trigger initialization */
2956 pctl_start(dram, params, 3);
2957
Jagan Teki43485e12019-07-15 23:58:54 +05302958 /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
2959 if (dramtype == LPDDR3)
2960 udelay(10);
2961
YouMin Chen6ba388f2019-11-15 11:04:49 +08002962 tmp = (rank == 2) ? 3 : 1;
2963 dram_set_cs(&dram->chan[ch], tmp, 2048,
2964 params->base.dramtype);
Jagan Teki43485e12019-07-15 23:58:54 +05302965 params->ch[ch].cap_info.rank = rank;
2966
YouMin Chende57fbf2019-11-15 11:04:46 +08002967 ret = dram->ops->data_training_first(dram, ch,
2968 rank, params);
Jagan Teki9eb935a2019-07-16 17:27:30 +05302969 if (!ret) {
2970 debug("%s: data trained for rank %d, ch %d\n",
2971 __func__, rank, ch);
Jagan Teki43485e12019-07-15 23:58:54 +05302972 break;
Jagan Teki9eb935a2019-07-16 17:27:30 +05302973 }
Jagan Teki43485e12019-07-15 23:58:54 +05302974 }
2975 /* Computed rank with associated channel number */
2976 params->ch[ch].cap_info.rank = rank;
2977 }
2978
2979 params->base.num_channels = 0;
Kever Yang50fb9982017-02-22 16:56:35 +08002980 for (channel = 0; channel < 2; channel++) {
2981 const struct chan_info *chan = &dram->chan[channel];
YouMin Chen99027372019-11-15 11:04:48 +08002982 struct sdram_cap_info *cap_info =
2983 &params->ch[channel].cap_info;
Kever Yang50fb9982017-02-22 16:56:35 +08002984
Jagan Teki43485e12019-07-15 23:58:54 +05302985 if (cap_info->rank == 0) {
YouMin Chen6ba388f2019-11-15 11:04:49 +08002986 clear_channel_params(params, 1);
Kever Yang50fb9982017-02-22 16:56:35 +08002987 continue;
Jagan Teki43485e12019-07-15 23:58:54 +05302988 } else {
2989 params->base.num_channels++;
Kever Yang50fb9982017-02-22 16:56:35 +08002990 }
2991
YouMin Chende57fbf2019-11-15 11:04:46 +08002992 printf("Channel ");
2993 printf(channel ? "1: " : "0: ");
Jagan Tekic9151e22019-07-15 23:58:45 +05302994
YouMin Chen6ba388f2019-11-15 11:04:49 +08002995 if (channel == 0)
2996 set_ddr_stride(dram->pmusgrf, 0x17);
2997 else
2998 set_ddr_stride(dram->pmusgrf, 0x18);
Kever Yang50fb9982017-02-22 16:56:35 +08002999
YouMin Chen6ba388f2019-11-15 11:04:49 +08003000 if (dram_detect_cap(dram, params, channel)) {
3001 printf("Cap error!\n");
3002 continue;
Kever Yang50fb9982017-02-22 16:56:35 +08003003 }
3004
Jagan Teki8eed4a42019-07-15 23:58:55 +05303005 sdram_print_ddr_info(cap_info, &params->base);
Kever Yange723a552019-08-12 20:02:29 +08003006 set_memory_map(chan, channel, params);
YouMin Chen99027372019-11-15 11:04:48 +08003007 cap_info->ddrconfig =
3008 calculate_ddrconfig(params, channel);
3009 if (-1 == cap_info->ddrconfig) {
3010 printf("no ddrconfig find, Cap not support!\n");
3011 continue;
3012 }
Jagan Teki43485e12019-07-15 23:58:54 +05303013 set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
Kever Yange723a552019-08-12 20:02:29 +08003014 set_cap_relate_config(chan, params, channel);
Jagan Teki43485e12019-07-15 23:58:54 +05303015 }
3016
3017 if (params->base.num_channels == 0) {
3018 printf("%s: ", __func__);
Jagan Teki8eed4a42019-07-15 23:58:55 +05303019 sdram_print_dram_type(params->base.dramtype);
Jagan Teki43485e12019-07-15 23:58:54 +05303020 printf(" - %dMHz failed!\n", params->base.ddr_freq);
3021 return -EINVAL;
Kever Yang50fb9982017-02-22 16:56:35 +08003022 }
Jagan Teki2525fae2019-07-15 23:58:52 +05303023
3024 params->base.stride = calculate_stride(params);
Jagan Tekia58ff792019-07-15 23:50:58 +05303025 dram_all_config(dram, params);
YouMin Chende57fbf2019-11-15 11:04:46 +08003026
3027 dram->ops->set_rate_index(dram, params);
Kever Yang50fb9982017-02-22 16:56:35 +08003028
3029 debug("Finish SDRAM initialization...\n");
3030 return 0;
3031}
3032
3033static int rk3399_dmc_ofdata_to_platdata(struct udevice *dev)
3034{
3035#if !CONFIG_IS_ENABLED(OF_PLATDATA)
3036 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
Kever Yang50fb9982017-02-22 16:56:35 +08003037 int ret;
3038
Philipp Tomsich0250c232017-06-07 18:46:03 +02003039 ret = dev_read_u32_array(dev, "rockchip,sdram-params",
3040 (u32 *)&plat->sdram_params,
3041 sizeof(plat->sdram_params) / sizeof(u32));
Kever Yang50fb9982017-02-22 16:56:35 +08003042 if (ret) {
3043 printf("%s: Cannot read rockchip,sdram-params %d\n",
3044 __func__, ret);
3045 return ret;
3046 }
Masahiro Yamadae4873e32018-04-19 12:14:03 +09003047 ret = regmap_init_mem(dev_ofnode(dev), &plat->map);
Kever Yang50fb9982017-02-22 16:56:35 +08003048 if (ret)
3049 printf("%s: regmap failed %d\n", __func__, ret);
3050
3051#endif
3052 return 0;
3053}
3054
3055#if CONFIG_IS_ENABLED(OF_PLATDATA)
3056static int conv_of_platdata(struct udevice *dev)
3057{
3058 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
3059 struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
3060 int ret;
3061
3062 ret = regmap_init_mem_platdata(dev, dtplat->reg,
Jagan Tekif676c7c2019-07-15 23:50:56 +05303063 ARRAY_SIZE(dtplat->reg) / 2,
3064 &plat->map);
Kever Yang50fb9982017-02-22 16:56:35 +08003065 if (ret)
3066 return ret;
3067
3068 return 0;
3069}
3070#endif
3071
Jagan Teki9eb935a2019-07-16 17:27:30 +05303072static const struct sdram_rk3399_ops rk3399_ops = {
Jagan Tekicc117bb2019-07-16 17:27:31 +05303073#if !defined(CONFIG_RAM_RK3399_LPDDR4)
YouMin Chende57fbf2019-11-15 11:04:46 +08003074 .data_training_first = data_training_first,
3075 .set_rate_index = switch_to_phy_index1,
YouMin Chen99027372019-11-15 11:04:48 +08003076 .modify_param = modify_param,
3077 .get_phy_index_params = get_phy_index_params,
Jagan Tekicc117bb2019-07-16 17:27:31 +05303078#else
YouMin Chende57fbf2019-11-15 11:04:46 +08003079 .data_training_first = lpddr4_mr_detect,
3080 .set_rate_index = lpddr4_set_rate,
YouMin Chen99027372019-11-15 11:04:48 +08003081 .modify_param = lpddr4_modify_param,
3082 .get_phy_index_params = lpddr4_get_phy_index_params,
Jagan Tekicc117bb2019-07-16 17:27:31 +05303083#endif
Jagan Teki9eb935a2019-07-16 17:27:30 +05303084};
3085
Kever Yang50fb9982017-02-22 16:56:35 +08003086static int rk3399_dmc_init(struct udevice *dev)
3087{
3088 struct dram_info *priv = dev_get_priv(dev);
3089 struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
3090 int ret;
3091#if !CONFIG_IS_ENABLED(OF_PLATDATA)
3092 struct rk3399_sdram_params *params = &plat->sdram_params;
3093#else
3094 struct dtd_rockchip_rk3399_dmc *dtplat = &plat->dtplat;
3095 struct rk3399_sdram_params *params =
3096 (void *)dtplat->rockchip_sdram_params;
3097
3098 ret = conv_of_platdata(dev);
3099 if (ret)
3100 return ret;
3101#endif
3102
Jagan Teki9eb935a2019-07-16 17:27:30 +05303103 priv->ops = &rk3399_ops;
Kever Yang50fb9982017-02-22 16:56:35 +08003104 priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
Jagan Tekic9151e22019-07-15 23:58:45 +05303105 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Jagan Teki6ea82692019-07-16 17:27:40 +05303106 priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
Kever Yang50fb9982017-02-22 16:56:35 +08003107 priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
3108 priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
3109 priv->pmucru = rockchip_get_pmucru();
3110 priv->cru = rockchip_get_cru();
3111 priv->chan[0].pctl = regmap_get_range(plat->map, 0);
3112 priv->chan[0].pi = regmap_get_range(plat->map, 1);
3113 priv->chan[0].publ = regmap_get_range(plat->map, 2);
3114 priv->chan[0].msch = regmap_get_range(plat->map, 3);
3115 priv->chan[1].pctl = regmap_get_range(plat->map, 4);
3116 priv->chan[1].pi = regmap_get_range(plat->map, 5);
3117 priv->chan[1].publ = regmap_get_range(plat->map, 6);
3118 priv->chan[1].msch = regmap_get_range(plat->map, 7);
3119
3120 debug("con reg %p %p %p %p %p %p %p %p\n",
3121 priv->chan[0].pctl, priv->chan[0].pi,
3122 priv->chan[0].publ, priv->chan[0].msch,
3123 priv->chan[1].pctl, priv->chan[1].pi,
3124 priv->chan[1].publ, priv->chan[1].msch);
Jagan Teki6ea82692019-07-16 17:27:40 +05303125 debug("cru %p, cic %p, grf %p, sgrf %p, pmucru %p, pmu %p\n", priv->cru,
3126 priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05303127
Kever Yang50fb9982017-02-22 16:56:35 +08003128#if CONFIG_IS_ENABLED(OF_PLATDATA)
3129 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
3130#else
3131 ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
3132#endif
3133 if (ret) {
3134 printf("%s clk get failed %d\n", __func__, ret);
3135 return ret;
3136 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05303137
Kever Yang50fb9982017-02-22 16:56:35 +08003138 ret = clk_set_rate(&priv->ddr_clk, params->base.ddr_freq * MHz);
3139 if (ret < 0) {
3140 printf("%s clk set failed %d\n", __func__, ret);
3141 return ret;
3142 }
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05303143
Kever Yang50fb9982017-02-22 16:56:35 +08003144 ret = sdram_init(priv, params);
3145 if (ret < 0) {
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05303146 printf("%s DRAM init failed %d\n", __func__, ret);
Kever Yang50fb9982017-02-22 16:56:35 +08003147 return ret;
3148 }
3149
3150 return 0;
3151}
3152#endif
3153
Kever Yang50fb9982017-02-22 16:56:35 +08003154static int rk3399_dmc_probe(struct udevice *dev)
3155{
Kever Yang7f347842019-04-01 17:20:53 +08003156#if defined(CONFIG_TPL_BUILD) || \
3157 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yang50fb9982017-02-22 16:56:35 +08003158 if (rk3399_dmc_init(dev))
3159 return 0;
3160#else
3161 struct dram_info *priv = dev_get_priv(dev);
3162
3163 priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
Jagan Tekiacf8e0f2019-07-15 23:50:57 +05303164 debug("%s: pmugrf = %p\n", __func__, priv->pmugrf);
Kever Yang6c15a542017-06-23 16:11:06 +08003165 priv->info.base = CONFIG_SYS_SDRAM_BASE;
Jagan Tekif676c7c2019-07-15 23:50:56 +05303166 priv->info.size =
3167 rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg2);
Kever Yang50fb9982017-02-22 16:56:35 +08003168#endif
3169 return 0;
3170}
3171
3172static int rk3399_dmc_get_info(struct udevice *dev, struct ram_info *info)
3173{
3174 struct dram_info *priv = dev_get_priv(dev);
3175
Kever Yangea61d142017-04-19 16:01:14 +08003176 *info = priv->info;
Kever Yang50fb9982017-02-22 16:56:35 +08003177
3178 return 0;
3179}
3180
3181static struct ram_ops rk3399_dmc_ops = {
3182 .get_info = rk3399_dmc_get_info,
3183};
3184
Kever Yang50fb9982017-02-22 16:56:35 +08003185static const struct udevice_id rk3399_dmc_ids[] = {
3186 { .compatible = "rockchip,rk3399-dmc" },
3187 { }
3188};
3189
3190U_BOOT_DRIVER(dmc_rk3399) = {
3191 .name = "rockchip_rk3399_dmc",
3192 .id = UCLASS_RAM,
3193 .of_match = rk3399_dmc_ids,
3194 .ops = &rk3399_dmc_ops,
Kever Yang7f347842019-04-01 17:20:53 +08003195#if defined(CONFIG_TPL_BUILD) || \
3196 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yang50fb9982017-02-22 16:56:35 +08003197 .ofdata_to_platdata = rk3399_dmc_ofdata_to_platdata,
3198#endif
3199 .probe = rk3399_dmc_probe,
Kever Yang50fb9982017-02-22 16:56:35 +08003200 .priv_auto_alloc_size = sizeof(struct dram_info),
Kever Yang7f347842019-04-01 17:20:53 +08003201#if defined(CONFIG_TPL_BUILD) || \
3202 (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
Kever Yang50fb9982017-02-22 16:56:35 +08003203 .platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
3204#endif
3205};