blob: 4fdd3894d3fe69407b39bfb46a9848c009b373e9 [file] [log] [blame]
Caesar Wanga8456902016-10-27 01:12:34 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <debug.h>
32#include <mmio.h>
33#include <plat_private.h>
34#include "dfs.h"
35#include "dram.h"
36#include "dram_spec_timing.h"
37#include "string.h"
38#include "soc.h"
39#include "pmu.h"
40
41#include <delay_timer.h>
42
43#define CTL_TRAINING (1)
44#define PI_TRAINING (!CTL_TRAINING)
45
46#define EN_READ_GATE_TRAINING (1)
47#define EN_CA_TRAINING (0)
48#define EN_WRITE_LEVELING (0)
49#define EN_READ_LEVELING (0)
50#define EN_WDQ_LEVELING (0)
51
52#define ENPER_CS_TRAINING_FREQ (933)
53
54struct pll_div {
55 unsigned int mhz;
56 unsigned int refdiv;
57 unsigned int fbdiv;
58 unsigned int postdiv1;
59 unsigned int postdiv2;
60 unsigned int frac;
61 unsigned int freq;
62};
63
64static const struct pll_div dpll_rates_table[] = {
65
66 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */
67 {.mhz = 933, .refdiv = 3, .fbdiv = 350, .postdiv1 = 3, .postdiv2 = 1},
68 {.mhz = 800, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1},
69 {.mhz = 732, .refdiv = 1, .fbdiv = 61, .postdiv1 = 2, .postdiv2 = 1},
70 {.mhz = 666, .refdiv = 1, .fbdiv = 111, .postdiv1 = 4, .postdiv2 = 1},
71 {.mhz = 600, .refdiv = 1, .fbdiv = 50, .postdiv1 = 2, .postdiv2 = 1},
72 {.mhz = 528, .refdiv = 1, .fbdiv = 66, .postdiv1 = 3, .postdiv2 = 1},
73 {.mhz = 400, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1},
74 {.mhz = 300, .refdiv = 1, .fbdiv = 50, .postdiv1 = 4, .postdiv2 = 1},
75 {.mhz = 200, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 2},
76};
77
Caesar Wanga8456902016-10-27 01:12:34 +080078struct rk3399_dram_status {
79 uint32_t current_index;
80 uint32_t index_freq[2];
81 uint32_t low_power_stat;
82 struct timing_related_config timing_config;
83 struct drv_odt_lp_config drv_odt_lp_cfg;
84};
85
86static struct rk3399_dram_status rk3399_dram_status;
87static struct ddr_dts_config_timing dts_parameter = {
88 .available = 0
89};
90
91static struct rk3399_sdram_default_config ddr3_default_config = {
92 .bl = 8,
93 .ap = 0,
94 .dramds = 40,
95 .dramodt = 120,
96 .burst_ref_cnt = 1,
97 .zqcsi = 0
98};
99
100static struct drv_odt_lp_config ddr3_drv_odt_default_config = {
101 .ddr3_speed_bin = DDR3_DEFAULT,
102 .pd_idle = 0,
103 .sr_idle = 0,
104 .sr_mc_gate_idle = 0,
105 .srpd_lite_idle = 0,
106 .standby_idle = 0,
107
108 .ddr3_dll_dis_freq = 300,
109 .phy_dll_dis_freq = 125,
110 .odt_dis_freq = 933,
111
112 .dram_side_drv = 40,
113 .dram_side_dq_odt = 120,
114 .dram_side_ca_odt = 120,
115
116 .phy_side_ca_drv = 40,
117 .phy_side_ck_cs_drv = 40,
118 .phy_side_dq_drv = 40,
119 .phy_side_odt = 240,
120};
121
122static struct rk3399_sdram_default_config lpddr3_default_config = {
123 .bl = 8,
124 .ap = 0,
125 .dramds = 34,
126 .dramodt = 240,
127 .burst_ref_cnt = 1,
128 .zqcsi = 0
129};
130
131static struct drv_odt_lp_config lpddr3_drv_odt_default_config = {
132 .ddr3_speed_bin = DDR3_DEFAULT,
133 .pd_idle = 0,
134 .sr_idle = 0,
135 .sr_mc_gate_idle = 0,
136 .srpd_lite_idle = 0,
137 .standby_idle = 0,
138
139 .ddr3_dll_dis_freq = 300,
140 .phy_dll_dis_freq = 125,
141 .odt_dis_freq = 666,
142
143 .dram_side_drv = 40,
144 .dram_side_dq_odt = 120,
145 .dram_side_ca_odt = 120,
146
147 .phy_side_ca_drv = 40,
148 .phy_side_ck_cs_drv = 40,
149 .phy_side_dq_drv = 40,
150 .phy_side_odt = 240,
151};
152
153static struct rk3399_sdram_default_config lpddr4_default_config = {
154 .bl = 16,
155 .ap = 0,
156 .dramds = 40,
157 .dramodt = 240,
158 .caodt = 240,
159 .burst_ref_cnt = 1,
160 .zqcsi = 0
161};
162
163static struct drv_odt_lp_config lpddr4_drv_odt_default_config = {
164 .ddr3_speed_bin = DDR3_DEFAULT,
165 .pd_idle = 0,
166 .sr_idle = 0,
167 .sr_mc_gate_idle = 0,
168 .srpd_lite_idle = 0,
169 .standby_idle = 0,
170
171 .ddr3_dll_dis_freq = 300,
172 .phy_dll_dis_freq = 125,
173 .odt_dis_freq = 933,
174
175 .dram_side_drv = 60,
176 .dram_side_dq_odt = 40,
177 .dram_side_ca_odt = 40,
178
179 .phy_side_ca_drv = 40,
180 .phy_side_ck_cs_drv = 80,
181 .phy_side_dq_drv = 80,
182 .phy_side_odt = 60,
183};
184
185uint32_t dcf_code[] = {
186#include "dcf_code.inc"
187};
188
Caesar Wanga8456902016-10-27 01:12:34 +0800189#define DCF_START_ADDR (SRAM_BASE + 0x1400)
190#define DCF_PARAM_ADDR (SRAM_BASE + 0x1000)
191
192/* DCF_PAMET */
193#define PARAM_DRAM_FREQ (0)
194#define PARAM_DPLL_CON0 (4)
195#define PARAM_DPLL_CON1 (8)
196#define PARAM_DPLL_CON2 (0xc)
197#define PARAM_DPLL_CON3 (0x10)
198#define PARAM_DPLL_CON4 (0x14)
199#define PARAM_DPLL_CON5 (0x18)
200/* equal to fn<<4 */
201#define PARAM_FREQ_SELECT (0x1c)
202
203static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config,
204 uint8_t channel, uint8_t cs)
205{
206 struct rk3399_sdram_channel *ch = &sdram_config->ch[channel];
207 uint32_t bandwidth;
208 uint32_t die_bandwidth;
209 uint32_t die;
210 uint32_t cs_cap;
211 uint32_t row;
212
213 row = cs == 0 ? ch->cs0_row : ch->cs1_row;
214 bandwidth = 8 * (1 << ch->bw);
215 die_bandwidth = 8 * (1 << ch->dbw);
216 die = bandwidth / die_bandwidth;
217 cs_cap = (1 << (row + ((1 << ch->bk) / 4 + 1) + ch->col +
218 (bandwidth / 16)));
219 if (ch->row_3_4)
220 cs_cap = cs_cap * 3 / 4;
221
222 return (cs_cap / die);
223}
224
225static void drv_odt_lp_cfg_init(uint32_t dram_type,
226 struct ddr_dts_config_timing *dts_timing,
227 struct drv_odt_lp_config *drv_config)
228{
229 if ((dts_timing) && (dts_timing->available)) {
230 drv_config->ddr3_speed_bin = dts_timing->ddr3_speed_bin;
231 drv_config->pd_idle = dts_timing->pd_idle;
232 drv_config->sr_idle = dts_timing->sr_idle;
233 drv_config->sr_mc_gate_idle = dts_timing->sr_mc_gate_idle;
234 drv_config->srpd_lite_idle = dts_timing->srpd_lite_idle;
235 drv_config->standby_idle = dts_timing->standby_idle;
236 drv_config->ddr3_dll_dis_freq = dts_timing->ddr3_dll_dis_freq;
237 drv_config->phy_dll_dis_freq = dts_timing->phy_dll_dis_freq;
238 }
239
240 switch (dram_type) {
241 case DDR3:
242 if ((dts_timing) && (dts_timing->available)) {
243 drv_config->odt_dis_freq =
244 dts_timing->ddr3_odt_dis_freq;
245 drv_config->dram_side_drv = dts_timing->ddr3_drv;
246 drv_config->dram_side_dq_odt = dts_timing->ddr3_odt;
247 drv_config->phy_side_ca_drv =
248 dts_timing->phy_ddr3_ca_drv;
249 drv_config->phy_side_ck_cs_drv =
250 dts_timing->phy_ddr3_ca_drv;
251 drv_config->phy_side_dq_drv =
252 dts_timing->phy_ddr3_dq_drv;
253 drv_config->phy_side_odt = dts_timing->phy_ddr3_odt;
254 } else {
255 memcpy(drv_config, &ddr3_drv_odt_default_config,
256 sizeof(struct drv_odt_lp_config));
257 }
258 break;
259 case LPDDR3:
260 if ((dts_timing) && (dts_timing->available)) {
261 drv_config->odt_dis_freq =
262 dts_timing->lpddr3_odt_dis_freq;
263 drv_config->dram_side_drv = dts_timing->lpddr3_drv;
264 drv_config->dram_side_dq_odt = dts_timing->lpddr3_odt;
265 drv_config->phy_side_ca_drv =
266 dts_timing->phy_lpddr3_ca_drv;
267 drv_config->phy_side_ck_cs_drv =
268 dts_timing->phy_lpddr3_ca_drv;
269 drv_config->phy_side_dq_drv =
270 dts_timing->phy_lpddr3_dq_drv;
271 drv_config->phy_side_odt = dts_timing->phy_lpddr3_odt;
272
273 } else {
274 memcpy(drv_config, &lpddr3_drv_odt_default_config,
275 sizeof(struct drv_odt_lp_config));
276 }
277 break;
278 case LPDDR4:
279 default:
280 if ((dts_timing) && (dts_timing->available)) {
281 drv_config->odt_dis_freq =
282 dts_timing->lpddr4_odt_dis_freq;
283 drv_config->dram_side_drv = dts_timing->lpddr4_drv;
284 drv_config->dram_side_dq_odt =
285 dts_timing->lpddr4_dq_odt;
286 drv_config->dram_side_ca_odt =
287 dts_timing->lpddr4_ca_odt;
288 drv_config->phy_side_ca_drv =
289 dts_timing->phy_lpddr4_ca_drv;
290 drv_config->phy_side_ck_cs_drv =
291 dts_timing->phy_lpddr4_ck_cs_drv;
292 drv_config->phy_side_dq_drv =
293 dts_timing->phy_lpddr4_dq_drv;
294 drv_config->phy_side_odt = dts_timing->phy_lpddr4_odt;
295 } else {
296 memcpy(drv_config, &lpddr4_drv_odt_default_config,
297 sizeof(struct drv_odt_lp_config));
298 }
299 break;
300 }
301
302 switch (drv_config->phy_side_ca_drv) {
303 case 240:
304 drv_config->phy_side_ca_drv = PHY_DRV_ODT_240;
305 break;
306 case 120:
307 drv_config->phy_side_ca_drv = PHY_DRV_ODT_120;
308 break;
309 case 80:
310 drv_config->phy_side_ca_drv = PHY_DRV_ODT_80;
311 break;
312 case 60:
313 drv_config->phy_side_ca_drv = PHY_DRV_ODT_60;
314 break;
315 case 48:
316 drv_config->phy_side_ca_drv = PHY_DRV_ODT_48;
317 break;
318 case 40:
319 drv_config->phy_side_ca_drv = PHY_DRV_ODT_40;
320 break;
321 default:
322 drv_config->phy_side_ca_drv = PHY_DRV_ODT_34_3;
323 break;
324 };
325
326 switch (drv_config->phy_side_ck_cs_drv) {
327 case 240:
328 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_240;
329 break;
330 case 120:
331 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_120;
332 break;
333 case 80:
334 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_80;
335 break;
336 case 60:
337 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_60;
338 break;
339 case 48:
340 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_48;
341 break;
342 case 40:
343 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_40;
344 break;
345 default:
346 drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_34_3;
347 break;
348 }
349
350 switch (drv_config->phy_side_dq_drv) {
351 case 240:
352 drv_config->phy_side_dq_drv = PHY_DRV_ODT_240;
353 break;
354 case 120:
355 drv_config->phy_side_dq_drv = PHY_DRV_ODT_120;
356 break;
357 case 80:
358 drv_config->phy_side_dq_drv = PHY_DRV_ODT_80;
359 break;
360 case 60:
361 drv_config->phy_side_dq_drv = PHY_DRV_ODT_60;
362 break;
363 case 48:
364 drv_config->phy_side_dq_drv = PHY_DRV_ODT_48;
365 break;
366 case 40:
367 drv_config->phy_side_dq_drv = PHY_DRV_ODT_40;
368 break;
369 default:
370 drv_config->phy_side_dq_drv = PHY_DRV_ODT_34_3;
371 break;
372 }
373
374 switch (drv_config->phy_side_odt) {
375 case 240:
376 drv_config->phy_side_odt = PHY_DRV_ODT_240;
377 break;
378 case 120:
379 drv_config->phy_side_odt = PHY_DRV_ODT_120;
380 break;
381 case 80:
382 drv_config->phy_side_odt = PHY_DRV_ODT_80;
383 break;
384 case 60:
385 drv_config->phy_side_odt = PHY_DRV_ODT_60;
386 break;
387 case 48:
388 drv_config->phy_side_odt = PHY_DRV_ODT_48;
389 break;
390 case 40:
391 drv_config->phy_side_odt = PHY_DRV_ODT_40;
392 break;
393 default:
394 drv_config->phy_side_odt = PHY_DRV_ODT_34_3;
395 break;
396 }
397}
398
399static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config,
400 struct rk3399_sdram_params *sdram_params,
401 struct drv_odt_lp_config *drv_config)
402{
403 uint32_t i, j;
404
405 for (i = 0; i < sdram_params->num_channels; i++) {
406 ptiming_config->dram_info[i].speed_rate =
407 drv_config->ddr3_speed_bin;
408 ptiming_config->dram_info[i].cs_cnt = sdram_params->ch[i].rank;
409 for (j = 0; j < sdram_params->ch[i].rank; j++) {
410 ptiming_config->dram_info[i].per_die_capability[j] =
411 get_cs_die_capability(sdram_params, i, j);
412 }
413 }
414 ptiming_config->dram_type = sdram_params->dramtype;
415 ptiming_config->ch_cnt = sdram_params->num_channels;
416 switch (sdram_params->dramtype) {
417 case DDR3:
418 ptiming_config->bl = ddr3_default_config.bl;
419 ptiming_config->ap = ddr3_default_config.ap;
420 break;
421 case LPDDR3:
422 ptiming_config->bl = lpddr3_default_config.bl;
423 ptiming_config->ap = lpddr3_default_config.ap;
424 break;
425 case LPDDR4:
426 ptiming_config->bl = lpddr4_default_config.bl;
427 ptiming_config->ap = lpddr4_default_config.ap;
428 ptiming_config->rdbi = 0;
429 ptiming_config->wdbi = 0;
430 break;
431 }
432 ptiming_config->dramds = drv_config->dram_side_drv;
433 ptiming_config->dramodt = drv_config->dram_side_dq_odt;
434 ptiming_config->caodt = drv_config->dram_side_ca_odt;
435}
436
437struct lat_adj_pair {
438 uint32_t cl;
439 uint32_t rdlat_adj;
440 uint32_t cwl;
441 uint32_t wrlat_adj;
442};
443
444const struct lat_adj_pair ddr3_lat_adj[] = {
445 {6, 5, 5, 4},
446 {8, 7, 6, 5},
447 {10, 9, 7, 6},
448 {11, 9, 8, 7},
449 {13, 0xb, 9, 8},
450 {14, 0xb, 0xa, 9}
451};
452
453const struct lat_adj_pair lpddr3_lat_adj[] = {
454 {3, 2, 1, 0},
455 {6, 5, 3, 2},
456 {8, 7, 4, 3},
457 {9, 8, 5, 4},
458 {10, 9, 6, 5},
459 {11, 9, 6, 5},
460 {12, 0xa, 6, 5},
461 {14, 0xc, 8, 7},
462 {16, 0xd, 8, 7}
463};
464
465const struct lat_adj_pair lpddr4_lat_adj[] = {
466 {6, 5, 4, 2},
467 {10, 9, 6, 4},
468 {14, 0xc, 8, 6},
469 {20, 0x11, 0xa, 8},
470 {24, 0x15, 0xc, 0xa},
471 {28, 0x18, 0xe, 0xc},
472 {32, 0x1b, 0x10, 0xe},
473 {36, 0x1e, 0x12, 0x10}
474};
475
476static uint32_t get_rdlat_adj(uint32_t dram_type, uint32_t cl)
477{
478 const struct lat_adj_pair *p;
479 uint32_t cnt;
480 uint32_t i;
481
482 if (dram_type == DDR3) {
483 p = ddr3_lat_adj;
484 cnt = ARRAY_SIZE(ddr3_lat_adj);
485 } else if (dram_type == LPDDR3) {
486 p = lpddr3_lat_adj;
487 cnt = ARRAY_SIZE(lpddr3_lat_adj);
488 } else {
489 p = lpddr4_lat_adj;
490 cnt = ARRAY_SIZE(lpddr4_lat_adj);
491 }
492
493 for (i = 0; i < cnt; i++) {
494 if (cl == p[i].cl)
495 return p[i].rdlat_adj;
496 }
497 /* fail */
498 return 0xff;
499}
500
501static uint32_t get_wrlat_adj(uint32_t dram_type, uint32_t cwl)
502{
503 const struct lat_adj_pair *p;
504 uint32_t cnt;
505 uint32_t i;
506
507 if (dram_type == DDR3) {
508 p = ddr3_lat_adj;
509 cnt = ARRAY_SIZE(ddr3_lat_adj);
510 } else if (dram_type == LPDDR3) {
511 p = lpddr3_lat_adj;
512 cnt = ARRAY_SIZE(lpddr3_lat_adj);
513 } else {
514 p = lpddr4_lat_adj;
515 cnt = ARRAY_SIZE(lpddr4_lat_adj);
516 }
517
518 for (i = 0; i < cnt; i++) {
519 if (cwl == p[i].cwl)
520 return p[i].wrlat_adj;
521 }
522 /* fail */
523 return 0xff;
524}
525
526#define PI_REGS_DIMM_SUPPORT (0)
527#define PI_ADD_LATENCY (0)
528#define PI_DOUBLEFREEK (1)
529
530#define PI_PAD_DELAY_PS_VALUE (1000)
531#define PI_IE_ENABLE_VALUE (3000)
532#define PI_TSEL_ENABLE_VALUE (700)
533
534static uint32_t get_pi_rdlat_adj(struct dram_timing_t *pdram_timing)
535{
536 /*[DLLSUBTYPE2] == "STD_DENALI_HS" */
537 uint32_t rdlat, delay_adder, ie_enable, hs_offset, tsel_adder,
538 extra_adder, tsel_enable;
539
540 ie_enable = PI_IE_ENABLE_VALUE;
541 tsel_enable = PI_TSEL_ENABLE_VALUE;
542
543 rdlat = pdram_timing->cl + PI_ADD_LATENCY;
544 delay_adder = ie_enable / (1000000 / pdram_timing->mhz);
545 if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0)
546 delay_adder++;
547 hs_offset = 0;
548 tsel_adder = 0;
549 extra_adder = 0;
550 /* rdlat = rdlat - (PREAMBLE_SUPPORT & 0x1); */
551 tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz);
552 if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0)
553 tsel_adder++;
554 delay_adder = delay_adder - 1;
555 if (tsel_adder > delay_adder)
556 extra_adder = tsel_adder - delay_adder;
557 else
558 extra_adder = 0;
559 if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK)
560 hs_offset = 2;
561 else
562 hs_offset = 1;
563
564 if (delay_adder > (rdlat - 1 - hs_offset)) {
565 rdlat = rdlat - tsel_adder;
566 } else {
567 if ((rdlat - delay_adder) < 2)
568 rdlat = 2;
569 else
570 rdlat = rdlat - delay_adder - extra_adder;
571 }
572
573 return rdlat;
574}
575
576static uint32_t get_pi_wrlat(struct dram_timing_t *pdram_timing,
577 struct timing_related_config *timing_config)
578{
579 uint32_t tmp;
580
581 if (timing_config->dram_type == LPDDR3) {
582 tmp = pdram_timing->cl;
583 if (tmp >= 14)
584 tmp = 8;
585 else if (tmp >= 10)
586 tmp = 6;
587 else if (tmp == 9)
588 tmp = 5;
589 else if (tmp == 8)
590 tmp = 4;
591 else if (tmp == 6)
592 tmp = 3;
593 else
594 tmp = 1;
595 } else {
596 tmp = 1;
597 }
598
599 return tmp;
600}
601
602static uint32_t get_pi_wrlat_adj(struct dram_timing_t *pdram_timing,
603 struct timing_related_config *timing_config)
604{
605 return get_pi_wrlat(pdram_timing, timing_config) + PI_ADD_LATENCY - 1;
606}
607
608static uint32_t get_pi_tdfi_phy_rdlat(struct dram_timing_t *pdram_timing,
609 struct timing_related_config *timing_config)
610{
611 /* [DLLSUBTYPE2] == "STD_DENALI_HS" */
612 uint32_t cas_lat, delay_adder, ie_enable, hs_offset, ie_delay_adder;
613 uint32_t mem_delay_ps, round_trip_ps;
614 uint32_t phy_internal_delay, lpddr_adder, dfi_adder, rdlat_delay;
615
616 ie_enable = PI_IE_ENABLE_VALUE;
617
618 delay_adder = ie_enable / (1000000 / pdram_timing->mhz);
619 if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0)
620 delay_adder++;
621 delay_adder = delay_adder - 1;
622 if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK)
623 hs_offset = 2;
624 else
625 hs_offset = 1;
626
627 cas_lat = pdram_timing->cl + PI_ADD_LATENCY;
628
629 if (delay_adder > (cas_lat - 1 - hs_offset)) {
630 ie_delay_adder = 0;
631 } else {
632 ie_delay_adder = ie_enable / (1000000 / pdram_timing->mhz);
633 if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0)
634 ie_delay_adder++;
635 }
636
637 if (timing_config->dram_type == DDR3) {
638 mem_delay_ps = 0;
639 } else if (timing_config->dram_type == LPDDR4) {
640 mem_delay_ps = 3600;
641 } else if (timing_config->dram_type == LPDDR3) {
642 mem_delay_ps = 5500;
643 } else {
644 printf("get_pi_tdfi_phy_rdlat:dramtype unsupport\n");
645 return 0;
646 }
647 round_trip_ps = 1100 + 500 + mem_delay_ps + 500 + 600;
648 delay_adder = round_trip_ps / (1000000 / pdram_timing->mhz);
649 if ((round_trip_ps % (1000000 / pdram_timing->mhz)) != 0)
650 delay_adder++;
651
652 phy_internal_delay = 5 + 2 + 4;
653 lpddr_adder = mem_delay_ps / (1000000 / pdram_timing->mhz);
654 if ((mem_delay_ps % (1000000 / pdram_timing->mhz)) != 0)
655 lpddr_adder++;
656 dfi_adder = 0;
657 phy_internal_delay = phy_internal_delay + 2;
658 rdlat_delay = delay_adder + phy_internal_delay +
659 ie_delay_adder + lpddr_adder + dfi_adder;
660
661 rdlat_delay = rdlat_delay + 2;
662 return rdlat_delay;
663}
664
665static uint32_t get_pi_todtoff_min(struct dram_timing_t *pdram_timing,
666 struct timing_related_config *timing_config)
667{
668 uint32_t tmp, todtoff_min_ps;
669
670 if (timing_config->dram_type == LPDDR3)
671 todtoff_min_ps = 2500;
672 else if (timing_config->dram_type == LPDDR4)
673 todtoff_min_ps = 1500;
674 else
675 todtoff_min_ps = 0;
676 /* todtoff_min */
677 tmp = todtoff_min_ps / (1000000 / pdram_timing->mhz);
678 if ((todtoff_min_ps % (1000000 / pdram_timing->mhz)) != 0)
679 tmp++;
680 return tmp;
681}
682
683static uint32_t get_pi_todtoff_max(struct dram_timing_t *pdram_timing,
684 struct timing_related_config *timing_config)
685{
686 uint32_t tmp, todtoff_max_ps;
687
688 if ((timing_config->dram_type == LPDDR4)
689 || (timing_config->dram_type == LPDDR3))
690 todtoff_max_ps = 3500;
691 else
692 todtoff_max_ps = 0;
693
694 /* todtoff_max */
695 tmp = todtoff_max_ps / (1000000 / pdram_timing->mhz);
696 if ((todtoff_max_ps % (1000000 / pdram_timing->mhz)) != 0)
697 tmp++;
698 return tmp;
699}
700
701static void gen_rk3399_ctl_params_f0(struct timing_related_config
702 *timing_config,
703 struct dram_timing_t *pdram_timing)
704{
705 uint32_t i;
706 uint32_t tmp, tmp1;
707
708 for (i = 0; i < timing_config->ch_cnt; i++) {
709 if (timing_config->dram_type == DDR3) {
710 tmp = ((700000 + 10) * timing_config->freq +
711 999) / 1000;
712 tmp += pdram_timing->txsnr + (pdram_timing->tmrd * 3) +
713 pdram_timing->tmod + pdram_timing->tzqinit;
Caesar Wang8bc16672016-10-27 01:12:47 +0800714 mmio_write_32(CTL_REG(i, 5), tmp);
Caesar Wanga8456902016-10-27 01:12:34 +0800715
Caesar Wang8bc16672016-10-27 01:12:47 +0800716 mmio_clrsetbits_32(CTL_REG(i, 22), 0xffff,
717 pdram_timing->tdllk);
Caesar Wanga8456902016-10-27 01:12:34 +0800718
Caesar Wang8bc16672016-10-27 01:12:47 +0800719 mmio_write_32(CTL_REG(i, 32),
720 (pdram_timing->tmod << 8) |
721 pdram_timing->tmrd);
Caesar Wanga8456902016-10-27 01:12:34 +0800722
Caesar Wang8bc16672016-10-27 01:12:47 +0800723 mmio_clrsetbits_32(CTL_REG(i, 59), 0xffff << 16,
724 (pdram_timing->txsr -
725 pdram_timing->trcd) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800726 } else if (timing_config->dram_type == LPDDR4) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800727 mmio_write_32(CTL_REG(i, 5), pdram_timing->tinit1 +
728 pdram_timing->tinit3);
729 mmio_write_32(CTL_REG(i, 32),
730 (pdram_timing->tmrd << 8) |
731 pdram_timing->tmrd);
732 mmio_clrsetbits_32(CTL_REG(i, 59), 0xffff << 16,
733 pdram_timing->txsr << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800734 } else {
Caesar Wang8bc16672016-10-27 01:12:47 +0800735 mmio_write_32(CTL_REG(i, 5), pdram_timing->tinit1);
736 mmio_write_32(CTL_REG(i, 7), pdram_timing->tinit4);
737 mmio_write_32(CTL_REG(i, 32),
738 (pdram_timing->tmrd << 8) |
739 pdram_timing->tmrd);
740 mmio_clrsetbits_32(CTL_REG(i, 59), 0xffff << 16,
741 pdram_timing->txsr << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800742 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800743 mmio_write_32(CTL_REG(i, 6), pdram_timing->tinit3);
744 mmio_write_32(CTL_REG(i, 8), pdram_timing->tinit5);
745 mmio_clrsetbits_32(CTL_REG(i, 23), (0x7f << 16),
746 ((pdram_timing->cl * 2) << 16));
747 mmio_clrsetbits_32(CTL_REG(i, 23), (0x1f << 24),
748 (pdram_timing->cwl << 24));
749 mmio_clrsetbits_32(CTL_REG(i, 24), 0x3f, pdram_timing->al);
750 mmio_clrsetbits_32(CTL_REG(i, 26), 0xffff << 16,
751 (pdram_timing->trc << 24) |
752 (pdram_timing->trrd << 16));
753 mmio_write_32(CTL_REG(i, 27),
754 (pdram_timing->tfaw << 24) |
755 (pdram_timing->trppb << 16) |
756 (pdram_timing->twtr << 8) |
757 pdram_timing->tras_min);
Caesar Wanga8456902016-10-27 01:12:34 +0800758
Caesar Wang8bc16672016-10-27 01:12:47 +0800759 mmio_clrsetbits_32(CTL_REG(i, 31), 0xff << 24,
760 max(4, pdram_timing->trtp) << 24);
761 mmio_write_32(CTL_REG(i, 33), (pdram_timing->tcke << 24) |
762 pdram_timing->tras_max);
763 mmio_clrsetbits_32(CTL_REG(i, 34), 0xff,
764 max(1, pdram_timing->tckesr));
765 mmio_clrsetbits_32(CTL_REG(i, 39),
766 (0x3f << 16) | (0xff << 8),
767 (pdram_timing->twr << 16) |
768 (pdram_timing->trcd << 8));
769 mmio_clrsetbits_32(CTL_REG(i, 42), 0x1f << 16,
770 pdram_timing->tmrz << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800771 tmp = pdram_timing->tdal ? pdram_timing->tdal :
Caesar Wang8bc16672016-10-27 01:12:47 +0800772 (pdram_timing->twr + pdram_timing->trp);
773 mmio_clrsetbits_32(CTL_REG(i, 44), 0xff, tmp);
774 mmio_clrsetbits_32(CTL_REG(i, 45), 0xff, pdram_timing->trp);
775 mmio_write_32(CTL_REG(i, 48),
776 ((pdram_timing->trefi - 8) << 16) |
777 pdram_timing->trfc);
778 mmio_clrsetbits_32(CTL_REG(i, 52), 0xffff, pdram_timing->txp);
779 mmio_clrsetbits_32(CTL_REG(i, 53), 0xffff << 16,
780 pdram_timing->txpdll << 16);
781 mmio_clrsetbits_32(CTL_REG(i, 55), 0xf << 24,
782 pdram_timing->tcscke << 24);
783 mmio_clrsetbits_32(CTL_REG(i, 55), 0xff, pdram_timing->tmrri);
784 mmio_write_32(CTL_REG(i, 56),
785 (pdram_timing->tzqcke << 24) |
786 (pdram_timing->tmrwckel << 16) |
787 (pdram_timing->tckehcs << 8) |
788 pdram_timing->tckelcs);
789 mmio_clrsetbits_32(CTL_REG(i, 60), 0xffff, pdram_timing->txsnr);
790 mmio_clrsetbits_32(CTL_REG(i, 62), 0xffff << 16,
791 (pdram_timing->tckehcmd << 24) |
792 (pdram_timing->tckelcmd << 16));
793 mmio_write_32(CTL_REG(i, 63),
794 (pdram_timing->tckelpd << 24) |
795 (pdram_timing->tescke << 16) |
796 (pdram_timing->tsr << 8) |
797 pdram_timing->tckckel);
798 mmio_clrsetbits_32(CTL_REG(i, 64), 0xfff,
799 (pdram_timing->tcmdcke << 8) |
800 pdram_timing->tcsckeh);
801 mmio_clrsetbits_32(CTL_REG(i, 92), 0xffff << 8,
802 (pdram_timing->tcksrx << 16) |
803 (pdram_timing->tcksre << 8));
804 mmio_clrsetbits_32(CTL_REG(i, 108), 0x1 << 24,
805 (timing_config->dllbp << 24));
806 mmio_clrsetbits_32(CTL_REG(i, 122), 0x3ff << 16,
807 (pdram_timing->tvrcg_enable << 16));
808 mmio_write_32(CTL_REG(i, 123), (pdram_timing->tfc_long << 16) |
809 pdram_timing->tvrcg_disable);
810 mmio_write_32(CTL_REG(i, 124),
811 (pdram_timing->tvref_long << 16) |
812 (pdram_timing->tckfspx << 8) |
813 pdram_timing->tckfspe);
814 mmio_write_32(CTL_REG(i, 133), (pdram_timing->mr[1] << 16) |
815 pdram_timing->mr[0]);
816 mmio_clrsetbits_32(CTL_REG(i, 134), 0xffff,
817 pdram_timing->mr[2]);
818 mmio_clrsetbits_32(CTL_REG(i, 138), 0xffff,
819 pdram_timing->mr[3]);
820 mmio_clrsetbits_32(CTL_REG(i, 139), 0xff << 24,
821 pdram_timing->mr11 << 24);
822 mmio_write_32(CTL_REG(i, 147),
823 (pdram_timing->mr[1] << 16) |
824 pdram_timing->mr[0]);
825 mmio_clrsetbits_32(CTL_REG(i, 148), 0xffff,
826 pdram_timing->mr[2]);
827 mmio_clrsetbits_32(CTL_REG(i, 152), 0xffff,
828 pdram_timing->mr[3]);
829 mmio_clrsetbits_32(CTL_REG(i, 153), 0xff << 24,
830 pdram_timing->mr11 << 24);
Caesar Wanga8456902016-10-27 01:12:34 +0800831 if (timing_config->dram_type == LPDDR4) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800832 mmio_clrsetbits_32(CTL_REG(i, 140), 0xffff << 16,
833 pdram_timing->mr12 << 16);
834 mmio_clrsetbits_32(CTL_REG(i, 142), 0xffff << 16,
835 pdram_timing->mr14 << 16);
836 mmio_clrsetbits_32(CTL_REG(i, 145), 0xffff << 16,
837 pdram_timing->mr22 << 16);
838 mmio_clrsetbits_32(CTL_REG(i, 154), 0xffff << 16,
839 pdram_timing->mr12 << 16);
840 mmio_clrsetbits_32(CTL_REG(i, 156), 0xffff << 16,
841 pdram_timing->mr14 << 16);
842 mmio_clrsetbits_32(CTL_REG(i, 159), 0xffff << 16,
843 pdram_timing->mr22 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800844 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800845 mmio_clrsetbits_32(CTL_REG(i, 179), 0xfff << 8,
846 pdram_timing->tzqinit << 8);
847 mmio_write_32(CTL_REG(i, 180), (pdram_timing->tzqcs << 16) |
848 (pdram_timing->tzqinit / 2));
849 mmio_write_32(CTL_REG(i, 181), (pdram_timing->tzqlat << 16) |
850 pdram_timing->tzqcal);
851 mmio_clrsetbits_32(CTL_REG(i, 212), 0xff << 8,
852 pdram_timing->todton << 8);
Caesar Wanga8456902016-10-27 01:12:34 +0800853
854 if (timing_config->odt) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800855 mmio_setbits_32(CTL_REG(i, 213), 1 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800856 if (timing_config->freq < 400)
857 tmp = 4 << 24;
858 else
859 tmp = 8 << 24;
860 } else {
Caesar Wang8bc16672016-10-27 01:12:47 +0800861 mmio_clrbits_32(CTL_REG(i, 213), 1 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800862 tmp = 2 << 24;
863 }
864
Caesar Wang8bc16672016-10-27 01:12:47 +0800865 mmio_clrsetbits_32(CTL_REG(i, 216), 0x1f << 24, tmp);
866 mmio_clrsetbits_32(CTL_REG(i, 221), (0x3 << 16) | (0xf << 8),
867 (pdram_timing->tdqsck << 16) |
868 (pdram_timing->tdqsck_max << 8));
Caesar Wanga8456902016-10-27 01:12:34 +0800869 tmp =
870 (get_wrlat_adj(timing_config->dram_type, pdram_timing->cwl)
871 << 8) | get_rdlat_adj(timing_config->dram_type,
872 pdram_timing->cl);
Caesar Wang8bc16672016-10-27 01:12:47 +0800873 mmio_clrsetbits_32(CTL_REG(i, 284), 0xffff, tmp);
874 mmio_clrsetbits_32(CTL_REG(i, 82), 0xffff << 16,
875 (4 * pdram_timing->trefi) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800876
Caesar Wang8bc16672016-10-27 01:12:47 +0800877 mmio_clrsetbits_32(CTL_REG(i, 83), 0xffff,
878 (2 * pdram_timing->trefi) & 0xffff);
Caesar Wanga8456902016-10-27 01:12:34 +0800879
880 if ((timing_config->dram_type == LPDDR3) ||
881 (timing_config->dram_type == LPDDR4)) {
882 tmp = get_pi_wrlat(pdram_timing, timing_config);
883 tmp1 = get_pi_todtoff_max(pdram_timing, timing_config);
884 tmp = (tmp > tmp1) ? (tmp - tmp1) : 0;
885 } else {
886 tmp = 0;
887 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800888 mmio_clrsetbits_32(CTL_REG(i, 214), 0x3f << 16,
889 (tmp & 0x3f) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800890
891 if ((timing_config->dram_type == LPDDR3) ||
892 (timing_config->dram_type == LPDDR4)) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800893 /* min_rl_preamble = cl+TDQSCK_MIN -1 */
Caesar Wanga8456902016-10-27 01:12:34 +0800894 tmp = pdram_timing->cl +
895 get_pi_todtoff_min(pdram_timing, timing_config) - 1;
896 /* todtoff_max */
897 tmp1 = get_pi_todtoff_max(pdram_timing, timing_config);
898 tmp = (tmp > tmp1) ? (tmp - tmp1) : 0;
899 } else {
900 tmp = pdram_timing->cl - pdram_timing->cwl;
901 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800902 mmio_clrsetbits_32(CTL_REG(i, 215), 0x3f << 8,
903 (tmp & 0x3f) << 8);
Caesar Wanga8456902016-10-27 01:12:34 +0800904
Caesar Wang8bc16672016-10-27 01:12:47 +0800905 mmio_clrsetbits_32(CTL_REG(i, 275), 0xff << 16,
906 (get_pi_tdfi_phy_rdlat(pdram_timing,
907 timing_config) &
908 0xff) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800909
Caesar Wang8bc16672016-10-27 01:12:47 +0800910 mmio_clrsetbits_32(CTL_REG(i, 277), 0xffff,
911 (2 * pdram_timing->trefi) & 0xffff);
Caesar Wanga8456902016-10-27 01:12:34 +0800912
Caesar Wang8bc16672016-10-27 01:12:47 +0800913 mmio_clrsetbits_32(CTL_REG(i, 282), 0xffff,
914 (2 * pdram_timing->trefi) & 0xffff);
Caesar Wanga8456902016-10-27 01:12:34 +0800915
Caesar Wang8bc16672016-10-27 01:12:47 +0800916 mmio_write_32(CTL_REG(i, 283), 20 * pdram_timing->trefi);
Caesar Wanga8456902016-10-27 01:12:34 +0800917
918 /* CTL_308 TDFI_CALVL_CAPTURE_F0:RW:16:10 */
919 tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1;
920 if ((20000 % (1000000 / pdram_timing->mhz)) != 0)
921 tmp1++;
922 tmp = (tmp1 >> 1) + (tmp1 % 2) + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +0800923 mmio_clrsetbits_32(CTL_REG(i, 308), 0x3ff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800924
925 /* CTL_308 TDFI_CALVL_CC_F0:RW:0:10 */
926 tmp = tmp + 18;
Caesar Wang8bc16672016-10-27 01:12:47 +0800927 mmio_clrsetbits_32(CTL_REG(i, 308), 0x3ff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +0800928
929 /* CTL_314 TDFI_WRCSLAT_F0:RW:8:8 */
930 tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config);
931 if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800932 if (tmp1 == 0)
933 tmp = 0;
934 else if (tmp1 < 5)
935 tmp = tmp1 - 1;
936 else
Caesar Wanga8456902016-10-27 01:12:34 +0800937 tmp = tmp1 - 5;
Caesar Wanga8456902016-10-27 01:12:34 +0800938 } else {
939 tmp = tmp1 - 2;
940 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800941 mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +0800942
943 /* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */
944 if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) &&
Caesar Wang8bc16672016-10-27 01:12:47 +0800945 (pdram_timing->cl >= 5))
Caesar Wanga8456902016-10-27 01:12:34 +0800946 tmp = pdram_timing->cl - 5;
947 else
948 tmp = pdram_timing->cl - 2;
Caesar Wang8bc16672016-10-27 01:12:47 +0800949 mmio_clrsetbits_32(CTL_REG(i, 314), 0xff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +0800950 }
951}
952
953static void gen_rk3399_ctl_params_f1(struct timing_related_config
954 *timing_config,
955 struct dram_timing_t *pdram_timing)
956{
957 uint32_t i;
958 uint32_t tmp, tmp1;
959
960 for (i = 0; i < timing_config->ch_cnt; i++) {
961 if (timing_config->dram_type == DDR3) {
962 tmp =
Caesar Wang8bc16672016-10-27 01:12:47 +0800963 ((700000 + 10) * timing_config->freq + 999) / 1000;
964 tmp += pdram_timing->txsnr + (pdram_timing->tmrd * 3) +
965 pdram_timing->tmod + pdram_timing->tzqinit;
966 mmio_write_32(CTL_REG(i, 9), tmp);
967 mmio_clrsetbits_32(CTL_REG(i, 22), 0xffff << 16,
968 pdram_timing->tdllk << 16);
969 mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00,
970 (pdram_timing->tmod << 24) |
971 (pdram_timing->tmrd << 16) |
972 (pdram_timing->trtp << 8));
973 mmio_clrsetbits_32(CTL_REG(i, 60), 0xffff << 16,
974 (pdram_timing->txsr -
975 pdram_timing->trcd) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800976 } else if (timing_config->dram_type == LPDDR4) {
Caesar Wang8bc16672016-10-27 01:12:47 +0800977 mmio_write_32(CTL_REG(i, 9), pdram_timing->tinit1 +
978 pdram_timing->tinit3);
979 mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00,
980 (pdram_timing->tmrd << 24) |
981 (pdram_timing->tmrd << 16) |
982 (pdram_timing->trtp << 8));
983 mmio_clrsetbits_32(CTL_REG(i, 60), 0xffff << 16,
984 pdram_timing->txsr << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800985 } else {
Caesar Wang8bc16672016-10-27 01:12:47 +0800986 mmio_write_32(CTL_REG(i, 9), pdram_timing->tinit1);
987 mmio_write_32(CTL_REG(i, 11), pdram_timing->tinit4);
988 mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00,
989 (pdram_timing->tmrd << 24) |
990 (pdram_timing->tmrd << 16) |
991 (pdram_timing->trtp << 8));
992 mmio_clrsetbits_32(CTL_REG(i, 60), 0xffff << 16,
993 pdram_timing->txsr << 16);
Caesar Wanga8456902016-10-27 01:12:34 +0800994 }
Caesar Wang8bc16672016-10-27 01:12:47 +0800995 mmio_write_32(CTL_REG(i, 10), pdram_timing->tinit3);
996 mmio_write_32(CTL_REG(i, 12), pdram_timing->tinit5);
997 mmio_clrsetbits_32(CTL_REG(i, 24), (0x7f << 8),
998 ((pdram_timing->cl * 2) << 8));
999 mmio_clrsetbits_32(CTL_REG(i, 24), (0x1f << 16),
1000 (pdram_timing->cwl << 16));
1001 mmio_clrsetbits_32(CTL_REG(i, 24), 0x3f << 24,
1002 pdram_timing->al << 24);
1003 mmio_clrsetbits_32(CTL_REG(i, 28), 0xffffff00,
1004 (pdram_timing->tras_min << 24) |
1005 (pdram_timing->trc << 16) |
1006 (pdram_timing->trrd << 8));
1007 mmio_clrsetbits_32(CTL_REG(i, 29), 0xffffff,
1008 (pdram_timing->tfaw << 16) |
1009 (pdram_timing->trppb << 8) |
1010 pdram_timing->twtr);
1011 mmio_write_32(CTL_REG(i, 35), (pdram_timing->tcke << 24) |
1012 pdram_timing->tras_max);
1013 mmio_clrsetbits_32(CTL_REG(i, 36), 0xff,
1014 max(1, pdram_timing->tckesr));
1015 mmio_clrsetbits_32(CTL_REG(i, 39), (0xff << 24),
1016 (pdram_timing->trcd << 24));
1017 mmio_clrsetbits_32(CTL_REG(i, 40), 0x3f, pdram_timing->twr);
1018 mmio_clrsetbits_32(CTL_REG(i, 42), 0x1f << 24,
1019 pdram_timing->tmrz << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001020 tmp = pdram_timing->tdal ? pdram_timing->tdal :
Caesar Wang8bc16672016-10-27 01:12:47 +08001021 (pdram_timing->twr + pdram_timing->trp);
1022 mmio_clrsetbits_32(CTL_REG(i, 44), 0xff << 8, tmp << 8);
1023 mmio_clrsetbits_32(CTL_REG(i, 45), 0xff << 8,
1024 pdram_timing->trp << 8);
1025 mmio_write_32(CTL_REG(i, 49),
1026 ((pdram_timing->trefi - 8) << 16) |
1027 pdram_timing->trfc);
1028 mmio_clrsetbits_32(CTL_REG(i, 52), 0xffff << 16,
1029 pdram_timing->txp << 16);
1030 mmio_clrsetbits_32(CTL_REG(i, 54), 0xffff,
1031 pdram_timing->txpdll);
1032 mmio_clrsetbits_32(CTL_REG(i, 55), 0xff << 8,
1033 pdram_timing->tmrri << 8);
1034 mmio_write_32(CTL_REG(i, 57), (pdram_timing->tmrwckel << 24) |
1035 (pdram_timing->tckehcs << 16) |
1036 (pdram_timing->tckelcs << 8) |
1037 pdram_timing->tcscke);
1038 mmio_clrsetbits_32(CTL_REG(i, 58), 0xf, pdram_timing->tzqcke);
1039 mmio_clrsetbits_32(CTL_REG(i, 61), 0xffff, pdram_timing->txsnr);
1040 mmio_clrsetbits_32(CTL_REG(i, 64), 0xffff << 16,
1041 (pdram_timing->tckehcmd << 24) |
1042 (pdram_timing->tckelcmd << 16));
1043 mmio_write_32(CTL_REG(i, 65), (pdram_timing->tckelpd << 24) |
1044 (pdram_timing->tescke << 16) |
1045 (pdram_timing->tsr << 8) |
1046 pdram_timing->tckckel);
1047 mmio_clrsetbits_32(CTL_REG(i, 66), 0xfff,
1048 (pdram_timing->tcmdcke << 8) |
1049 pdram_timing->tcsckeh);
1050 mmio_clrsetbits_32(CTL_REG(i, 92), (0xff << 24),
1051 (pdram_timing->tcksre << 24));
1052 mmio_clrsetbits_32(CTL_REG(i, 93), 0xff,
1053 pdram_timing->tcksrx);
1054 mmio_clrsetbits_32(CTL_REG(i, 108), (0x1 << 25),
1055 (timing_config->dllbp << 25));
1056 mmio_write_32(CTL_REG(i, 125),
1057 (pdram_timing->tvrcg_disable << 16) |
1058 pdram_timing->tvrcg_enable);
1059 mmio_write_32(CTL_REG(i, 126), (pdram_timing->tckfspx << 24) |
1060 (pdram_timing->tckfspe << 16) |
1061 pdram_timing->tfc_long);
1062 mmio_clrsetbits_32(CTL_REG(i, 127), 0xffff,
1063 pdram_timing->tvref_long);
1064 mmio_clrsetbits_32(CTL_REG(i, 134), 0xffff << 16,
1065 pdram_timing->mr[0] << 16);
1066 mmio_write_32(CTL_REG(i, 135), (pdram_timing->mr[2] << 16) |
1067 pdram_timing->mr[1]);
1068 mmio_clrsetbits_32(CTL_REG(i, 138), 0xffff << 16,
1069 pdram_timing->mr[3] << 16);
1070 mmio_clrsetbits_32(CTL_REG(i, 140), 0xff, pdram_timing->mr11);
1071 mmio_clrsetbits_32(CTL_REG(i, 148), 0xffff << 16,
1072 pdram_timing->mr[0] << 16);
1073 mmio_write_32(CTL_REG(i, 149), (pdram_timing->mr[2] << 16) |
1074 pdram_timing->mr[1]);
1075 mmio_clrsetbits_32(CTL_REG(i, 152), 0xffff << 16,
1076 pdram_timing->mr[3] << 16);
1077 mmio_clrsetbits_32(CTL_REG(i, 154), 0xff, pdram_timing->mr11);
Caesar Wanga8456902016-10-27 01:12:34 +08001078 if (timing_config->dram_type == LPDDR4) {
Caesar Wang8bc16672016-10-27 01:12:47 +08001079 mmio_clrsetbits_32(CTL_REG(i, 141), 0xffff,
1080 pdram_timing->mr12);
1081 mmio_clrsetbits_32(CTL_REG(i, 143), 0xffff,
1082 pdram_timing->mr14);
1083 mmio_clrsetbits_32(CTL_REG(i, 146), 0xffff,
1084 pdram_timing->mr22);
1085 mmio_clrsetbits_32(CTL_REG(i, 155), 0xffff,
1086 pdram_timing->mr12);
1087 mmio_clrsetbits_32(CTL_REG(i, 157), 0xffff,
1088 pdram_timing->mr14);
1089 mmio_clrsetbits_32(CTL_REG(i, 160), 0xffff,
1090 pdram_timing->mr22);
Caesar Wanga8456902016-10-27 01:12:34 +08001091 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001092 mmio_write_32(CTL_REG(i, 182),
1093 ((pdram_timing->tzqinit / 2) << 16) |
1094 pdram_timing->tzqinit);
1095 mmio_write_32(CTL_REG(i, 183), (pdram_timing->tzqcal << 16) |
1096 pdram_timing->tzqcs);
1097 mmio_clrsetbits_32(CTL_REG(i, 184), 0x3f, pdram_timing->tzqlat);
1098 mmio_clrsetbits_32(CTL_REG(i, 188), 0xfff,
1099 pdram_timing->tzqreset);
1100 mmio_clrsetbits_32(CTL_REG(i, 212), 0xff << 16,
1101 pdram_timing->todton << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001102
1103 if (timing_config->odt) {
Caesar Wang8bc16672016-10-27 01:12:47 +08001104 mmio_setbits_32(CTL_REG(i, 213), (1 << 24));
Caesar Wanga8456902016-10-27 01:12:34 +08001105 if (timing_config->freq < 400)
1106 tmp = 4 << 24;
1107 else
1108 tmp = 8 << 24;
1109 } else {
Caesar Wang8bc16672016-10-27 01:12:47 +08001110 mmio_clrbits_32(CTL_REG(i, 213), (1 << 24));
Caesar Wanga8456902016-10-27 01:12:34 +08001111 tmp = 2 << 24;
1112 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001113 mmio_clrsetbits_32(CTL_REG(i, 217), 0x1f << 24, tmp);
1114 mmio_clrsetbits_32(CTL_REG(i, 221), 0xf << 24,
1115 (pdram_timing->tdqsck_max << 24));
1116 mmio_clrsetbits_32(CTL_REG(i, 222), 0x3, pdram_timing->tdqsck);
1117 mmio_clrsetbits_32(CTL_REG(i, 291), 0xffff,
1118 (get_wrlat_adj(timing_config->dram_type,
1119 pdram_timing->cwl) << 8) |
1120 get_rdlat_adj(timing_config->dram_type,
1121 pdram_timing->cl));
Caesar Wanga8456902016-10-27 01:12:34 +08001122
Caesar Wang8bc16672016-10-27 01:12:47 +08001123 mmio_clrsetbits_32(CTL_REG(i, 84), 0xffff,
1124 (4 * pdram_timing->trefi) & 0xffff);
Caesar Wanga8456902016-10-27 01:12:34 +08001125
Caesar Wang8bc16672016-10-27 01:12:47 +08001126 mmio_clrsetbits_32(CTL_REG(i, 84), 0xffff << 16,
1127 ((2 * pdram_timing->trefi) & 0xffff) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001128
1129 if ((timing_config->dram_type == LPDDR3) ||
1130 (timing_config->dram_type == LPDDR4)) {
1131 tmp = get_pi_wrlat(pdram_timing, timing_config);
1132 tmp1 = get_pi_todtoff_max(pdram_timing, timing_config);
1133 tmp = (tmp > tmp1) ? (tmp - tmp1) : 0;
1134 } else {
1135 tmp = 0;
1136 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001137 mmio_clrsetbits_32(CTL_REG(i, 214), 0x3f << 24,
1138 (tmp & 0x3f) << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001139
1140 if ((timing_config->dram_type == LPDDR3) ||
1141 (timing_config->dram_type == LPDDR4)) {
Caesar Wang8bc16672016-10-27 01:12:47 +08001142 /* min_rl_preamble = cl + TDQSCK_MIN - 1 */
Caesar Wanga8456902016-10-27 01:12:34 +08001143 tmp = pdram_timing->cl +
Caesar Wang8bc16672016-10-27 01:12:47 +08001144 get_pi_todtoff_min(pdram_timing, timing_config);
1145 tmp--;
Caesar Wanga8456902016-10-27 01:12:34 +08001146 /* todtoff_max */
1147 tmp1 = get_pi_todtoff_max(pdram_timing, timing_config);
1148 tmp = (tmp > tmp1) ? (tmp - tmp1) : 0;
1149 } else {
1150 tmp = pdram_timing->cl - pdram_timing->cwl;
1151 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001152 mmio_clrsetbits_32(CTL_REG(i, 215), 0x3f << 16,
1153 (tmp & 0x3f) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001154
Caesar Wang8bc16672016-10-27 01:12:47 +08001155 mmio_clrsetbits_32(CTL_REG(i, 275), 0xff << 24,
1156 (get_pi_tdfi_phy_rdlat(pdram_timing,
1157 timing_config) &
1158 0xff) << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001159
Caesar Wang8bc16672016-10-27 01:12:47 +08001160 mmio_clrsetbits_32(CTL_REG(i, 284), 0xffff << 16,
1161 ((2 * pdram_timing->trefi) & 0xffff) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001162
Caesar Wang8bc16672016-10-27 01:12:47 +08001163 mmio_clrsetbits_32(CTL_REG(i, 289), 0xffff,
1164 (2 * pdram_timing->trefi) & 0xffff);
Caesar Wanga8456902016-10-27 01:12:34 +08001165
Caesar Wang8bc16672016-10-27 01:12:47 +08001166 mmio_write_32(CTL_REG(i, 290), 20 * pdram_timing->trefi);
Caesar Wanga8456902016-10-27 01:12:34 +08001167
1168 /* CTL_309 TDFI_CALVL_CAPTURE_F1:RW:16:10 */
1169 tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1;
1170 if ((20000 % (1000000 / pdram_timing->mhz)) != 0)
1171 tmp1++;
1172 tmp = (tmp1 >> 1) + (tmp1 % 2) + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001173 mmio_clrsetbits_32(CTL_REG(i, 309), 0x3ff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001174
1175 /* CTL_309 TDFI_CALVL_CC_F1:RW:0:10 */
1176 tmp = tmp + 18;
Caesar Wang8bc16672016-10-27 01:12:47 +08001177 mmio_clrsetbits_32(CTL_REG(i, 309), 0x3ff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001178
1179 /* CTL_314 TDFI_WRCSLAT_F1:RW:24:8 */
1180 tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config);
1181 if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) {
Caesar Wang8bc16672016-10-27 01:12:47 +08001182 if (tmp1 == 0)
1183 tmp = 0;
1184 else if (tmp1 < 5)
1185 tmp = tmp1 - 1;
1186 else
Caesar Wanga8456902016-10-27 01:12:34 +08001187 tmp = tmp1 - 5;
Caesar Wanga8456902016-10-27 01:12:34 +08001188 } else {
1189 tmp = tmp1 - 2;
1190 }
1191
Caesar Wang8bc16672016-10-27 01:12:47 +08001192 mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001193
1194 /* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */
1195 if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) &&
Caesar Wang8bc16672016-10-27 01:12:47 +08001196 (pdram_timing->cl >= 5))
Caesar Wanga8456902016-10-27 01:12:34 +08001197 tmp = pdram_timing->cl - 5;
1198 else
1199 tmp = pdram_timing->cl - 2;
Caesar Wang8bc16672016-10-27 01:12:47 +08001200 mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001201 }
1202}
1203
1204static void gen_rk3399_ctl_params(struct timing_related_config *timing_config,
1205 struct dram_timing_t *pdram_timing,
1206 uint32_t fn)
1207{
1208 if (fn == 0)
1209 gen_rk3399_ctl_params_f0(timing_config, pdram_timing);
1210 else
1211 gen_rk3399_ctl_params_f1(timing_config, pdram_timing);
1212
1213#if CTL_TRAINING
1214 uint32_t i, tmp0, tmp1;
1215
1216 tmp0 = tmp1 = 0;
1217#if EN_READ_GATE_TRAINING
1218 tmp1 = 1;
1219#endif
1220
1221#if EN_CA_TRAINING
1222 tmp0 |= (1 << 8);
1223#endif
1224
1225#if EN_WRITE_LEVELING
1226 tmp0 |= (1 << 16);
1227#endif
1228
1229#if EN_READ_LEVELING
1230 tmp0 |= (1 << 24);
1231#endif
1232 for (i = 0; i < timing_config->ch_cnt; i++) {
1233 if (tmp0 | tmp1)
Caesar Wang8bc16672016-10-27 01:12:47 +08001234 mmio_setbits_32(CTL_REG(i, 305), 1 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001235 if (tmp0)
Caesar Wang8bc16672016-10-27 01:12:47 +08001236 mmio_setbits_32(CTL_REG(i, 70), tmp0);
Caesar Wanga8456902016-10-27 01:12:34 +08001237 if (tmp1)
Caesar Wang8bc16672016-10-27 01:12:47 +08001238 mmio_setbits_32(CTL_REG(i, 71), tmp1);
Caesar Wanga8456902016-10-27 01:12:34 +08001239 }
1240#endif
1241}
1242
1243static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config,
1244 struct dram_timing_t *pdram_timing)
1245{
1246 uint32_t tmp, tmp1, tmp2;
1247 uint32_t i;
1248
1249 for (i = 0; i < timing_config->ch_cnt; i++) {
1250 /* PI_02 PI_TDFI_PHYMSTR_MAX_F0:RW:0:32 */
1251 tmp = 4 * pdram_timing->trefi;
Caesar Wang8bc16672016-10-27 01:12:47 +08001252 mmio_write_32(PI_REG(i, 2), tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001253 /* PI_03 PI_TDFI_PHYMSTR_RESP_F0:RW:0:16 */
1254 tmp = 2 * pdram_timing->trefi;
Caesar Wang8bc16672016-10-27 01:12:47 +08001255 mmio_clrsetbits_32(PI_REG(i, 3), 0xffff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001256 /* PI_07 PI_TDFI_PHYUPD_RESP_F0:RW:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001257 mmio_clrsetbits_32(PI_REG(i, 7), 0xffff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001258
1259 /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F0:RW:0:8 */
1260 if (timing_config->dram_type == LPDDR4)
1261 tmp = 2;
1262 else
1263 tmp = 0;
1264 tmp = (pdram_timing->bl / 2) + 4 +
Caesar Wang8bc16672016-10-27 01:12:47 +08001265 (get_pi_rdlat_adj(pdram_timing) - 2) + tmp +
1266 get_pi_tdfi_phy_rdlat(pdram_timing, timing_config);
1267 mmio_clrsetbits_32(PI_REG(i, 42), 0xff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001268 /* PI_43 PI_WRLAT_F0:RW:0:5 */
1269 if (timing_config->dram_type == LPDDR3) {
1270 tmp = get_pi_wrlat(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001271 mmio_clrsetbits_32(PI_REG(i, 43), 0x1f, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001272 }
1273 /* PI_43 PI_ADDITIVE_LAT_F0:RW:8:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001274 mmio_clrsetbits_32(PI_REG(i, 43), 0x3f << 8,
1275 PI_ADD_LATENCY << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001276
1277 /* PI_43 PI_CASLAT_LIN_F0:RW:16:7 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001278 mmio_clrsetbits_32(PI_REG(i, 43), 0x7f << 16,
1279 (pdram_timing->cl * 2) << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001280 /* PI_46 PI_TREF_F0:RW:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001281 mmio_clrsetbits_32(PI_REG(i, 46), 0xffff << 16,
1282 pdram_timing->trefi << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001283 /* PI_46 PI_TRFC_F0:RW:0:10 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001284 mmio_clrsetbits_32(PI_REG(i, 46), 0x3ff, pdram_timing->trfc);
Caesar Wanga8456902016-10-27 01:12:34 +08001285 /* PI_66 PI_TODTL_2CMD_F0:RW:24:8 */
1286 if (timing_config->dram_type == LPDDR3) {
1287 tmp = get_pi_todtoff_max(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001288 mmio_clrsetbits_32(PI_REG(i, 66), 0xff << 24,
1289 tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001290 }
1291 /* PI_72 PI_WR_TO_ODTH_F0:RW:16:6 */
1292 if ((timing_config->dram_type == LPDDR3) ||
1293 (timing_config->dram_type == LPDDR4)) {
1294 tmp1 = get_pi_wrlat(pdram_timing, timing_config);
1295 tmp2 = get_pi_todtoff_max(pdram_timing, timing_config);
1296 if (tmp1 > tmp2)
1297 tmp = tmp1 - tmp2;
1298 else
1299 tmp = 0;
1300 } else if (timing_config->dram_type == DDR3) {
1301 tmp = 0;
1302 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001303 mmio_clrsetbits_32(PI_REG(i, 72), 0x3f << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001304 /* PI_73 PI_RD_TO_ODTH_F0:RW:8:6 */
1305 if ((timing_config->dram_type == LPDDR3) ||
1306 (timing_config->dram_type == LPDDR4)) {
Caesar Wang8bc16672016-10-27 01:12:47 +08001307 /* min_rl_preamble = cl + TDQSCK_MIN - 1 */
1308 tmp1 = pdram_timing->cl;
1309 tmp1 += get_pi_todtoff_min(pdram_timing, timing_config);
1310 tmp1--;
Caesar Wanga8456902016-10-27 01:12:34 +08001311 /* todtoff_max */
1312 tmp2 = get_pi_todtoff_max(pdram_timing, timing_config);
1313 if (tmp1 > tmp2)
1314 tmp = tmp1 - tmp2;
1315 else
1316 tmp = 0;
1317 } else if (timing_config->dram_type == DDR3) {
1318 tmp = pdram_timing->cl - pdram_timing->cwl;
1319 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001320 mmio_clrsetbits_32(PI_REG(i, 73), 0x3f << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001321 /* PI_89 PI_RDLAT_ADJ_F0:RW:16:8 */
1322 tmp = get_pi_rdlat_adj(pdram_timing);
Caesar Wang8bc16672016-10-27 01:12:47 +08001323 mmio_clrsetbits_32(PI_REG(i, 89), 0xff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001324 /* PI_90 PI_WRLAT_ADJ_F0:RW:16:8 */
1325 tmp = get_pi_wrlat_adj(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001326 mmio_clrsetbits_32(PI_REG(i, 90), 0xff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001327 /* PI_91 PI_TDFI_WRCSLAT_F0:RW:16:8 */
1328 tmp1 = tmp;
Caesar Wang8bc16672016-10-27 01:12:47 +08001329 if (tmp1 == 0)
1330 tmp = 0;
1331 else if (tmp1 < 5)
1332 tmp = tmp1 - 1;
1333 else
Caesar Wanga8456902016-10-27 01:12:34 +08001334 tmp = tmp1 - 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001335 mmio_clrsetbits_32(PI_REG(i, 91), 0xff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001336 /* PI_95 PI_TDFI_CALVL_CAPTURE_F0:RW:16:10 */
1337 tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1;
1338 if ((20000 % (1000000 / pdram_timing->mhz)) != 0)
1339 tmp1++;
1340 tmp = (tmp1 >> 1) + (tmp1 % 2) + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001341 mmio_clrsetbits_32(PI_REG(i, 95), 0x3ff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001342 /* PI_95 PI_TDFI_CALVL_CC_F0:RW:0:10 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001343 mmio_clrsetbits_32(PI_REG(i, 95), 0x3ff, tmp + 18);
Caesar Wanga8456902016-10-27 01:12:34 +08001344 /* PI_102 PI_TMRZ_F0:RW:8:5 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001345 mmio_clrsetbits_32(PI_REG(i, 102), 0x1f << 8,
1346 pdram_timing->tmrz << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001347 /* PI_111 PI_TDFI_CALVL_STROBE_F0:RW:8:4 */
1348 tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz);
1349 if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0)
1350 tmp1++;
1351 /* pi_tdfi_calvl_strobe=tds_train+5 */
1352 tmp = tmp1 + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001353 mmio_clrsetbits_32(PI_REG(i, 111), 0xf << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001354 /* PI_116 PI_TCKEHDQS_F0:RW:16:6 */
1355 tmp = 10000 / (1000000 / pdram_timing->mhz);
1356 if ((10000 % (1000000 / pdram_timing->mhz)) != 0)
1357 tmp++;
1358 if (pdram_timing->mhz <= 100)
1359 tmp = tmp + 1;
1360 else
1361 tmp = tmp + 8;
Caesar Wang8bc16672016-10-27 01:12:47 +08001362 mmio_clrsetbits_32(PI_REG(i, 116), 0x3f << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001363 /* PI_125 PI_MR1_DATA_F0_0:RW+:8:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001364 mmio_clrsetbits_32(PI_REG(i, 125), 0xffff << 8,
1365 pdram_timing->mr[1] << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001366 /* PI_133 PI_MR1_DATA_F0_1:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001367 mmio_clrsetbits_32(PI_REG(i, 133), 0xffff, pdram_timing->mr[1]);
Caesar Wanga8456902016-10-27 01:12:34 +08001368 /* PI_140 PI_MR1_DATA_F0_2:RW+:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001369 mmio_clrsetbits_32(PI_REG(i, 140), 0xffff << 16,
1370 pdram_timing->mr[1] << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001371 /* PI_148 PI_MR1_DATA_F0_3:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001372 mmio_clrsetbits_32(PI_REG(i, 148), 0xffff, pdram_timing->mr[1]);
Caesar Wanga8456902016-10-27 01:12:34 +08001373 /* PI_126 PI_MR2_DATA_F0_0:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001374 mmio_clrsetbits_32(PI_REG(i, 126), 0xffff, pdram_timing->mr[2]);
Caesar Wanga8456902016-10-27 01:12:34 +08001375 /* PI_133 PI_MR2_DATA_F0_1:RW+:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001376 mmio_clrsetbits_32(PI_REG(i, 133), 0xffff << 16,
1377 pdram_timing->mr[2] << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001378 /* PI_141 PI_MR2_DATA_F0_2:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001379 mmio_clrsetbits_32(PI_REG(i, 141), 0xffff, pdram_timing->mr[2]);
Caesar Wanga8456902016-10-27 01:12:34 +08001380 /* PI_148 PI_MR2_DATA_F0_3:RW+:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001381 mmio_clrsetbits_32(PI_REG(i, 148), 0xffff << 16,
1382 pdram_timing->mr[2] << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001383 /* PI_156 PI_TFC_F0:RW:0:10 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001384 mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff, pdram_timing->trfc);
Caesar Wanga8456902016-10-27 01:12:34 +08001385 /* PI_158 PI_TWR_F0:RW:24:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001386 mmio_clrsetbits_32(PI_REG(i, 158), 0x3f << 24,
1387 pdram_timing->twr << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001388 /* PI_158 PI_TWTR_F0:RW:16:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001389 mmio_clrsetbits_32(PI_REG(i, 158), 0x3f << 16,
1390 pdram_timing->twtr << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001391 /* PI_158 PI_TRCD_F0:RW:8:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001392 mmio_clrsetbits_32(PI_REG(i, 158), 0xff << 8,
1393 pdram_timing->trcd << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001394 /* PI_158 PI_TRP_F0:RW:0:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001395 mmio_clrsetbits_32(PI_REG(i, 158), 0xff, pdram_timing->trp);
Caesar Wanga8456902016-10-27 01:12:34 +08001396 /* PI_157 PI_TRTP_F0:RW:24:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001397 mmio_clrsetbits_32(PI_REG(i, 157), 0xff << 24,
1398 pdram_timing->trtp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001399 /* PI_159 PI_TRAS_MIN_F0:RW:24:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001400 mmio_clrsetbits_32(PI_REG(i, 159), 0xff << 24,
1401 pdram_timing->tras_min << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001402 /* PI_159 PI_TRAS_MAX_F0:RW:0:17 */
1403 tmp = pdram_timing->tras_max * 99 / 100;
Caesar Wang8bc16672016-10-27 01:12:47 +08001404 mmio_clrsetbits_32(PI_REG(i, 159), 0x1ffff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001405 /* PI_160 PI_TMRD_F0:RW:16:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001406 mmio_clrsetbits_32(PI_REG(i, 160), 0x3f << 16,
1407 pdram_timing->tmrd << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001408 /*PI_160 PI_TDQSCK_MAX_F0:RW:0:4 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001409 mmio_clrsetbits_32(PI_REG(i, 160), 0xf,
1410 pdram_timing->tdqsck_max);
Caesar Wanga8456902016-10-27 01:12:34 +08001411 /* PI_187 PI_TDFI_CTRLUPD_MAX_F0:RW:8:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001412 mmio_clrsetbits_32(PI_REG(i, 187), 0xffff << 8,
1413 (2 * pdram_timing->trefi) << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001414 /* PI_188 PI_TDFI_CTRLUPD_INTERVAL_F0:RW:0:32 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001415 mmio_clrsetbits_32(PI_REG(i, 188), 0xffffffff,
1416 20 * pdram_timing->trefi);
Caesar Wanga8456902016-10-27 01:12:34 +08001417 }
1418}
1419
1420static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config,
1421 struct dram_timing_t *pdram_timing)
1422{
1423 uint32_t tmp, tmp1, tmp2;
1424 uint32_t i;
1425
1426 for (i = 0; i < timing_config->ch_cnt; i++) {
1427 /* PI_04 PI_TDFI_PHYMSTR_MAX_F1:RW:0:32 */
1428 tmp = 4 * pdram_timing->trefi;
Caesar Wang8bc16672016-10-27 01:12:47 +08001429 mmio_write_32(PI_REG(i, 4), tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001430 /* PI_05 PI_TDFI_PHYMSTR_RESP_F1:RW:0:16 */
1431 tmp = 2 * pdram_timing->trefi;
Caesar Wang8bc16672016-10-27 01:12:47 +08001432 mmio_clrsetbits_32(PI_REG(i, 5), 0xffff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001433 /* PI_12 PI_TDFI_PHYUPD_RESP_F1:RW:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001434 mmio_clrsetbits_32(PI_REG(i, 12), 0xffff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001435
1436 /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F1:RW:8:8 */
1437 if (timing_config->dram_type == LPDDR4)
1438 tmp = 2;
1439 else
1440 tmp = 0;
1441 tmp = (pdram_timing->bl / 2) + 4 +
Caesar Wang8bc16672016-10-27 01:12:47 +08001442 (get_pi_rdlat_adj(pdram_timing) - 2) + tmp +
1443 get_pi_tdfi_phy_rdlat(pdram_timing, timing_config);
1444 mmio_clrsetbits_32(PI_REG(i, 42), 0xff << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001445 /* PI_43 PI_WRLAT_F1:RW:24:5 */
1446 if (timing_config->dram_type == LPDDR3) {
1447 tmp = get_pi_wrlat(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001448 mmio_clrsetbits_32(PI_REG(i, 43), 0x1f << 24,
1449 tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001450 }
1451 /* PI_44 PI_ADDITIVE_LAT_F1:RW:0:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001452 mmio_clrsetbits_32(PI_REG(i, 44), 0x3f, PI_ADD_LATENCY);
Caesar Wanga8456902016-10-27 01:12:34 +08001453 /* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001454 mmio_clrsetbits_32(PI_REG(i, 44), 0x7f << 8,
1455 pdram_timing->cl * 2);
Caesar Wanga8456902016-10-27 01:12:34 +08001456 /* PI_47 PI_TREF_F1:RW:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001457 mmio_clrsetbits_32(PI_REG(i, 47), 0xffff << 16,
1458 pdram_timing->trefi << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001459 /* PI_47 PI_TRFC_F1:RW:0:10 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001460 mmio_clrsetbits_32(PI_REG(i, 47), 0x3ff, pdram_timing->trfc);
Caesar Wanga8456902016-10-27 01:12:34 +08001461 /* PI_67 PI_TODTL_2CMD_F1:RW:8:8 */
1462 if (timing_config->dram_type == LPDDR3) {
1463 tmp = get_pi_todtoff_max(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001464 mmio_clrsetbits_32(PI_REG(i, 67), 0xff << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001465 }
1466 /* PI_72 PI_WR_TO_ODTH_F1:RW:24:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001467 if ((timing_config->dram_type == LPDDR3) ||
1468 (timing_config->dram_type == LPDDR4)) {
Caesar Wanga8456902016-10-27 01:12:34 +08001469 tmp1 = get_pi_wrlat(pdram_timing, timing_config);
1470 tmp2 = get_pi_todtoff_max(pdram_timing, timing_config);
1471 if (tmp1 > tmp2)
1472 tmp = tmp1 - tmp2;
1473 else
1474 tmp = 0;
1475 } else if (timing_config->dram_type == DDR3) {
1476 tmp = 0;
1477 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001478 mmio_clrsetbits_32(PI_REG(i, 72), 0x3f << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001479 /* PI_73 PI_RD_TO_ODTH_F1:RW:16:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001480 if ((timing_config->dram_type == LPDDR3) ||
1481 (timing_config->dram_type == LPDDR4)) {
1482 /* min_rl_preamble = cl + TDQSCK_MIN - 1 */
1483 tmp1 = pdram_timing->cl +
1484 get_pi_todtoff_min(pdram_timing, timing_config);
1485 tmp1--;
Caesar Wanga8456902016-10-27 01:12:34 +08001486 /* todtoff_max */
1487 tmp2 = get_pi_todtoff_max(pdram_timing, timing_config);
1488 if (tmp1 > tmp2)
1489 tmp = tmp1 - tmp2;
1490 else
1491 tmp = 0;
Caesar Wang8bc16672016-10-27 01:12:47 +08001492 } else if (timing_config->dram_type == DDR3)
Caesar Wanga8456902016-10-27 01:12:34 +08001493 tmp = pdram_timing->cl - pdram_timing->cwl;
Caesar Wang8bc16672016-10-27 01:12:47 +08001494
1495 mmio_clrsetbits_32(PI_REG(i, 73), 0x3f << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001496 /*P I_89 PI_RDLAT_ADJ_F1:RW:24:8 */
1497 tmp = get_pi_rdlat_adj(pdram_timing);
Caesar Wang8bc16672016-10-27 01:12:47 +08001498 mmio_clrsetbits_32(PI_REG(i, 89), 0xff << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001499 /* PI_90 PI_WRLAT_ADJ_F1:RW:24:8 */
1500 tmp = get_pi_wrlat_adj(pdram_timing, timing_config);
Caesar Wang8bc16672016-10-27 01:12:47 +08001501 mmio_clrsetbits_32(PI_REG(i, 90), 0xff << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001502 /* PI_91 PI_TDFI_WRCSLAT_F1:RW:24:8 */
1503 tmp1 = tmp;
Caesar Wang8bc16672016-10-27 01:12:47 +08001504 if (tmp1 == 0)
1505 tmp = 0;
1506 else if (tmp1 < 5)
1507 tmp = tmp1 - 1;
1508 else
Caesar Wanga8456902016-10-27 01:12:34 +08001509 tmp = tmp1 - 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001510 mmio_clrsetbits_32(PI_REG(i, 91), 0xff << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001511 /*PI_96 PI_TDFI_CALVL_CAPTURE_F1:RW:16:10 */
1512 /* tadr=20ns */
1513 tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1;
1514 if ((20000 % (1000000 / pdram_timing->mhz)) != 0)
1515 tmp1++;
1516 tmp = (tmp1 >> 1) + (tmp1 % 2) + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001517 mmio_clrsetbits_32(PI_REG(i, 96), 0x3ff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001518 /* PI_96 PI_TDFI_CALVL_CC_F1:RW:0:10 */
1519 tmp = tmp + 18;
Caesar Wang8bc16672016-10-27 01:12:47 +08001520 mmio_clrsetbits_32(PI_REG(i, 96), 0x3ff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001521 /*PI_103 PI_TMRZ_F1:RW:0:5 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001522 mmio_clrsetbits_32(PI_REG(i, 103), 0x1f, pdram_timing->tmrz);
Caesar Wanga8456902016-10-27 01:12:34 +08001523 /*PI_111 PI_TDFI_CALVL_STROBE_F1:RW:16:4 */
1524 /* tds_train=ceil(2/ns) */
1525 tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz);
1526 if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0)
1527 tmp1++;
1528 /* pi_tdfi_calvl_strobe=tds_train+5 */
1529 tmp = tmp1 + 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001530 mmio_clrsetbits_32(PI_REG(i, 111), 0xf << 16,
1531 tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001532 /* PI_116 PI_TCKEHDQS_F1:RW:24:6 */
1533 tmp = 10000 / (1000000 / pdram_timing->mhz);
1534 if ((10000 % (1000000 / pdram_timing->mhz)) != 0)
1535 tmp++;
1536 if (pdram_timing->mhz <= 100)
1537 tmp = tmp + 1;
1538 else
1539 tmp = tmp + 8;
Caesar Wang8bc16672016-10-27 01:12:47 +08001540 mmio_clrsetbits_32(PI_REG(i, 116), 0x3f << 24,
1541 tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001542 /* PI_128 PI_MR1_DATA_F1_0:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001543 mmio_clrsetbits_32(PI_REG(i, 128), 0xffff, pdram_timing->mr[1]);
Caesar Wanga8456902016-10-27 01:12:34 +08001544 /* PI_135 PI_MR1_DATA_F1_1:RW+:8:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001545 mmio_clrsetbits_32(PI_REG(i, 135), 0xffff << 8,
1546 pdram_timing->mr[1] << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001547 /* PI_143 PI_MR1_DATA_F1_2:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001548 mmio_clrsetbits_32(PI_REG(i, 143), 0xffff, pdram_timing->mr[1]);
Caesar Wanga8456902016-10-27 01:12:34 +08001549 /* PI_150 PI_MR1_DATA_F1_3:RW+:8:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001550 mmio_clrsetbits_32(PI_REG(i, 150), 0xffff << 8,
1551 pdram_timing->mr[1] << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001552 /* PI_128 PI_MR2_DATA_F1_0:RW+:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001553 mmio_clrsetbits_32(PI_REG(i, 128), 0xffff << 16,
1554 pdram_timing->mr[2] << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001555 /* PI_136 PI_MR2_DATA_F1_1:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001556 mmio_clrsetbits_32(PI_REG(i, 136), 0xffff, pdram_timing->mr[2]);
Caesar Wanga8456902016-10-27 01:12:34 +08001557 /* PI_143 PI_MR2_DATA_F1_2:RW+:16:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001558 mmio_clrsetbits_32(PI_REG(i, 143), 0xffff << 16,
1559 pdram_timing->mr[2] << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001560 /* PI_151 PI_MR2_DATA_F1_3:RW+:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001561 mmio_clrsetbits_32(PI_REG(i, 151), 0xffff, pdram_timing->mr[2]);
Caesar Wanga8456902016-10-27 01:12:34 +08001562 /* PI_156 PI_TFC_F1:RW:16:10 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001563 mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff << 16,
1564 pdram_timing->trfc << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001565 /* PI_162 PI_TWR_F1:RW:8:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001566 mmio_clrsetbits_32(PI_REG(i, 162), 0x3f << 8,
1567 pdram_timing->twr << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001568 /* PI_162 PI_TWTR_F1:RW:0:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001569 mmio_clrsetbits_32(PI_REG(i, 162), 0x3f, pdram_timing->twtr);
Caesar Wanga8456902016-10-27 01:12:34 +08001570 /* PI_161 PI_TRCD_F1:RW:24:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001571 mmio_clrsetbits_32(PI_REG(i, 161), 0xff << 24,
1572 pdram_timing->trcd << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001573 /* PI_161 PI_TRP_F1:RW:16:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001574 mmio_clrsetbits_32(PI_REG(i, 161), 0xff << 16,
1575 pdram_timing->trp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001576 /* PI_161 PI_TRTP_F1:RW:8:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001577 mmio_clrsetbits_32(PI_REG(i, 161), 0xff << 8,
1578 pdram_timing->trtp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001579 /* PI_163 PI_TRAS_MIN_F1:RW:24:8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001580 mmio_clrsetbits_32(PI_REG(i, 163), 0xff << 24,
1581 pdram_timing->tras_min << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001582 /* PI_163 PI_TRAS_MAX_F1:RW:0:17 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001583 mmio_clrsetbits_32(PI_REG(i, 163), 0x1ffff,
1584 pdram_timing->tras_max * 99 / 100);
Caesar Wanga8456902016-10-27 01:12:34 +08001585 /* PI_164 PI_TMRD_F1:RW:16:6 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001586 mmio_clrsetbits_32(PI_REG(i, 164), 0x3f << 16,
1587 pdram_timing->tmrd << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001588 /* PI_164 PI_TDQSCK_MAX_F1:RW:0:4 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001589 mmio_clrsetbits_32(PI_REG(i, 164), 0xf,
1590 pdram_timing->tdqsck_max);
Caesar Wanga8456902016-10-27 01:12:34 +08001591 /* PI_189 PI_TDFI_CTRLUPD_MAX_F1:RW:0:16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001592 mmio_clrsetbits_32(PI_REG(i, 189), 0xffff,
1593 2 * pdram_timing->trefi);
Caesar Wanga8456902016-10-27 01:12:34 +08001594 /* PI_190 PI_TDFI_CTRLUPD_INTERVAL_F1:RW:0:32 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001595 mmio_clrsetbits_32(PI_REG(i, 190), 0xffffffff,
1596 20 * pdram_timing->trefi);
Caesar Wanga8456902016-10-27 01:12:34 +08001597 }
1598}
1599
1600static void gen_rk3399_pi_params(struct timing_related_config *timing_config,
1601 struct dram_timing_t *pdram_timing,
1602 uint32_t fn)
1603{
1604 if (fn == 0)
1605 gen_rk3399_pi_params_f0(timing_config, pdram_timing);
1606 else
1607 gen_rk3399_pi_params_f1(timing_config, pdram_timing);
1608
1609#if PI_TRAINING
Caesar Wang8bc16672016-10-27 01:12:47 +08001610 uint32_t i;
Caesar Wanga8456902016-10-27 01:12:34 +08001611
Caesar Wang8bc16672016-10-27 01:12:47 +08001612 for (i = 0; i < timing_config->ch_cnt; i++) {
Caesar Wanga8456902016-10-27 01:12:34 +08001613#if EN_READ_GATE_TRAINING
Caesar Wang8bc16672016-10-27 01:12:47 +08001614 mmio_clrsetbits_32(PI_REG(i, 80), 3 << 24, 2 << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001615#endif
1616
1617#if EN_CA_TRAINING
Caesar Wang8bc16672016-10-27 01:12:47 +08001618 mmio_clrsetbits_32(PI_REG(i, 100), 3 << 8, 2 << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001619#endif
1620
1621#if EN_WRITE_LEVELING
Caesar Wang8bc16672016-10-27 01:12:47 +08001622 mmio_clrsetbits_32(PI_REG(i, 60), 3 << 8, 2 << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001623#endif
1624
1625#if EN_READ_LEVELING
Caesar Wang8bc16672016-10-27 01:12:47 +08001626 mmio_clrsetbits_32(PI_REG(i, 80), 3 << 16, 2 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001627#endif
1628
1629#if EN_WDQ_LEVELING
Caesar Wang8bc16672016-10-27 01:12:47 +08001630 mmio_clrsetbits_32(PI_REG(i, 124), 3 << 16, 2 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001631#endif
Caesar Wang8bc16672016-10-27 01:12:47 +08001632 }
Caesar Wanga8456902016-10-27 01:12:34 +08001633#endif
1634}
1635
1636static void gen_rk3399_set_odt(uint32_t odt_en)
1637{
1638 uint32_t drv_odt_val;
1639 uint32_t i;
1640
1641 for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) {
1642 drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 16;
Caesar Wang8bc16672016-10-27 01:12:47 +08001643 mmio_clrsetbits_32(PHY_REG(i, 5), 0x7 << 16, drv_odt_val);
1644 mmio_clrsetbits_32(PHY_REG(i, 133), 0x7 << 16, drv_odt_val);
1645 mmio_clrsetbits_32(PHY_REG(i, 261), 0x7 << 16, drv_odt_val);
1646 mmio_clrsetbits_32(PHY_REG(i, 389), 0x7 << 16, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001647 drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 24;
Caesar Wang8bc16672016-10-27 01:12:47 +08001648 mmio_clrsetbits_32(PHY_REG(i, 6), 0x7 << 24, drv_odt_val);
1649 mmio_clrsetbits_32(PHY_REG(i, 134), 0x7 << 24, drv_odt_val);
1650 mmio_clrsetbits_32(PHY_REG(i, 262), 0x7 << 24, drv_odt_val);
1651 mmio_clrsetbits_32(PHY_REG(i, 390), 0x7 << 24, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001652 }
1653}
1654
1655static void gen_rk3399_set_ds_odt(struct timing_related_config *timing_config,
1656 struct drv_odt_lp_config *drv_config)
1657{
1658 uint32_t i, drv_odt_val;
1659
1660 for (i = 0; i < timing_config->ch_cnt; i++) {
1661 if (timing_config->dram_type == LPDDR4)
1662 drv_odt_val = drv_config->phy_side_odt |
Caesar Wang8bc16672016-10-27 01:12:47 +08001663 (PHY_DRV_ODT_Hi_Z << 4) |
1664 (drv_config->phy_side_dq_drv << 8) |
1665 (drv_config->phy_side_dq_drv << 12);
Caesar Wanga8456902016-10-27 01:12:34 +08001666 else if (timing_config->dram_type == LPDDR3)
1667 drv_odt_val = PHY_DRV_ODT_Hi_Z |
Caesar Wang8bc16672016-10-27 01:12:47 +08001668 (drv_config->phy_side_odt << 4) |
1669 (drv_config->phy_side_dq_drv << 8) |
1670 (drv_config->phy_side_dq_drv << 12);
Caesar Wanga8456902016-10-27 01:12:34 +08001671 else
1672 drv_odt_val = drv_config->phy_side_odt |
Caesar Wang8bc16672016-10-27 01:12:47 +08001673 (drv_config->phy_side_odt << 4) |
1674 (drv_config->phy_side_dq_drv << 8) |
1675 (drv_config->phy_side_dq_drv << 12);
Caesar Wanga8456902016-10-27 01:12:34 +08001676
1677 /* DQ drv odt set */
Caesar Wang8bc16672016-10-27 01:12:47 +08001678 mmio_clrsetbits_32(PHY_REG(i, 6), 0xffffff, drv_odt_val);
1679 mmio_clrsetbits_32(PHY_REG(i, 134), 0xffffff, drv_odt_val);
1680 mmio_clrsetbits_32(PHY_REG(i, 262), 0xffffff, drv_odt_val);
1681 mmio_clrsetbits_32(PHY_REG(i, 390), 0xffffff, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001682 /* DQS drv odt set */
Caesar Wang8bc16672016-10-27 01:12:47 +08001683 mmio_clrsetbits_32(PHY_REG(i, 7), 0xffffff, drv_odt_val);
1684 mmio_clrsetbits_32(PHY_REG(i, 135), 0xffffff, drv_odt_val);
1685 mmio_clrsetbits_32(PHY_REG(i, 263), 0xffffff, drv_odt_val);
1686 mmio_clrsetbits_32(PHY_REG(i, 391), 0xffffff, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001687
1688 gen_rk3399_set_odt(timing_config->odt);
1689
1690 /* CA drv set */
1691 drv_odt_val = drv_config->phy_side_ca_drv |
Caesar Wang8bc16672016-10-27 01:12:47 +08001692 (drv_config->phy_side_ca_drv << 4);
1693 mmio_clrsetbits_32(PHY_REG(i, 544), 0xff, drv_odt_val);
1694 mmio_clrsetbits_32(PHY_REG(i, 672), 0xff, drv_odt_val);
1695 mmio_clrsetbits_32(PHY_REG(i, 800), 0xff, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001696
Caesar Wang8bc16672016-10-27 01:12:47 +08001697 mmio_clrsetbits_32(PHY_REG(i, 928), 0xff, drv_odt_val);
1698 mmio_clrsetbits_32(PHY_REG(i, 937), 0xff, drv_odt_val);
1699 mmio_clrsetbits_32(PHY_REG(i, 935), 0xff, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001700
1701 drv_odt_val = drv_config->phy_side_ck_cs_drv |
Caesar Wang8bc16672016-10-27 01:12:47 +08001702 (drv_config->phy_side_ck_cs_drv << 4);
1703 mmio_clrsetbits_32(PHY_REG(i, 929), 0xff, drv_odt_val);
1704 mmio_clrsetbits_32(PHY_REG(i, 939), 0xff, drv_odt_val);
Caesar Wanga8456902016-10-27 01:12:34 +08001705 }
1706}
1707
1708static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
1709 struct drv_odt_lp_config *drv_config,
1710 struct dram_timing_t *pdram_timing,
1711 uint32_t fn)
1712{
1713 uint32_t tmp, i, div, j;
1714 uint32_t mem_delay_ps, pad_delay_ps, total_delay_ps, delay_frac_ps;
1715 uint32_t trpre_min_ps, gate_delay_ps, gate_delay_frac_ps;
1716 uint32_t ie_enable, tsel_enable, cas_lat, rddata_en_ie_dly, tsel_adder;
1717 uint32_t extra_adder, delta, hs_offset;
1718
1719 for (i = 0; i < timing_config->ch_cnt; i++) {
1720
1721 pad_delay_ps = PI_PAD_DELAY_PS_VALUE;
1722 ie_enable = PI_IE_ENABLE_VALUE;
1723 tsel_enable = PI_TSEL_ENABLE_VALUE;
1724
Caesar Wang8bc16672016-10-27 01:12:47 +08001725 mmio_clrsetbits_32(PHY_REG(i, 896), (0x3 << 8) | 1, fn << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001726
1727 /* PHY_LOW_FREQ_SEL */
1728 /* DENALI_PHY_913 1bit offset_0 */
1729 if (timing_config->freq > 400)
Caesar Wang8bc16672016-10-27 01:12:47 +08001730 mmio_clrbits_32(PHY_REG(i, 913), 1);
Caesar Wanga8456902016-10-27 01:12:34 +08001731 else
Caesar Wang8bc16672016-10-27 01:12:47 +08001732 mmio_setbits_32(PHY_REG(i, 913), 1);
Caesar Wanga8456902016-10-27 01:12:34 +08001733
1734 /* PHY_RPTR_UPDATE_x */
1735 /* DENALI_PHY_87/215/343/471 4bit offset_16 */
1736 tmp = 2500 / (1000000 / pdram_timing->mhz) + 3;
1737 if ((2500 % (1000000 / pdram_timing->mhz)) != 0)
1738 tmp++;
Caesar Wang8bc16672016-10-27 01:12:47 +08001739 mmio_clrsetbits_32(PHY_REG(i, 87), 0xf << 16, tmp << 16);
1740 mmio_clrsetbits_32(PHY_REG(i, 215), 0xf << 16, tmp << 16);
1741 mmio_clrsetbits_32(PHY_REG(i, 343), 0xf << 16, tmp << 16);
1742 mmio_clrsetbits_32(PHY_REG(i, 471), 0xf << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001743
1744 /* PHY_PLL_CTRL */
1745 /* DENALI_PHY_911 13bits offset_0 */
1746 /* PHY_LP4_BOOT_PLL_CTRL */
1747 /* DENALI_PHY_919 13bits offset_0 */
1748 if (pdram_timing->mhz <= 150)
1749 tmp = 3;
1750 else if (pdram_timing->mhz <= 300)
1751 tmp = 2;
1752 else if (pdram_timing->mhz <= 600)
1753 tmp = 1;
1754 else
1755 tmp = 0;
1756 tmp = (1 << 12) | (tmp << 9) | (2 << 7) | (1 << 1);
Caesar Wang8bc16672016-10-27 01:12:47 +08001757 mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff, tmp);
1758 mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001759
1760 /* PHY_PLL_CTRL_CA */
1761 /* DENALI_PHY_911 13bits offset_16 */
1762 /* PHY_LP4_BOOT_PLL_CTRL_CA */
1763 /* DENALI_PHY_919 13bits offset_16 */
1764 if (pdram_timing->mhz <= 150)
1765 tmp = 3;
1766 else if (pdram_timing->mhz <= 300)
1767 tmp = 2;
1768 else if (pdram_timing->mhz <= 600)
1769 tmp = 1;
1770 else
1771 tmp = 0;
1772 tmp = (tmp << 9) | (2 << 7) | (1 << 5) | (1 << 1);
Caesar Wang8bc16672016-10-27 01:12:47 +08001773 mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff << 16, tmp << 16);
1774 mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001775
1776 /* PHY_TCKSRE_WAIT */
1777 /* DENALI_PHY_922 4bits offset_24 */
1778 if (pdram_timing->mhz <= 400)
1779 tmp = 1;
1780 else if (pdram_timing->mhz <= 800)
1781 tmp = 3;
1782 else if (pdram_timing->mhz <= 1000)
1783 tmp = 4;
1784 else
1785 tmp = 5;
Caesar Wang8bc16672016-10-27 01:12:47 +08001786 mmio_clrsetbits_32(PHY_REG(i, 922), 0xf << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001787 /* PHY_CAL_CLK_SELECT_0:RW8:3 */
1788 div = pdram_timing->mhz / (2 * 20);
1789 for (j = 2, tmp = 1; j <= 128; j <<= 1, tmp++) {
1790 if (div < j)
1791 break;
1792 }
Caesar Wang8bc16672016-10-27 01:12:47 +08001793 mmio_clrsetbits_32(PHY_REG(i, 947), 0x7 << 8, tmp << 8);
1794 mmio_setbits_32(PHY_REG(i, 927), (1 << 22));
Caesar Wanga8456902016-10-27 01:12:34 +08001795
1796 if (timing_config->dram_type == DDR3) {
1797 mem_delay_ps = 0;
1798 trpre_min_ps = 1000;
1799 } else if (timing_config->dram_type == LPDDR4) {
1800 mem_delay_ps = 1500;
1801 trpre_min_ps = 900;
1802 } else if (timing_config->dram_type == LPDDR3) {
1803 mem_delay_ps = 2500;
1804 trpre_min_ps = 900;
1805 } else {
1806 ERROR("gen_rk3399_phy_params:dramtype unsupport\n");
1807 return;
1808 }
1809 total_delay_ps = mem_delay_ps + pad_delay_ps;
Caesar Wang8bc16672016-10-27 01:12:47 +08001810 delay_frac_ps = 1000 * total_delay_ps /
1811 (1000000 / pdram_timing->mhz);
Caesar Wanga8456902016-10-27 01:12:34 +08001812 gate_delay_ps = delay_frac_ps + 1000 - (trpre_min_ps / 2);
Caesar Wang8bc16672016-10-27 01:12:47 +08001813 gate_delay_frac_ps = gate_delay_ps % 1000;
Caesar Wanga8456902016-10-27 01:12:34 +08001814 tmp = gate_delay_frac_ps * 0x200 / 1000;
1815 /* PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY */
1816 /* DENALI_PHY_2/130/258/386 10bits offset_0 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001817 mmio_clrsetbits_32(PHY_REG(i, 2), 0x2ff, tmp);
1818 mmio_clrsetbits_32(PHY_REG(i, 130), 0x2ff, tmp);
1819 mmio_clrsetbits_32(PHY_REG(i, 258), 0x2ff, tmp);
1820 mmio_clrsetbits_32(PHY_REG(i, 386), 0x2ff, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001821 /* PHY_RDDQS_GATE_SLAVE_DELAY */
1822 /* DENALI_PHY_77/205/333/461 10bits offset_16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001823 mmio_clrsetbits_32(PHY_REG(i, 77), 0x2ff << 16, tmp << 16);
1824 mmio_clrsetbits_32(PHY_REG(i, 205), 0x2ff << 16, tmp << 16);
1825 mmio_clrsetbits_32(PHY_REG(i, 333), 0x2ff << 16, tmp << 16);
1826 mmio_clrsetbits_32(PHY_REG(i, 461), 0x2ff << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001827
1828 tmp = gate_delay_ps / 1000;
1829 /* PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST */
1830 /* DENALI_PHY_10/138/266/394 4bit offset_0 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001831 mmio_clrsetbits_32(PHY_REG(i, 10), 0xf, tmp);
1832 mmio_clrsetbits_32(PHY_REG(i, 138), 0xf, tmp);
1833 mmio_clrsetbits_32(PHY_REG(i, 266), 0xf, tmp);
1834 mmio_clrsetbits_32(PHY_REG(i, 394), 0xf, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001835 /* PHY_RDDQS_LATENCY_ADJUST */
1836 /* DENALI_PHY_78/206/334/462 4bits offset_0 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001837 mmio_clrsetbits_32(PHY_REG(i, 78), 0xf, tmp);
1838 mmio_clrsetbits_32(PHY_REG(i, 206), 0xf, tmp);
1839 mmio_clrsetbits_32(PHY_REG(i, 334), 0xf, tmp);
1840 mmio_clrsetbits_32(PHY_REG(i, 462), 0xf, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001841 /* PHY_GTLVL_LAT_ADJ_START */
1842 /* DENALI_PHY_80/208/336/464 4bits offset_16 */
1843 tmp = delay_frac_ps / 1000;
Caesar Wang8bc16672016-10-27 01:12:47 +08001844 mmio_clrsetbits_32(PHY_REG(i, 80), 0xf << 16, tmp << 16);
1845 mmio_clrsetbits_32(PHY_REG(i, 208), 0xf << 16, tmp << 16);
1846 mmio_clrsetbits_32(PHY_REG(i, 336), 0xf << 16, tmp << 16);
1847 mmio_clrsetbits_32(PHY_REG(i, 464), 0xf << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001848
1849 cas_lat = pdram_timing->cl + PI_ADD_LATENCY;
1850 rddata_en_ie_dly = ie_enable / (1000000 / pdram_timing->mhz);
1851 if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0)
1852 rddata_en_ie_dly++;
1853 rddata_en_ie_dly = rddata_en_ie_dly - 1;
1854 tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz);
1855 if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0)
1856 tsel_adder++;
1857 if (rddata_en_ie_dly > tsel_adder)
1858 extra_adder = rddata_en_ie_dly - tsel_adder;
1859 else
1860 extra_adder = 0;
1861 delta = cas_lat - rddata_en_ie_dly;
1862 if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK)
1863 hs_offset = 2;
1864 else
1865 hs_offset = 1;
Caesar Wang8bc16672016-10-27 01:12:47 +08001866 if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset))
Caesar Wanga8456902016-10-27 01:12:34 +08001867 tmp = 0;
Caesar Wang8bc16672016-10-27 01:12:47 +08001868 else if ((delta == 2) || (delta == 1))
1869 tmp = rddata_en_ie_dly - 0 - extra_adder;
1870 else
1871 tmp = extra_adder;
Caesar Wanga8456902016-10-27 01:12:34 +08001872 /* PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY */
1873 /* DENALI_PHY_9/137/265/393 4bit offset_16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001874 mmio_clrsetbits_32(PHY_REG(i, 9), 0xf << 16, tmp << 16);
1875 mmio_clrsetbits_32(PHY_REG(i, 137), 0xf << 16, tmp << 16);
1876 mmio_clrsetbits_32(PHY_REG(i, 265), 0xf << 16, tmp << 16);
1877 mmio_clrsetbits_32(PHY_REG(i, 393), 0xf << 16, tmp << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001878 /* PHY_RDDATA_EN_TSEL_DLY */
1879 /* DENALI_PHY_86/214/342/470 4bit offset_0 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001880 mmio_clrsetbits_32(PHY_REG(i, 86), 0xf, tmp);
1881 mmio_clrsetbits_32(PHY_REG(i, 214), 0xf, tmp);
1882 mmio_clrsetbits_32(PHY_REG(i, 342), 0xf, tmp);
1883 mmio_clrsetbits_32(PHY_REG(i, 470), 0xf, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08001884
1885 if (tsel_adder > rddata_en_ie_dly)
1886 extra_adder = tsel_adder - rddata_en_ie_dly;
1887 else
1888 extra_adder = 0;
1889 if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset))
1890 tmp = tsel_adder;
1891 else
1892 tmp = rddata_en_ie_dly - 0 + extra_adder;
1893 /* PHY_LP4_BOOT_RDDATA_EN_DLY */
1894 /* DENALI_PHY_9/137/265/393 4bit offset_8 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001895 mmio_clrsetbits_32(PHY_REG(i, 9), 0xf << 8, tmp << 8);
1896 mmio_clrsetbits_32(PHY_REG(i, 137), 0xf << 8, tmp << 8);
1897 mmio_clrsetbits_32(PHY_REG(i, 265), 0xf << 8, tmp << 8);
1898 mmio_clrsetbits_32(PHY_REG(i, 393), 0xf << 8, tmp << 8);
Caesar Wanga8456902016-10-27 01:12:34 +08001899 /* PHY_RDDATA_EN_DLY */
1900 /* DENALI_PHY_85/213/341/469 4bit offset_24 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001901 mmio_clrsetbits_32(PHY_REG(i, 85), 0xf << 24, tmp << 24);
1902 mmio_clrsetbits_32(PHY_REG(i, 213), 0xf << 24, tmp << 24);
1903 mmio_clrsetbits_32(PHY_REG(i, 341), 0xf << 24, tmp << 24);
1904 mmio_clrsetbits_32(PHY_REG(i, 469), 0xf << 24, tmp << 24);
Caesar Wanga8456902016-10-27 01:12:34 +08001905
1906 if (pdram_timing->mhz <= ENPER_CS_TRAINING_FREQ) {
Caesar Wanga8456902016-10-27 01:12:34 +08001907 /*
1908 * Note:Per-CS Training is not compatible at speeds
1909 * under 533 MHz. If the PHY is running at a speed
1910 * less than 533MHz, all phy_per_cs_training_en_X
1911 * parameters must be cleared to 0.
1912 */
1913
1914 /*DENALI_PHY_84/212/340/468 1bit offset_16 */
Caesar Wang8bc16672016-10-27 01:12:47 +08001915 mmio_clrbits_32(PHY_REG(i, 84), 0x1 << 16);
1916 mmio_clrbits_32(PHY_REG(i, 212), 0x1 << 16);
1917 mmio_clrbits_32(PHY_REG(i, 340), 0x1 << 16);
1918 mmio_clrbits_32(PHY_REG(i, 468), 0x1 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001919 } else {
Caesar Wang8bc16672016-10-27 01:12:47 +08001920 mmio_setbits_32(PHY_REG(i, 84), 0x1 << 16);
1921 mmio_setbits_32(PHY_REG(i, 212), 0x1 << 16);
1922 mmio_setbits_32(PHY_REG(i, 340), 0x1 << 16);
1923 mmio_setbits_32(PHY_REG(i, 468), 0x1 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08001924 }
1925 }
1926}
1927
1928static int to_get_clk_index(unsigned int mhz)
1929{
1930 int pll_cnt, i;
1931
1932 pll_cnt = ARRAY_SIZE(dpll_rates_table);
1933
1934 /* Assumming rate_table is in descending order */
1935 for (i = 0; i < pll_cnt; i++) {
1936 if (mhz >= dpll_rates_table[i].mhz)
1937 break;
1938 }
1939
1940 /* if mhz lower than lowest frequency in table, use lowest frequency */
1941 if (i == pll_cnt)
1942 i = pll_cnt - 1;
1943
1944 return i;
1945}
1946
1947uint32_t rkclk_prepare_pll_timing(unsigned int mhz)
1948{
1949 unsigned int refdiv, postdiv1, fbdiv, postdiv2;
1950 int index;
1951
1952 index = to_get_clk_index(mhz);
1953 refdiv = dpll_rates_table[index].refdiv;
1954 fbdiv = dpll_rates_table[index].fbdiv;
1955 postdiv1 = dpll_rates_table[index].postdiv1;
1956 postdiv2 = dpll_rates_table[index].postdiv2;
Caesar Wang8bc16672016-10-27 01:12:47 +08001957 mmio_write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(fbdiv));
1958 mmio_write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON1,
1959 POSTDIV2(postdiv2) | POSTDIV1(postdiv1) | REFDIV(refdiv));
Caesar Wanga8456902016-10-27 01:12:34 +08001960 return (24 * fbdiv) / refdiv / postdiv1 / postdiv2;
1961}
1962
1963uint32_t ddr_get_rate(void)
1964{
1965 uint32_t refdiv, postdiv1, fbdiv, postdiv2;
1966
1967 refdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) & 0x3f;
1968 fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff;
1969 postdiv1 =
1970 (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 8) & 0x7;
1971 postdiv2 =
1972 (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 12) & 0x7;
1973
1974 return (24 / refdiv * fbdiv / postdiv1 / postdiv2) * 1000 * 1000;
1975}
1976
1977/*
1978 * return: bit12: channel 1, external self-refresh
1979 * bit11: channel 1, stdby_mode
1980 * bit10: channel 1, self-refresh with controller and memory clock gate
1981 * bit9: channel 1, self-refresh
1982 * bit8: channel 1, power-down
1983 *
1984 * bit4: channel 1, external self-refresh
1985 * bit3: channel 0, stdby_mode
1986 * bit2: channel 0, self-refresh with controller and memory clock gate
1987 * bit1: channel 0, self-refresh
1988 * bit0: channel 0, power-down
1989 */
1990uint32_t exit_low_power(void)
1991{
Caesar Wanga8456902016-10-27 01:12:34 +08001992 uint32_t low_power = 0;
1993 uint32_t channel_mask;
Caesar Wang8bc16672016-10-27 01:12:47 +08001994 uint32_t tmp, i;
Caesar Wanga8456902016-10-27 01:12:34 +08001995
Caesar Wang8bc16672016-10-27 01:12:47 +08001996 channel_mask = (mmio_read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) &
1997 0x3;
1998 for (i = 0; i < 2; i++) {
1999 if (!(channel_mask & (1 << i)))
Caesar Wanga8456902016-10-27 01:12:34 +08002000 continue;
2001
2002 /* exit stdby mode */
Caesar Wang8bc16672016-10-27 01:12:47 +08002003 mmio_write_32(CIC_BASE + CIC_CTRL1,
2004 (1 << (i + 16)) | (0 << i));
Caesar Wanga8456902016-10-27 01:12:34 +08002005 /* exit external self-refresh */
Caesar Wang8bc16672016-10-27 01:12:47 +08002006 tmp = i ? 12 : 8;
2007 low_power |= ((mmio_read_32(PMU_BASE + PMU_SFT_CON) >> tmp) &
2008 0x1) << (4 + 8 * i);
2009 mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 1 << tmp);
2010 while (!(mmio_read_32(PMU_BASE + PMU_DDR_SREF_ST) & (1 << i)))
Caesar Wanga8456902016-10-27 01:12:34 +08002011 ;
2012 /* exit auto low-power */
Caesar Wang8bc16672016-10-27 01:12:47 +08002013 mmio_clrbits_32(CTL_REG(i, 101), 0x7);
Caesar Wanga8456902016-10-27 01:12:34 +08002014 /* lp_cmd to exit */
Caesar Wang8bc16672016-10-27 01:12:47 +08002015 if (((mmio_read_32(CTL_REG(i, 100)) >> 24) & 0x7f) !=
2016 0x40) {
2017 while (mmio_read_32(CTL_REG(i, 200)) & 0x1)
Caesar Wanga8456902016-10-27 01:12:34 +08002018 ;
Caesar Wang8bc16672016-10-27 01:12:47 +08002019 mmio_clrsetbits_32(CTL_REG(i, 93), 0xff << 24,
2020 0x69 << 24);
2021 while (((mmio_read_32(CTL_REG(i, 100)) >> 24) & 0x7f) !=
2022 0x40)
Caesar Wanga8456902016-10-27 01:12:34 +08002023 ;
2024 }
2025 }
2026 return low_power;
2027}
2028
2029void resume_low_power(uint32_t low_power)
2030{
Caesar Wanga8456902016-10-27 01:12:34 +08002031 uint32_t channel_mask;
Caesar Wang8bc16672016-10-27 01:12:47 +08002032 uint32_t tmp, i, val;
Caesar Wanga8456902016-10-27 01:12:34 +08002033
Caesar Wang8bc16672016-10-27 01:12:47 +08002034 channel_mask = (mmio_read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) &
2035 0x3;
2036 for (i = 0; i < 2; i++) {
2037 if (!(channel_mask & (1 << i)))
Caesar Wanga8456902016-10-27 01:12:34 +08002038 continue;
2039
2040 /* resume external self-refresh */
Caesar Wang8bc16672016-10-27 01:12:47 +08002041 tmp = i ? 12 : 8;
2042 val = (low_power >> (4 + 8 * i)) & 0x1;
2043 mmio_setbits_32(PMU_BASE + PMU_SFT_CON, val << tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08002044 /* resume auto low-power */
Caesar Wang8bc16672016-10-27 01:12:47 +08002045 val = (low_power >> (8 * i)) & 0x7;
2046 mmio_setbits_32(CTL_REG(i, 101), val);
Caesar Wanga8456902016-10-27 01:12:34 +08002047 /* resume stdby mode */
Caesar Wang8bc16672016-10-27 01:12:47 +08002048 val = (low_power >> (3 + 8 * i)) & 0x1;
2049 mmio_write_32(CIC_BASE + CIC_CTRL1,
2050 (1 << (i + 16)) | (val << i));
Caesar Wanga8456902016-10-27 01:12:34 +08002051 }
2052}
2053
2054static void wait_dcf_done(void)
2055{
Caesar Wang8bc16672016-10-27 01:12:47 +08002056 while ((mmio_read_32(DCF_BASE + DCF_DCF_ISR) & (DCF_DONE)) == 0)
Caesar Wanga8456902016-10-27 01:12:34 +08002057 continue;
2058}
2059
2060void clr_dcf_irq(void)
2061{
2062 /* clear dcf irq status */
2063 mmio_write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE);
2064}
2065
2066static void enable_dcf(uint32_t dcf_addr)
2067{
2068 /* config DCF start addr */
Caesar Wang8bc16672016-10-27 01:12:47 +08002069 mmio_write_32(DCF_BASE + DCF_DCF_ADDR, dcf_addr);
Caesar Wanga8456902016-10-27 01:12:34 +08002070 /* wait dcf done */
Caesar Wang8bc16672016-10-27 01:12:47 +08002071 while (mmio_read_32(DCF_BASE + DCF_DCF_CTRL) & 1)
Caesar Wanga8456902016-10-27 01:12:34 +08002072 continue;
2073 /* clear dcf irq status */
Caesar Wang8bc16672016-10-27 01:12:47 +08002074 mmio_write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE);
Caesar Wanga8456902016-10-27 01:12:34 +08002075 /* DCF start */
Caesar Wang8bc16672016-10-27 01:12:47 +08002076 mmio_setbits_32(DCF_BASE + DCF_DCF_CTRL, DCF_START);
Caesar Wanga8456902016-10-27 01:12:34 +08002077}
2078
2079void dcf_code_init(void)
2080{
2081 memcpy((void *)DCF_START_ADDR, (void *)dcf_code, sizeof(dcf_code));
2082 /* set dcf master secure */
Caesar Wang8bc16672016-10-27 01:12:47 +08002083 mmio_write_32(SGRF_BASE + 0xe01c, ((0x3 << 0) << 16) | (0 << 0));
2084 mmio_write_32(DCF_BASE + DCF_DCF_TOSET, 0x80000000);
Caesar Wanga8456902016-10-27 01:12:34 +08002085}
2086
2087static void dcf_start(uint32_t freq, uint32_t index)
2088{
Caesar Wang8bc16672016-10-27 01:12:47 +08002089 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
2090 (0x1 << (1 + 16)) | (1 << 1));
2091 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(11),
2092 (0x1 << (0 + 16)) | (1 << 0));
2093 mmio_write_32(DCF_PARAM_ADDR + PARAM_FREQ_SELECT, index << 4);
Caesar Wanga8456902016-10-27 01:12:34 +08002094
Caesar Wang8bc16672016-10-27 01:12:47 +08002095 mmio_write_32(DCF_PARAM_ADDR + PARAM_DRAM_FREQ, freq);
Caesar Wanga8456902016-10-27 01:12:34 +08002096
2097 rkclk_prepare_pll_timing(freq);
2098 udelay(10);
Caesar Wang8bc16672016-10-27 01:12:47 +08002099 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
2100 (0x1 << (1 + 16)) | (0 << 1));
2101 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(11),
2102 (0x1 << (0 + 16)) | (0 << 0));
Caesar Wanga8456902016-10-27 01:12:34 +08002103 udelay(10);
2104 enable_dcf(DCF_START_ADDR);
2105}
2106
2107static void dram_low_power_config(struct drv_odt_lp_config *lp_config)
2108{
2109 uint32_t tmp, tmp1, i;
2110 uint32_t ch_cnt = rk3399_dram_status.timing_config.ch_cnt;
2111 uint32_t dram_type = rk3399_dram_status.timing_config.dram_type;
2112 uint32_t *low_power = &rk3399_dram_status.low_power_stat;
2113
2114 if (dram_type == LPDDR4)
2115 tmp = (lp_config->srpd_lite_idle << 16) |
2116 lp_config->pd_idle;
2117 else
2118 tmp = lp_config->pd_idle;
2119
2120 if (dram_type == DDR3)
2121 tmp1 = (2 << 16) | (0x7 << 8) | 7;
2122 else
2123 tmp1 = (3 << 16) | (0x7 << 8) | 7;
2124
2125 *low_power = 0;
2126
2127 for (i = 0; i < ch_cnt; i++) {
Caesar Wang8bc16672016-10-27 01:12:47 +08002128 mmio_write_32(CTL_REG(i, 102), tmp);
2129 mmio_clrsetbits_32(CTL_REG(i, 103), 0xffff,
2130 (lp_config->sr_mc_gate_idle << 8) |
2131 lp_config->sr_idle);
2132 mmio_clrsetbits_32(CTL_REG(i, 101), 0x70f0f, tmp1);
Caesar Wanga8456902016-10-27 01:12:34 +08002133 *low_power |= (7 << (8 * i));
2134 }
2135
2136 /* standby idle */
Caesar Wang8bc16672016-10-27 01:12:47 +08002137 mmio_write_32(CIC_BASE + CIC_IDLE_TH, lp_config->standby_idle);
2138 mmio_write_32(CIC_BASE + CIC_CG_WAIT_TH, 0x640008);
Caesar Wanga8456902016-10-27 01:12:34 +08002139
2140 if (ch_cnt == 2) {
Caesar Wang8bc16672016-10-27 01:12:47 +08002141 mmio_write_32(GRF_BASE + GRF_DDRC1_CON1,
2142 (((0x1<<4) | (0x1<<5) | (0x1<<6) |
2143 (0x1<<7)) << 16) |
2144 ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7)));
Caesar Wanga8456902016-10-27 01:12:34 +08002145 if (lp_config->standby_idle) {
2146 tmp = 0x002a002a;
2147 *low_power |= (1 << 11);
Caesar Wang8bc16672016-10-27 01:12:47 +08002148 } else
Caesar Wanga8456902016-10-27 01:12:34 +08002149 tmp = 0;
Caesar Wang8bc16672016-10-27 01:12:47 +08002150 mmio_write_32(CIC_BASE + CIC_CTRL1, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08002151 }
2152
Caesar Wang8bc16672016-10-27 01:12:47 +08002153 mmio_write_32(GRF_BASE + GRF_DDRC0_CON1,
2154 (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) |
2155 ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7)));
Caesar Wanga8456902016-10-27 01:12:34 +08002156 if (lp_config->standby_idle) {
2157 tmp = 0x00150015;
2158 *low_power |= (1 << 3);
Caesar Wang8bc16672016-10-27 01:12:47 +08002159 } else
Caesar Wanga8456902016-10-27 01:12:34 +08002160 tmp = 0;
Caesar Wang8bc16672016-10-27 01:12:47 +08002161 mmio_write_32(CIC_BASE + CIC_CTRL1, tmp);
Caesar Wanga8456902016-10-27 01:12:34 +08002162}
2163
2164
2165static void dram_related_init(struct ddr_dts_config_timing *dts_timing)
2166{
2167 uint32_t trefi0, trefi1;
2168 uint32_t i;
2169
2170 dcf_code_init();
2171
2172 /* get sdram config for os reg */
2173 drv_odt_lp_cfg_init(sdram_config.dramtype, dts_timing,
2174 &rk3399_dram_status.drv_odt_lp_cfg);
2175 sdram_timing_cfg_init(&rk3399_dram_status.timing_config,
2176 &sdram_config,
2177 &rk3399_dram_status.drv_odt_lp_cfg);
2178
Caesar Wang8bc16672016-10-27 01:12:47 +08002179 trefi0 = ((mmio_read_32(CTL_REG(0, 48)) >> 16) & 0xffff) + 8;
2180 trefi1 = ((mmio_read_32(CTL_REG(0, 49)) >> 16) & 0xffff) + 8;
Caesar Wanga8456902016-10-27 01:12:34 +08002181
2182 rk3399_dram_status.index_freq[0] = trefi0 * 10 / 39;
2183 rk3399_dram_status.index_freq[1] = trefi1 * 10 / 39;
2184 rk3399_dram_status.current_index =
Caesar Wang8bc16672016-10-27 01:12:47 +08002185 (mmio_read_32(CTL_REG(0, 111)) >> 16) & 0x3;
Caesar Wanga8456902016-10-27 01:12:34 +08002186 if (rk3399_dram_status.timing_config.dram_type == DDR3) {
2187 rk3399_dram_status.index_freq[0] /= 2;
2188 rk3399_dram_status.index_freq[1] /= 2;
2189 }
2190 rk3399_dram_status.index_freq[(rk3399_dram_status.current_index + 1)
2191 & 0x1] = 0;
2192
2193 /* disable all training by ctl and pi */
2194 for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) {
Caesar Wang8bc16672016-10-27 01:12:47 +08002195 mmio_clrbits_32(CTL_REG(i, 70), (1 << 24) |
Caesar Wanga8456902016-10-27 01:12:34 +08002196 (1 << 16) | (1 << 8) | 1);
Caesar Wang8bc16672016-10-27 01:12:47 +08002197 mmio_clrbits_32(CTL_REG(i, 71), 1);
Caesar Wanga8456902016-10-27 01:12:34 +08002198
Caesar Wang8bc16672016-10-27 01:12:47 +08002199 mmio_clrbits_32(PI_REG(i, 60), 0x3 << 8);
2200 mmio_clrbits_32(PI_REG(i, 80), (0x3 << 24) | (0x3 << 16));
2201 mmio_clrbits_32(PI_REG(i, 100), 0x3 << 8);
2202 mmio_clrbits_32(PI_REG(i, 124), 0x3 << 16);
Caesar Wanga8456902016-10-27 01:12:34 +08002203 }
2204
2205 /* init drv odt */
2206 if (rk3399_dram_status.index_freq[rk3399_dram_status.current_index] <
2207 rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq)
2208 rk3399_dram_status.timing_config.odt = 0;
2209 else
2210 rk3399_dram_status.timing_config.odt = 1;
2211 gen_rk3399_set_ds_odt(&rk3399_dram_status.timing_config,
2212 &rk3399_dram_status.drv_odt_lp_cfg);
2213 dram_low_power_config(&rk3399_dram_status.drv_odt_lp_cfg);
2214}
2215
2216static uint32_t prepare_ddr_timing(uint32_t mhz)
2217{
2218 uint32_t index;
2219 struct dram_timing_t dram_timing;
2220
2221 rk3399_dram_status.timing_config.freq = mhz;
2222
2223 if (mhz < rk3399_dram_status.drv_odt_lp_cfg.ddr3_dll_dis_freq)
2224 rk3399_dram_status.timing_config.dllbp = 1;
2225 else
2226 rk3399_dram_status.timing_config.dllbp = 0;
2227 if (mhz < rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq) {
2228 rk3399_dram_status.timing_config.odt = 0;
2229 } else {
2230 rk3399_dram_status.timing_config.odt = 1;
2231 gen_rk3399_set_odt(1);
2232 }
2233
2234 index = (rk3399_dram_status.current_index + 1) & 0x1;
2235 if (rk3399_dram_status.index_freq[index] == mhz)
2236 goto out;
2237
2238 /*
2239 * checking if having available gate traiing timing for
2240 * target freq.
2241 */
2242 dram_get_parameter(&rk3399_dram_status.timing_config, &dram_timing);
2243 gen_rk3399_ctl_params(&rk3399_dram_status.timing_config,
2244 &dram_timing, index);
2245 gen_rk3399_pi_params(&rk3399_dram_status.timing_config,
2246 &dram_timing, index);
2247 gen_rk3399_phy_params(&rk3399_dram_status.timing_config,
2248 &rk3399_dram_status.drv_odt_lp_cfg,
2249 &dram_timing, index);
2250 rk3399_dram_status.index_freq[index] = mhz;
2251
2252
2253out:
2254 return index;
2255}
2256
2257void print_dram_status_info(void)
2258{
2259 uint32_t *p;
2260 uint32_t i;
2261
2262 p = (uint32_t *) &rk3399_dram_status.timing_config;
2263 INFO("rk3399_dram_status.timing_config:\n");
2264 for (i = 0; i < sizeof(struct timing_related_config) / 4; i++)
2265 tf_printf("%u\n", p[i]);
2266 p = (uint32_t *) &rk3399_dram_status.drv_odt_lp_cfg;
2267 INFO("rk3399_dram_status.drv_odt_lp_cfg:\n");
2268 for (i = 0; i < sizeof(struct drv_odt_lp_config) / 4; i++)
2269 tf_printf("%u\n", p[i]);
2270}
2271
2272uint32_t ddr_set_rate(uint32_t hz)
2273{
2274 uint32_t low_power, index;
2275 uint32_t mhz = hz / (1000 * 1000);
2276
2277 if (mhz ==
2278 rk3399_dram_status.index_freq[rk3399_dram_status.current_index])
2279 goto out;
2280
2281 index = to_get_clk_index(mhz);
2282 mhz = dpll_rates_table[index].mhz;
2283
2284 low_power = exit_low_power();
2285 index = prepare_ddr_timing(mhz);
2286 if (index > 1)
2287 goto out;
2288
2289 dcf_start(mhz, index);
2290 wait_dcf_done();
2291 if (rk3399_dram_status.timing_config.odt == 0)
2292 gen_rk3399_set_odt(0);
2293
2294 rk3399_dram_status.current_index = index;
2295
2296 if (mhz < dts_parameter.auto_pd_dis_freq)
2297 low_power |= rk3399_dram_status.low_power_stat;
2298
2299 resume_low_power(low_power);
2300out:
2301 return mhz;
2302}
2303
2304uint32_t ddr_round_rate(uint32_t hz)
2305{
2306 int index;
2307 uint32_t mhz = hz / (1000 * 1000);
2308
2309 index = to_get_clk_index(mhz);
2310
2311 return dpll_rates_table[index].mhz * 1000 * 1000;
2312}
2313
2314uint32_t dts_timing_receive(uint32_t timing, uint32_t index)
2315{
2316 uint32_t *p = (uint32_t *) &dts_parameter;
2317 static uint32_t receive_nums;
2318
2319 if (index < (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) {
2320 p[index] = (uint32_t)timing;
2321 receive_nums++;
2322 } else {
2323 dts_parameter.available = 0;
2324 return -1;
2325 }
2326
2327 /* receive all parameter */
2328 if (receive_nums == (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) {
2329 dts_parameter.available = 1;
2330 receive_nums = 0;
2331 }
2332
2333 return index;
2334}
2335
2336void ddr_dfs_init(void)
2337{
2338 dram_related_init(&dts_parameter);
2339}