blob: f88de8301b868e4c6191233b41c6668501412016 [file] [log] [blame]
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001/*
2 * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdint.h>
8#include <string.h>
9#include <stdio.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <common/debug.h>
12#include <lib/mmio.h>
13
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020014#include "ddr_regdef.h"
15#include "init_dram_tbl_h3.h"
16#include "init_dram_tbl_m3.h"
17#include "init_dram_tbl_h3ver2.h"
18#include "init_dram_tbl_m3n.h"
19#include "boot_init_dram_regdef.h"
20#include "boot_init_dram.h"
21#include "dram_sub_func.h"
22#include "micro_delay.h"
23
24#define DDR_BACKUPMODE
25#define FATAL_MSG(x) NOTICE(x)
26
27/*******************************************************************************
28 * variables
29 ******************************************************************************/
30#ifdef RCAR_DDR_FIXED_LSI_TYPE
31#ifndef RCAR_AUTO
32#define RCAR_AUTO 99
33#define RCAR_H3 0
34#define RCAR_M3 1
35#define RCAR_M3N 2
36#define RCAR_E3 3 /* NON */
37#define RCAR_H3N 4
38
39#define RCAR_CUT_10 0
40#define RCAR_CUT_11 1
41#define RCAR_CUT_20 10
42#define RCAR_CUT_30 20
43#endif
44#ifndef RCAR_LSI
45#define RCAR_LSI RCAR_AUTO
46#endif
47#if(RCAR_LSI==RCAR_AUTO)
48static uint32_t Prr_Product;
49static uint32_t Prr_Cut;
50#else
51#if(RCAR_LSI==RCAR_H3)
52static const uint32_t Prr_Product = PRR_PRODUCT_H3;
53#elif(RCAR_LSI==RCAR_M3)
54static const uint32_t Prr_Product = PRR_PRODUCT_M3;
55#elif(RCAR_LSI==RCAR_M3N)
56static const uint32_t Prr_Product = PRR_PRODUCT_M3N;
57#elif(RCAR_LSI==RCAR_H3N)
58static const uint32_t Prr_Product = PRR_PRODUCT_H3;
59#endif /* RCAR_LSI */
60
61#ifndef RCAR_LSI_CUT
62static uint32_t Prr_Cut;
63#else /* RCAR_LSI_CUT */
64#if(RCAR_LSI_CUT==RCAR_CUT_10)
65static const uint32_t Prr_Cut = PRR_PRODUCT_10;
66#elif(RCAR_LSI_CUT==RCAR_CUT_11)
67static const uint32_t Prr_Cut = PRR_PRODUCT_11;
68#elif(RCAR_LSI_CUT==RCAR_CUT_20)
69static const uint32_t Prr_Cut = PRR_PRODUCT_20;
70#elif(RCAR_LSI_CUT==RCAR_CUT_30)
71static const uint32_t Prr_Cut = PRR_PRODUCT_30;
72#endif /* RCAR_LSI_CUT */
73#endif /* RCAR_LSI_CUT */
74#endif /* RCAR_AUTO_NON */
75#else /* RCAR_DDR_FIXED_LSI_TYPE */
76static uint32_t Prr_Product;
77static uint32_t Prr_Cut;
78#endif /* RCAR_DDR_FIXED_LSI_TYPE */
79
80char *pRCAR_DDR_VERSION;
81uint32_t _cnf_BOARDTYPE;
82static uint32_t *pDDR_REGDEF_TBL;
83static uint32_t brd_clk;
84static uint32_t brd_clkdiv;
85static uint32_t brd_clkdiva;
86static uint32_t ddr_mbps;
87static uint32_t ddr_mbpsdiv;
88static uint32_t ddr_tccd;
89static struct _boardcnf *Boardcnf;
Marek Vasut6c245a52018-12-12 18:06:39 +010090static uint32_t ddr_phyvalid;
91static uint32_t ddr_phycaslice;
92static volatile uint32_t ddr_density[DRAM_CH_CNT][CS_CNT];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020093static uint32_t ch_have_this_cs[CS_CNT];
94static uint32_t rdqdm_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2][9];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020095static uint32_t max_density;
96static uint32_t ddr0800_mul;
97static uint32_t ddr_mul;
98static uint32_t ddr_mbps;
99static uint32_t DDR_PHY_SLICE_REGSET_OFS;
100static uint32_t DDR_PHY_ADR_V_REGSET_OFS;
101static uint32_t DDR_PHY_ADR_I_REGSET_OFS;
102static uint32_t DDR_PHY_ADR_G_REGSET_OFS;
103static uint32_t DDR_PI_REGSET_OFS;
104static uint32_t DDR_PHY_SLICE_REGSET_SIZE;
105static uint32_t DDR_PHY_ADR_V_REGSET_SIZE;
106static uint32_t DDR_PHY_ADR_I_REGSET_SIZE;
107static uint32_t DDR_PHY_ADR_G_REGSET_SIZE;
108static uint32_t DDR_PI_REGSET_SIZE;
109static uint32_t DDR_PHY_SLICE_REGSET_NUM;
110static uint32_t DDR_PHY_ADR_V_REGSET_NUM;
111static uint32_t DDR_PHY_ADR_I_REGSET_NUM;
112static uint32_t DDR_PHY_ADR_G_REGSET_NUM;
113static uint32_t DDR_PI_REGSET_NUM;
114static uint32_t DDR_PHY_ADR_I_NUM;
115#define DDR_PHY_REGSET_MAX 128
116#define DDR_PI_REGSET_MAX 320
117static uint32_t _cnf_DDR_PHY_SLICE_REGSET[DDR_PHY_REGSET_MAX];
118static uint32_t _cnf_DDR_PHY_ADR_V_REGSET[DDR_PHY_REGSET_MAX];
119static uint32_t _cnf_DDR_PHY_ADR_I_REGSET[DDR_PHY_REGSET_MAX];
120static uint32_t _cnf_DDR_PHY_ADR_G_REGSET[DDR_PHY_REGSET_MAX];
121static uint32_t _cnf_DDR_PI_REGSET[DDR_PI_REGSET_MAX];
122static uint32_t Pll3Mode;
123static uint32_t loop_max;
124#ifdef DDR_BACKUPMODE
125uint32_t ddrBackup;
126/* #define DDR_BACKUPMODE_HALF //for Half channel(ch0,1 only) */
127#endif
128
129#ifdef ddr_qos_init_setting /* only for non qos_init */
130#define OPERATING_FREQ (400U) /* Mhz */
131#define BASE_SUB_SLOT_NUM (0x6U)
132#define SUB_SLOT_CYCLE (0x7EU) /* 126 */
133#define QOSWT_WTSET0_CYCLE ((SUB_SLOT_CYCLE * BASE_SUB_SLOT_NUM * 1000U)/OPERATING_FREQ) /* unit:ns */
134
135uint32_t get_refperiod(void)
136{
137 return QOSWT_WTSET0_CYCLE;
138}
139#else /* ddr_qos_init_setting // only for non qos_init */
140extern uint32_t get_refperiod(void);
141#endif /* ddr_qos_init_setting // only for non qos_init */
142
143#define _reg_PHY_RX_CAL_X_NUM 11
144static const uint32_t _reg_PHY_RX_CAL_X[_reg_PHY_RX_CAL_X_NUM] = {
145 _reg_PHY_RX_CAL_DQ0,
146 _reg_PHY_RX_CAL_DQ1,
147 _reg_PHY_RX_CAL_DQ2,
148 _reg_PHY_RX_CAL_DQ3,
149 _reg_PHY_RX_CAL_DQ4,
150 _reg_PHY_RX_CAL_DQ5,
151 _reg_PHY_RX_CAL_DQ6,
152 _reg_PHY_RX_CAL_DQ7,
153 _reg_PHY_RX_CAL_DM,
154 _reg_PHY_RX_CAL_DQS,
155 _reg_PHY_RX_CAL_FDBK
156};
157
158#define _reg_PHY_CLK_WRX_SLAVE_DELAY_NUM 10
159static const uint32_t
160 _reg_PHY_CLK_WRX_SLAVE_DELAY[_reg_PHY_CLK_WRX_SLAVE_DELAY_NUM] = {
161 _reg_PHY_CLK_WRDQ0_SLAVE_DELAY,
162 _reg_PHY_CLK_WRDQ1_SLAVE_DELAY,
163 _reg_PHY_CLK_WRDQ2_SLAVE_DELAY,
164 _reg_PHY_CLK_WRDQ3_SLAVE_DELAY,
165 _reg_PHY_CLK_WRDQ4_SLAVE_DELAY,
166 _reg_PHY_CLK_WRDQ5_SLAVE_DELAY,
167 _reg_PHY_CLK_WRDQ6_SLAVE_DELAY,
168 _reg_PHY_CLK_WRDQ7_SLAVE_DELAY,
169 _reg_PHY_CLK_WRDM_SLAVE_DELAY,
170 _reg_PHY_CLK_WRDQS_SLAVE_DELAY
171};
172
173#define _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM 9
174static const uint32_t
175 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[_reg_PHY_RDDQS_X_FALL_SLAVE_DELAY_NUM] = {
176 _reg_PHY_RDDQS_DQ0_FALL_SLAVE_DELAY,
177 _reg_PHY_RDDQS_DQ1_FALL_SLAVE_DELAY,
178 _reg_PHY_RDDQS_DQ2_FALL_SLAVE_DELAY,
179 _reg_PHY_RDDQS_DQ3_FALL_SLAVE_DELAY,
180 _reg_PHY_RDDQS_DQ4_FALL_SLAVE_DELAY,
181 _reg_PHY_RDDQS_DQ5_FALL_SLAVE_DELAY,
182 _reg_PHY_RDDQS_DQ6_FALL_SLAVE_DELAY,
183 _reg_PHY_RDDQS_DQ7_FALL_SLAVE_DELAY,
184 _reg_PHY_RDDQS_DM_FALL_SLAVE_DELAY
185};
186
187#define _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM 9
188static const uint32_t
189 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[_reg_PHY_RDDQS_X_RISE_SLAVE_DELAY_NUM] = {
190 _reg_PHY_RDDQS_DQ0_RISE_SLAVE_DELAY,
191 _reg_PHY_RDDQS_DQ1_RISE_SLAVE_DELAY,
192 _reg_PHY_RDDQS_DQ2_RISE_SLAVE_DELAY,
193 _reg_PHY_RDDQS_DQ3_RISE_SLAVE_DELAY,
194 _reg_PHY_RDDQS_DQ4_RISE_SLAVE_DELAY,
195 _reg_PHY_RDDQS_DQ5_RISE_SLAVE_DELAY,
196 _reg_PHY_RDDQS_DQ6_RISE_SLAVE_DELAY,
197 _reg_PHY_RDDQS_DQ7_RISE_SLAVE_DELAY,
198 _reg_PHY_RDDQS_DM_RISE_SLAVE_DELAY
199};
200
201#define _reg_PHY_PAD_TERM_X_NUM 8
202static const uint32_t _reg_PHY_PAD_TERM_X[_reg_PHY_PAD_TERM_X_NUM] = {
203 _reg_PHY_PAD_FDBK_TERM,
204 _reg_PHY_PAD_DATA_TERM,
205 _reg_PHY_PAD_DQS_TERM,
206 _reg_PHY_PAD_ADDR_TERM,
207 _reg_PHY_PAD_CLK_TERM,
208 _reg_PHY_PAD_CKE_TERM,
209 _reg_PHY_PAD_RST_TERM,
210 _reg_PHY_PAD_CS_TERM
211};
212
213#define _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM 10
214static const uint32_t
215 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[_reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM] = {
216 _reg_PHY_ADR0_CLK_WR_SLAVE_DELAY,
217 _reg_PHY_ADR1_CLK_WR_SLAVE_DELAY,
218 _reg_PHY_ADR2_CLK_WR_SLAVE_DELAY,
219 _reg_PHY_ADR3_CLK_WR_SLAVE_DELAY,
220 _reg_PHY_ADR4_CLK_WR_SLAVE_DELAY,
221 _reg_PHY_ADR5_CLK_WR_SLAVE_DELAY,
222
223 _reg_PHY_GRP_SLAVE_DELAY_0,
224 _reg_PHY_GRP_SLAVE_DELAY_1,
225 _reg_PHY_GRP_SLAVE_DELAY_2,
226 _reg_PHY_GRP_SLAVE_DELAY_3
227};
228
229/*******************************************************************************
230 * Prototypes
231 ******************************************************************************/
232static inline int32_t vch_nxt(int32_t pos);
233static void cpg_write_32(uint32_t a, uint32_t v);
234static void pll3_control(uint32_t high);
235static inline void dsb_sev(void);
236static void wait_dbcmd(void);
237static void send_dbcmd(uint32_t cmd);
238static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd);
239static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata);
240static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata);
241static inline uint32_t ddr_regdef(uint32_t _regdef);
242static inline uint32_t ddr_regdef_adr(uint32_t _regdef);
243static inline uint32_t ddr_regdef_lsb(uint32_t _regdef);
244static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef,
245 uint32_t val);
246static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef);
247static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val);
248static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val);
249static void ddr_setval_ach(uint32_t regdef, uint32_t val);
250static void ddr_setval_ach_as(uint32_t regdef, uint32_t val);
251static uint32_t ddr_getval(uint32_t ch, uint32_t regdef);
252static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t * p);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200253static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t * p);
254static void _tblcopy(uint32_t * to, const uint32_t * from, uint32_t size);
255static void ddrtbl_setval(uint32_t * tbl, uint32_t _regdef, uint32_t val);
256static uint32_t ddrtbl_getval(uint32_t * tbl, uint32_t _regdef);
257static uint32_t ddrphy_regif_chk(void);
258static inline void ddrphy_regif_idle();
259static uint16_t _f_scale(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv, uint32_t ps,
260 uint16_t cyc);
261static void _f_scale_js2(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv,
262 uint16_t * js2);
263static int16_t _f_scale_adj(int16_t ps);
264static void ddrtbl_load(void);
265static void ddr_config_sub(void);
266static void get_ca_swizzle(uint32_t ch, uint32_t ddr_csn, uint32_t * p_swz);
267static void ddr_config_sub_h3v1x(void);
268static void ddr_config(void);
269static void dbsc_regset(void);
270static void dbsc_regset_post(void);
271static uint32_t dfi_init_start(void);
272static void change_lpddr4_en(uint32_t mode);
273static uint32_t set_term_code(void);
Marek Vasut6c245a52018-12-12 18:06:39 +0100274static void ddr_register_set(void);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200275static inline uint32_t wait_freqchgreq(uint32_t assert);
276static inline void set_freqchgack(uint32_t assert);
277static inline void set_dfifrequency(uint32_t freq);
278static uint32_t pll3_freq(uint32_t on);
279static void update_dly(void);
280static uint32_t pi_training_go(void);
281static uint32_t init_ddr(void);
282static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200283static uint32_t wdqdm_man1(void);
284static uint32_t wdqdm_man(void);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200285static uint32_t rdqdm_man1(void);
286static uint32_t rdqdm_man(void);
287
288static int32_t _find_change(uint64_t val, uint32_t dir);
289static uint32_t _rx_offset_cal_updn(uint32_t code);
290static uint32_t rx_offset_cal(void);
291static uint32_t rx_offset_cal_hw(void);
292static void adjust_rddqs_latency(void);
293static void adjust_wpath_latency(void);
294
295struct DdrtData {
296 int32_t init_temp; /* Initial Temperature (do) */
297 uint32_t init_cal[4]; /* Initial io-code (4 is for H3) */
298 uint32_t tcomp_cal[4]; /* Temperature compensated io-code (4 is for H3) */
299};
300struct DdrtData tcal;
301
302static void pvtcode_update(void);
303static void pvtcode_update2(void);
304static void ddr_padcal_tcompensate_getinit(uint32_t override);
305
306/*******************************************************************************
307 * load board configuration
308 ******************************************************************************/
309#include "boot_init_dram_config.c"
310
Marek Vasut6c245a52018-12-12 18:06:39 +0100311#ifndef DDR_FAST_INIT
312static uint32_t rdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2][9];
313static uint32_t rdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2][9];
314static uint32_t rdqdm_nw[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2][9];
315static uint32_t rdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
316static uint32_t rdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2];
317static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn);
318static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn);
319
320static uint32_t wdqdm_le[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9];
321static uint32_t wdqdm_te[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9];
322static uint32_t wdqdm_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT][9];
323static uint32_t wdqdm_st[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
324static uint32_t wdqdm_win[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
325static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn);
326static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn);
327#endif/* DDR_FAST_INIT */
328
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200329/*******************************************************************************
330 * macro for channel selection loop
331 ******************************************************************************/
332static inline int32_t vch_nxt(int32_t pos)
333{
334 int32_t posn;
335
336 for (posn = pos; posn < DRAM_CH_CNT; posn++) {
337 if (ddr_phyvalid & (1U << posn))
338 break;
339 }
340 return posn;
341}
342
343#define foreach_vch(ch) \
344for(ch=vch_nxt(0);ch<DRAM_CH_CNT;ch=vch_nxt(ch+1))
345
346#define foreach_ech(ch) \
347for(ch=0;ch<DRAM_CH_CNT;ch++)
348
349/*******************************************************************************
350 * Printing functions
351 ******************************************************************************/
352#define MSG_LF(...)
353
354/*******************************************************************************
355 * clock settings, reset control
356 ******************************************************************************/
357static void cpg_write_32(uint32_t a, uint32_t v)
358{
359 mmio_write_32(CPG_CPGWPR, ~v);
360 mmio_write_32(a, v);
361}
362
363static void pll3_control(uint32_t high)
364{
365 uint32_t dataL, dataDIV, dataMUL, tmpDIV;
366
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200367 if (high) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200368 tmpDIV =
369 (1000 * ddr_mbpsdiv * brd_clkdiv * (brd_clkdiva + 1)) /
370 (ddr_mul * brd_clk * ddr_mbpsdiv + 1);
371 dataMUL =
Marek Vasut6c245a52018-12-12 18:06:39 +0100372 (ddr_mul * (tmpDIV + 1) - 1) << 24;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200373 Pll3Mode = 1;
374 loop_max = 2;
375 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200376 tmpDIV =
377 (1000 * ddr_mbpsdiv * brd_clkdiv * (brd_clkdiva + 1)) /
378 (ddr0800_mul * brd_clk * ddr_mbpsdiv + 1);
379 dataMUL =
Marek Vasut6c245a52018-12-12 18:06:39 +0100380 (ddr0800_mul * (tmpDIV + 1) - 1) << 24;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200381 Pll3Mode = 0;
382 loop_max = 8;
383 }
Marek Vasut6c245a52018-12-12 18:06:39 +0100384 if (tmpDIV) {
385 dataDIV = tmpDIV + 1;
386 } else {
387 dataDIV = 0;
388 }
389 dataMUL = dataMUL | (brd_clkdiva << 7);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200390
Marek Vasut6c245a52018-12-12 18:06:39 +0100391 /* PLL3 disable */
392 dataL = mmio_read_32(CPG_PLLECR) & ~CPG_PLLECR_PLL3E_BIT;
393 cpg_write_32(CPG_PLLECR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200394 dsb_sev();
395
Marek Vasut6c245a52018-12-12 18:06:39 +0100396 if ((Prr_Product == PRR_PRODUCT_M3) ||
397 ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_20))) {
398 /* PLL3 DIV resetting(Lowest value:3) */
399 dataL = 0x00030003 | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
400 cpg_write_32(CPG_FRQCRD, dataL);
401 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200402
Marek Vasut6c245a52018-12-12 18:06:39 +0100403 /* zb3 clk stop */
404 dataL = CPG_ZB3CKCR_ZB3ST_BIT | mmio_read_32(CPG_ZB3CKCR);
405 cpg_write_32(CPG_ZB3CKCR, dataL);
406 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200407
Marek Vasut6c245a52018-12-12 18:06:39 +0100408 /* PLL3 enable */
409 dataL = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR);
410 cpg_write_32(CPG_PLLECR, dataL);
411 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200412
Marek Vasut6c245a52018-12-12 18:06:39 +0100413 do {
414 dataL = mmio_read_32(CPG_PLLECR);
415 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
416 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200417
Marek Vasut6c245a52018-12-12 18:06:39 +0100418 /* PLL3 DIV resetting (Highest value:0) */
419 dataL = (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
420 cpg_write_32(CPG_FRQCRD, dataL);
421 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200422
Marek Vasut6c245a52018-12-12 18:06:39 +0100423 /* DIV SET KICK */
424 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
425 cpg_write_32(CPG_FRQCRB, dataL);
426 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200427
Marek Vasut6c245a52018-12-12 18:06:39 +0100428 /* PLL3 multiplie set */
429 cpg_write_32(CPG_PLL3CR, dataMUL);
430 dsb_sev();
431
432 do {
433 dataL = mmio_read_32(CPG_PLLECR);
434 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
435 dsb_sev();
436
437 /* PLL3 DIV resetting(Target value) */
438 dataL = (dataDIV << 16) | dataDIV | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
439 cpg_write_32(CPG_FRQCRD, dataL);
440 dsb_sev();
441
442 /* DIV SET KICK */
443 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
444 cpg_write_32(CPG_FRQCRB, dataL);
445 dsb_sev();
446
447 do {
448 dataL = mmio_read_32(CPG_PLLECR);
449 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
450 dsb_sev();
451
452 /* zb3 clk start */
453 dataL = (~CPG_ZB3CKCR_ZB3ST_BIT) & mmio_read_32(CPG_ZB3CKCR);
454 cpg_write_32(CPG_ZB3CKCR, dataL);
455 dsb_sev();
456
457 } else { /* H3Ver.3.0/M3N/V3H */
458
459 /* PLL3 multiplie set */
460 cpg_write_32(CPG_PLL3CR, dataMUL);
461 dsb_sev();
462
463 /* PLL3 DIV set(Target value) */
464 dataL = (dataDIV << 16) | dataDIV | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
465 cpg_write_32(CPG_FRQCRD, dataL);
466
467 /* DIV SET KICK */
468 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
469 cpg_write_32(CPG_FRQCRB, dataL);
470 dsb_sev();
471
472 /* PLL3 enable */
473 dataL = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR);
474 cpg_write_32(CPG_PLLECR, dataL);
475 dsb_sev();
476
477 do {
478 dataL = mmio_read_32(CPG_PLLECR);
479 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
480 dsb_sev();
481 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200482
483 return;
484}
485
486/*******************************************************************************
487 * barrier
488 ******************************************************************************/
489static inline void dsb_sev(void)
490{
491 __asm__ __volatile__("dsb sy");
492}
493
494/*******************************************************************************
495 * DDR memory register access
496 ******************************************************************************/
497static void wait_dbcmd(void)
498{
499 uint32_t dataL;
500 /* dummy read */
501 dataL = mmio_read_32(DBSC_DBCMD);
502 dsb_sev();
503 while (1) {
504 /* wait DBCMD 1=busy, 0=ready */
505 dataL = mmio_read_32(DBSC_DBWAIT);
506 dsb_sev();
507 if ((dataL & 0x00000001) == 0x00)
508 break;
509 }
510}
511
512static void send_dbcmd(uint32_t cmd)
513{
514 /* dummy read */
515 wait_dbcmd();
516 mmio_write_32(DBSC_DBCMD, cmd);
517 dsb_sev();
518}
519
520/*******************************************************************************
521 * DDRPHY register access (raw)
522 ******************************************************************************/
523static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd)
524{
525 uint32_t val;
526 uint32_t loop;
527
528 val = 0;
529 if ((PRR_PRODUCT_M3N != Prr_Product)
530 && (PRR_PRODUCT_V3H != Prr_Product)) {
531 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
532 dsb_sev();
533
534 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
535 dsb_sev();
536 }
537 dsb_sev();
538
539 for (loop = 0; loop < loop_max; loop++) {
540 val = mmio_read_32(DBSC_DBPDRGD(phyno));
541 dsb_sev();
542 }
543 (void)val;
544 } else {
545 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00004000);
546 dsb_sev();
547 while (mmio_read_32(DBSC_DBPDRGA(phyno)) !=
548 (regadd | 0x0000C000)) {
549 dsb_sev();
550 };
551 val = mmio_read_32(DBSC_DBPDRGA(phyno));
552 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
553 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
554 dsb_sev();
555 };
556 dsb_sev();
557
558 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
559 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
560 dsb_sev();
561 };
562
563 dsb_sev();
564 val = mmio_read_32(DBSC_DBPDRGD(phyno));
565 dsb_sev();
566 (void)val;
567 }
568 return val;
569}
570
571static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata)
572{
573 uint32_t val;
574 uint32_t loop;
575
576 if ((PRR_PRODUCT_M3N != Prr_Product)
577 && (PRR_PRODUCT_V3H != Prr_Product)) {
578 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
579 dsb_sev();
580 for (loop = 0; loop < loop_max; loop++) {
581 val = mmio_read_32(DBSC_DBPDRGA(phyno));
582 dsb_sev();
583 }
584 mmio_write_32(DBSC_DBPDRGD(phyno), regdata);
585 dsb_sev();
586
587 for (loop = 0; loop < loop_max; loop++) {
588 val = mmio_read_32(DBSC_DBPDRGD(phyno));
589 dsb_sev();
590 }
591 } else {
592 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
593 dsb_sev();
594
595 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
596 dsb_sev();
597 };
598 dsb_sev();
599
600 mmio_write_32(DBSC_DBPDRGD(phyno), regdata);
601 dsb_sev();
602
603 while (mmio_read_32(DBSC_DBPDRGA(phyno)) !=
604 (regadd | 0x00008000)) {
605 dsb_sev();
606 };
607 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
608
609 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
610 dsb_sev();
611 };
612 dsb_sev();
613
614 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
615 }
616 (void)val;
617}
618
619static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata)
620{
621 uint32_t ch;
622 uint32_t val;
623 uint32_t loop;
624
625 if ((PRR_PRODUCT_M3N != Prr_Product)
626 && (PRR_PRODUCT_V3H != Prr_Product)) {
627 foreach_vch(ch) {
628 mmio_write_32(DBSC_DBPDRGA(ch), regadd);
629 dsb_sev();
630 }
631
632 foreach_vch(ch) {
633 mmio_write_32(DBSC_DBPDRGD(ch), regdata);
634 dsb_sev();
635 }
636
637 for (loop = 0; loop < loop_max; loop++) {
638 val = mmio_read_32(DBSC_DBPDRGD(0));
639 dsb_sev();
640 }
641 (void)val;
642 } else {
643 foreach_vch(ch) {
644 reg_ddrphy_write(ch, regadd, regdata);
645 dsb_sev();
646 }
647 }
648}
649
650static inline void ddrphy_regif_idle()
651{
652 uint32_t val;
653
654 val = reg_ddrphy_read(0, ddr_regdef_adr(_reg_PI_INT_STATUS));
655 dsb_sev();
656 (void)val;
657}
658
659/*******************************************************************************
660 * DDRPHY register access (field modify)
661 ******************************************************************************/
662static inline uint32_t ddr_regdef(uint32_t _regdef)
663{
664 return pDDR_REGDEF_TBL[_regdef];
665}
666
667static inline uint32_t ddr_regdef_adr(uint32_t _regdef)
668{
669 return DDR_REGDEF_ADR(pDDR_REGDEF_TBL[_regdef]);
670}
671
672static inline uint32_t ddr_regdef_lsb(uint32_t _regdef)
673{
674 return DDR_REGDEF_LSB(pDDR_REGDEF_TBL[_regdef]);
675}
676
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200677static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef,
678 uint32_t val)
679{
680 uint32_t adr;
681 uint32_t lsb;
682 uint32_t len;
683 uint32_t msk;
684 uint32_t tmp;
685 uint32_t regdef;
686
687 regdef = ddr_regdef(_regdef);
688 adr = DDR_REGDEF_ADR(regdef) + 0x80 * slice;
689 len = DDR_REGDEF_LEN(regdef);
690 lsb = DDR_REGDEF_LSB(regdef);
691 if (len == 0x20)
692 msk = 0xffffffff;
693 else
694 msk = ((1U << len) - 1) << lsb;
695
696 tmp = reg_ddrphy_read(ch, adr);
697 tmp = (tmp & (~msk)) | ((val << lsb) & msk);
698 reg_ddrphy_write(ch, adr, tmp);
699}
700
701static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef)
702{
703 uint32_t adr;
704 uint32_t lsb;
705 uint32_t len;
706 uint32_t msk;
707 uint32_t tmp;
708 uint32_t regdef;
709
710 regdef = ddr_regdef(_regdef);
711 adr = DDR_REGDEF_ADR(regdef) + 0x80 * slice;
712 len = DDR_REGDEF_LEN(regdef);
713 lsb = DDR_REGDEF_LSB(regdef);
714 if (len == 0x20)
715 msk = 0xffffffff;
716 else
717 msk = ((1U << len) - 1);
718
719 tmp = reg_ddrphy_read(ch, adr);
720 tmp = (tmp >> lsb) & msk;
721
722 return tmp;
723}
724
725static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val)
726{
727 ddr_setval_s(ch, 0, regdef, val);
728}
729
730static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val)
731{
732 uint32_t ch;
733
734 foreach_vch(ch)
735 ddr_setval_s(ch, slice, regdef, val);
736}
737
738static void ddr_setval_ach(uint32_t regdef, uint32_t val)
739{
740 ddr_setval_ach_s(0, regdef, val);
741}
742
743static void ddr_setval_ach_as(uint32_t regdef, uint32_t val)
744{
745 uint32_t slice;
746
747 for (slice = 0; slice < SLICE_CNT; slice++)
748 ddr_setval_ach_s(slice, regdef, val);
749}
750
751static uint32_t ddr_getval(uint32_t ch, uint32_t regdef)
752{
753 return ddr_getval_s(ch, 0, regdef);
754}
755
756static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t * p)
757{
758 uint32_t ch;
759
760 foreach_vch(ch)
761 p[ch] = ddr_getval_s(ch, 0, regdef);
762 return p[0];
763}
764
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200765static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t * p)
766{
767 uint32_t ch, slice;
768 uint32_t *pp;
769
770 pp = p;
771 foreach_vch(ch)
772 for (slice = 0; slice < SLICE_CNT; slice++)
773 *pp++ = ddr_getval_s(ch, slice, regdef);
774 return p[0];
775}
776
777/*******************************************************************************
778 * handling functions for setteing ddrphy value table
779 ******************************************************************************/
780static void _tblcopy(uint32_t * to, const uint32_t * from, uint32_t size)
781{
782 uint32_t i;
783
784 for (i = 0; i < size; i++) {
785 to[i] = from[i];
786 }
787}
788
789static void ddrtbl_setval(uint32_t * tbl, uint32_t _regdef, uint32_t val)
790{
791 uint32_t adr;
792 uint32_t lsb;
793 uint32_t len;
794 uint32_t msk;
795 uint32_t tmp;
796 uint32_t adrmsk;
797 uint32_t regdef;
798
799 regdef = ddr_regdef(_regdef);
800 adr = DDR_REGDEF_ADR(regdef);
801 len = DDR_REGDEF_LEN(regdef);
802 lsb = DDR_REGDEF_LSB(regdef);
803 if (len == 0x20)
804 msk = 0xffffffff;
805 else
806 msk = ((1U << len) - 1) << lsb;
807
808 if (adr < 0x400) {
809 adrmsk = 0xff;
810 } else {
811 adrmsk = 0x7f;
812 }
813
814 tmp = tbl[adr & adrmsk];
815 tmp = (tmp & (~msk)) | ((val << lsb) & msk);
816 tbl[adr & adrmsk] = tmp;
817}
818
819static uint32_t ddrtbl_getval(uint32_t * tbl, uint32_t _regdef)
820{
821 uint32_t adr;
822 uint32_t lsb;
823 uint32_t len;
824 uint32_t msk;
825 uint32_t tmp;
826 uint32_t adrmsk;
827 uint32_t regdef;
828
829 regdef = ddr_regdef(_regdef);
830 adr = DDR_REGDEF_ADR(regdef);
831 len = DDR_REGDEF_LEN(regdef);
832 lsb = DDR_REGDEF_LSB(regdef);
833 if (len == 0x20)
834 msk = 0xffffffff;
835 else
836 msk = ((1U << len) - 1);
837
838 if (adr < 0x400) {
839 adrmsk = 0xff;
840 } else {
841 adrmsk = 0x7f;
842 }
843
844 tmp = tbl[adr & adrmsk];
845 tmp = (tmp >> lsb) & msk;
846
847 return tmp;
848}
849
850/*******************************************************************************
851 * DDRPHY register access handling
852 ******************************************************************************/
853static uint32_t ddrphy_regif_chk(void)
854{
855 uint32_t tmp_ach[DRAM_CH_CNT];
856 uint32_t ch;
857 uint32_t err;
858 uint32_t PI_VERSION_CODE;
859
860 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
861 || (Prr_Product == PRR_PRODUCT_M3)) {
862 PI_VERSION_CODE = 0x2041; /* H3 Ver.1.x/M3-W */
863 } else {
864 PI_VERSION_CODE = 0x2040; /* H3 Ver.2.0 or later/M3-N/V3H */
865 }
866
867 ddr_getval_ach(_reg_PI_VERSION, (uint32_t *) tmp_ach);
868 err = 0;
869 foreach_vch(ch) {
870 if (PI_VERSION_CODE != tmp_ach[ch])
871 err = 1;
872 }
873 return err;
874}
875
876/*******************************************************************************
877 * functions and parameters for timing setting
878 ******************************************************************************/
879struct _jedec_spec1 {
880 uint16_t fx3;
881 uint8_t RLwoDBI;
882 uint8_t RLwDBI;
883 uint8_t WL;
884 uint8_t nWR;
885 uint8_t nRTP;
886 uint8_t MR1;
887 uint8_t MR2;
888};
889#define JS1_USABLEC_SPEC_LO 2
890#define JS1_USABLEC_SPEC_HI 5
891#define JS1_FREQ_TBL_NUM 8
892#define JS1_MR1(f) (0x04 | ((f)<<4))
893#define JS1_MR2(f) (0x00 | ((f)<<3) | (f))
894const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
895/*A { 800, 6, 6, 4, 6 , 8, JS1_MR1(0), JS1_MR2(0) }, 533.333Mbps*/
896/*A { 1600, 10, 12, 6, 10 , 8, JS1_MR1(1), JS1_MR2(1) }, 1066.666Mbps*/
897/*A { 2400, 14, 16, 8, 16 , 8, JS1_MR1(2), JS1_MR2(2) }, 1600.000Mbps*/
898 /*B*/ {800, 6, 6, 4, 6, 8, JS1_MR1(0), JS1_MR2(0) | 0x40}, /* 533.333Mbps */
899 /*B*/ {1600, 10, 12, 8, 10, 8, JS1_MR1(1), JS1_MR2(1) | 0x40}, /* 1066.666Mbps */
900 /*B*/ {2400, 14, 16, 12, 16, 8, JS1_MR1(2), JS1_MR2(2) | 0x40}, /* 1600.000Mbps */
901 /*A*/ {3200, 20, 22, 10, 20, 8, JS1_MR1(3), JS1_MR2(3)}, /* 2133.333Mbps */
902 /*A*/ {4000, 24, 28, 12, 24, 10, JS1_MR1(4), JS1_MR2(4)}, /* 2666.666Mbps */
903 /*A*/ {4800, 28, 32, 14, 30, 12, JS1_MR1(5), JS1_MR2(5)}, /* 3200.000Mbps */
904 /*A*/ {5600, 32, 36, 16, 34, 14, JS1_MR1(6), JS1_MR2(6)}, /* 3733.333Mbps */
905 /*A*/ {6400, 36, 40, 18, 40, 16, JS1_MR1(7), JS1_MR2(7)} /* 4266.666Mbps */
906};
907
908struct _jedec_spec2 {
909 uint16_t ps;
910 uint16_t cyc;
911};
912
913#define JS2_tSR 0
914#define JS2_tXP 1
915#define JS2_tRTP 2
916#define JS2_tRCD 3
917#define JS2_tRPpb 4
918#define JS2_tRPab 5
919#define JS2_tRAS 6
920#define JS2_tWR 7
921#define JS2_tWTR 8
922#define JS2_tRRD 9
923#define JS2_tPPD 10
924#define JS2_tFAW 11
925#define JS2_tDQSCK 12
926#define JS2_tCKEHCMD 13
927#define JS2_tCKELCMD 14
928#define JS2_tCKELPD 15
929#define JS2_tMRR 16
930#define JS2_tMRW 17
931#define JS2_tMRD 18
932#define JS2_tZQCALns 19
933#define JS2_tZQLAT 20
934#define JS2_tIEdly 21
935#define JS2_TBLCNT 22
936
937#define JS2_tRCpb (JS2_TBLCNT)
938#define JS2_tRCab (JS2_TBLCNT+1)
Marek Vasut6c245a52018-12-12 18:06:39 +0100939#define JS2_tRFCab (JS2_TBLCNT+2)
940#define JS2_CNT (JS2_TBLCNT+3)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200941
942#ifndef JS2_DERATE
943#define JS2_DERATE 0
944#endif
945const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = {
946 {
947/*tSR */ {15000, 3},
948/*tXP */ {7500, 3},
949/*tRTP */ {7500, 8},
950/*tRCD */ {18000, 4},
951/*tRPpb */ {18000, 3},
952/*tRPab */ {21000, 3},
953/*tRAS */ {42000, 3},
954/*tWR */ {18000, 4},
955/*tWTR */ {10000, 8},
956/*tRRD */ {10000, 4},
957/*tPPD */ {0, 0},
958/*tFAW */ {40000, 0},
959/*tDQSCK*/ {3500, 0},
960/*tCKEHCMD*/ {7500, 3},
961/*tCKELCMD*/ {7500, 3},
962/*tCKELPD*/ {7500, 3},
963/*tMRR*/ {0, 8},
964/*tMRW*/ {10000, 10},
965/*tMRD*/ {14000, 10},
966/*tZQCALns*/ {1000 * 10, 0},
967/*tZQLAT*/ {30000, 10},
968/*tIEdly*/ {12500, 0}
969 }, {
970/*tSR */ {15000, 3},
971/*tXP */ {7500, 3},
972/*tRTP */ {7500, 8},
973/*tRCD */ {19875, 4},
974/*tRPpb */ {19875, 3},
975/*tRPab */ {22875, 3},
976/*tRAS */ {43875, 3},
977/*tWR */ {18000, 4},
978/*tWTR */ {10000, 8},
979/*tRRD */ {11875, 4},
980/*tPPD */ {0, 0},
981/*tFAW */ {40000, 0},
982/*tDQSCK*/ {3600, 0},
983/*tCKEHCMD*/ {7500, 3},
984/*tCKELCMD*/ {7500, 3},
985/*tCKELPD*/ {7500, 3},
986/*tMRR*/ {0, 8},
987/*tMRW*/ {10000, 10},
988/*tMRD*/ {14000, 10},
989/*tZQCALns*/ {1000 * 10, 0},
990/*tZQLAT*/ {30000, 10},
991/*tIEdly*/ {12500, 0}
992 }
993};
994
Marek Vasut6c245a52018-12-12 18:06:39 +0100995const uint16_t jedec_spec2_tRFC_ab[7] = {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200996/* 4Gb, 6Gb, 8Gb,12Gb, 16Gb, 24Gb(non), 32Gb(non) */
Marek Vasut6c245a52018-12-12 18:06:39 +0100997 130, 180, 180, 280, 280, 560, 560
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200998};
999
1000static uint32_t js1_ind;
1001static uint16_t js2[JS2_CNT];
1002static uint8_t RL;
1003static uint8_t WL;
1004
1005static uint16_t _f_scale(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv, uint32_t ps,
1006 uint16_t cyc)
1007{
1008 uint32_t tmp;
1009 uint32_t div;
1010
1011 tmp = (((uint32_t) (ps) + 9) / 10) * ddr_mbps;
1012 div = tmp / (200000 * ddr_mbpsdiv);
1013 if (tmp != (div * 200000 * ddr_mbpsdiv))
1014 div = div + 1;
1015
1016 if (div > cyc)
1017 return (uint16_t) div;
1018 return cyc;
1019}
1020
1021static void _f_scale_js2(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv,
1022 uint16_t * js2)
1023{
1024 int i;
1025
1026 for (i = 0; i < JS2_TBLCNT; i++) {
1027 js2[i] = _f_scale(ddr_mbps, ddr_mbpsdiv,
1028 1UL * jedec_spec2[JS2_DERATE][i].ps,
1029 jedec_spec2[JS2_DERATE][i].cyc);
1030 }
1031
1032 js2[JS2_tRCpb] = js2[JS2_tRAS] + js2[JS2_tRPpb];
1033 js2[JS2_tRCab] = js2[JS2_tRAS] + js2[JS2_tRPab];
1034}
1035
1036/* scaler for DELAY value */
1037static int16_t _f_scale_adj(int16_t ps)
1038{
1039 int32_t tmp;
1040 /*
1041 tmp = (int32_t)512 * ps * ddr_mbps /2 / ddr_mbpsdiv / 1000 / 1000;
1042 = ps * ddr_mbps /2 / ddr_mbpsdiv *512 / 8 / 8 / 125 / 125
1043 = ps * ddr_mbps / ddr_mbpsdiv *4 / 125 / 125
1044 */
1045 tmp =
1046 (int32_t) 4 *(int32_t) ps *(int32_t) ddr_mbps /
1047 (int32_t) ddr_mbpsdiv;
1048 tmp = (int32_t) tmp / (int32_t) 15625;
1049
1050 return (int16_t) tmp;
1051}
1052
1053const uint32_t _reg_PI_MR1_DATA_Fx_CSx[2][CSAB_CNT] = {
1054 {
1055 _reg_PI_MR1_DATA_F0_0,
1056 _reg_PI_MR1_DATA_F0_1,
1057 _reg_PI_MR1_DATA_F0_2,
1058 _reg_PI_MR1_DATA_F0_3},
1059 {
1060 _reg_PI_MR1_DATA_F1_0,
1061 _reg_PI_MR1_DATA_F1_1,
1062 _reg_PI_MR1_DATA_F1_2,
1063 _reg_PI_MR1_DATA_F1_3}
1064};
1065
1066const uint32_t _reg_PI_MR2_DATA_Fx_CSx[2][CSAB_CNT] = {
1067 {
1068 _reg_PI_MR2_DATA_F0_0,
1069 _reg_PI_MR2_DATA_F0_1,
1070 _reg_PI_MR2_DATA_F0_2,
1071 _reg_PI_MR2_DATA_F0_3},
1072 {
1073 _reg_PI_MR2_DATA_F1_0,
1074 _reg_PI_MR2_DATA_F1_1,
1075 _reg_PI_MR2_DATA_F1_2,
1076 _reg_PI_MR2_DATA_F1_3}
1077};
1078
1079const uint32_t _reg_PI_MR3_DATA_Fx_CSx[2][CSAB_CNT] = {
1080 {
1081 _reg_PI_MR3_DATA_F0_0,
1082 _reg_PI_MR3_DATA_F0_1,
1083 _reg_PI_MR3_DATA_F0_2,
1084 _reg_PI_MR3_DATA_F0_3},
1085 {
1086 _reg_PI_MR3_DATA_F1_0,
1087 _reg_PI_MR3_DATA_F1_1,
1088 _reg_PI_MR3_DATA_F1_2,
1089 _reg_PI_MR3_DATA_F1_3}
1090};
1091
1092const uint32_t _reg_PI_MR11_DATA_Fx_CSx[2][CSAB_CNT] = {
1093 {
1094 _reg_PI_MR11_DATA_F0_0,
1095 _reg_PI_MR11_DATA_F0_1,
1096 _reg_PI_MR11_DATA_F0_2,
1097 _reg_PI_MR11_DATA_F0_3},
1098 {
1099 _reg_PI_MR11_DATA_F1_0,
1100 _reg_PI_MR11_DATA_F1_1,
1101 _reg_PI_MR11_DATA_F1_2,
1102 _reg_PI_MR11_DATA_F1_3}
1103};
1104
1105const uint32_t _reg_PI_MR12_DATA_Fx_CSx[2][CSAB_CNT] = {
1106 {
1107 _reg_PI_MR12_DATA_F0_0,
1108 _reg_PI_MR12_DATA_F0_1,
1109 _reg_PI_MR12_DATA_F0_2,
1110 _reg_PI_MR12_DATA_F0_3},
1111 {
1112 _reg_PI_MR12_DATA_F1_0,
1113 _reg_PI_MR12_DATA_F1_1,
1114 _reg_PI_MR12_DATA_F1_2,
1115 _reg_PI_MR12_DATA_F1_3}
1116};
1117
1118const uint32_t _reg_PI_MR14_DATA_Fx_CSx[2][CSAB_CNT] = {
1119 {
1120 _reg_PI_MR14_DATA_F0_0,
1121 _reg_PI_MR14_DATA_F0_1,
1122 _reg_PI_MR14_DATA_F0_2,
1123 _reg_PI_MR14_DATA_F0_3},
1124 {
1125 _reg_PI_MR14_DATA_F1_0,
1126 _reg_PI_MR14_DATA_F1_1,
1127 _reg_PI_MR14_DATA_F1_2,
1128 _reg_PI_MR14_DATA_F1_3}
1129};
1130
1131/*******************************************************************************
1132 * regif pll w/a ( REGIF H3 Ver.2.0 or later/M3-N/V3H WA )
1133 *******************************************************************************/
1134static void regif_pll_wa(void)
1135{
1136 uint32_t ch;
1137
1138 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1139 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT),
1140 (0x0064U <<
1141 ddr_regdef_lsb(_reg_PHY_PLL_WAIT)));
1142 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL),
1143 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1144 _reg_PHY_PLL_CTRL));
1145
1146 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL),
1147 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1148 _reg_PHY_LP4_BOOT_PLL_CTRL));
1149
1150 } else {
1151 /* PLL setting for PHY : M3-W/M3-N/V3H/H3 Ver.2.0 or later */
1152 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT),
1153 (0x5064U <<
1154 ddr_regdef_lsb(_reg_PHY_PLL_WAIT)));
1155
1156 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL),
1157 (ddrtbl_getval
1158 (_cnf_DDR_PHY_ADR_G_REGSET,
1159 _reg_PHY_PLL_CTRL_TOP) << 16) |
1160 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1161 _reg_PHY_PLL_CTRL));
1162 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL_CA),
1163 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1164 _reg_PHY_PLL_CTRL_CA));
1165
1166 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL),
1167 (ddrtbl_getval
1168 (_cnf_DDR_PHY_ADR_G_REGSET,
1169 _reg_PHY_LP4_BOOT_PLL_CTRL_CA) << 16) |
1170 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1171 _reg_PHY_LP4_BOOT_PLL_CTRL));
1172 reg_ddrphy_write_a(ddr_regdef_adr
1173 (_reg_PHY_LP4_BOOT_TOP_PLL_CTRL),
1174 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1175 _reg_PHY_LP4_BOOT_TOP_PLL_CTRL));
1176 }
1177
1178 /* protect register interface */
1179 ddrphy_regif_idle();
1180 pll3_control(0);
1181
1182 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1183 /* non */
1184 } else {
1185 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_DLL_RST_EN),
1186 (0x01U <<
1187 ddr_regdef_lsb(_reg_PHY_DLL_RST_EN)));
1188 ddrphy_regif_idle();
1189 }
1190
1191 /***********************************************************************
1192 init start
1193 ***********************************************************************/
1194 /* dbdficnt0:
1195 * dfi_dram_clk_disable=1
1196 * dfi_frequency = 0
1197 * freq_ratio = 01 (2:1)
1198 * init_start =0
1199 */
1200 foreach_vch(ch)
1201 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10);
1202 dsb_sev();
1203
1204 /* dbdficnt0:
1205 * dfi_dram_clk_disable=1
1206 * dfi_frequency = 0
1207 * freq_ratio = 01 (2:1)
1208 * init_start =1
1209 */
1210 foreach_vch(ch)
1211 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11);
1212 dsb_sev();
1213
1214 foreach_ech(ch)
1215 if (((Boardcnf->phyvalid) & (1U << ch)))
1216 while ((mmio_read_32(DBSC_PLL_LOCK(ch)) & 0x1f) != 0x1f) ;
1217 dsb_sev();
1218}
1219
1220/*******************************************************************************
1221 * load table data into DDR registers
1222 ******************************************************************************/
1223static void ddrtbl_load(void)
1224{
1225 int i;
1226 uint32_t slice;
1227 uint32_t csab;
1228 uint32_t adr;
1229 uint32_t dataL;
1230 uint32_t tmp[3];
1231 uint16_t dataS;
1232
1233 /***********************************************************************
1234 TIMING REGISTERS
1235 ***********************************************************************/
1236 /* search jedec_spec1 index */
1237 for (i = JS1_USABLEC_SPEC_LO; i < JS1_FREQ_TBL_NUM - 1; i++) {
1238 if (js1[i].fx3 * 2 * ddr_mbpsdiv >= ddr_mbps * 3)
1239 break;
1240 }
1241 if (JS1_USABLEC_SPEC_HI < i)
1242 js1_ind = JS1_USABLEC_SPEC_HI;
1243 else
1244 js1_ind = i;
1245
1246 if (Boardcnf->dbi_en)
1247 RL = js1[js1_ind].RLwDBI;
1248 else
1249 RL = js1[js1_ind].RLwoDBI;
1250
1251 WL = js1[js1_ind].WL;
1252
1253 /* calculate jedec_spec2 */
1254 _f_scale_js2(ddr_mbps, ddr_mbpsdiv, js2);
1255
1256 /***********************************************************************
1257 PREPARE TBL
1258 ***********************************************************************/
1259 if (Prr_Product == PRR_PRODUCT_H3) {
1260 if (Prr_Cut <= PRR_PRODUCT_11) {
1261 /* H3 Ver.1.x */
1262 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1263 DDR_PHY_SLICE_REGSET_H3,
1264 DDR_PHY_SLICE_REGSET_NUM_H3);
1265 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1266 DDR_PHY_ADR_V_REGSET_H3,
1267 DDR_PHY_ADR_V_REGSET_NUM_H3);
1268 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET,
1269 DDR_PHY_ADR_I_REGSET_H3,
1270 DDR_PHY_ADR_I_REGSET_NUM_H3);
1271 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1272 DDR_PHY_ADR_G_REGSET_H3,
1273 DDR_PHY_ADR_G_REGSET_NUM_H3);
1274 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_H3,
1275 DDR_PI_REGSET_NUM_H3);
1276
1277 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_H3;
1278 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_H3;
1279 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_H3;
1280 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_H3;
1281 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_H3;
1282 DDR_PHY_SLICE_REGSET_SIZE =
1283 DDR_PHY_SLICE_REGSET_SIZE_H3;
1284 DDR_PHY_ADR_V_REGSET_SIZE =
1285 DDR_PHY_ADR_V_REGSET_SIZE_H3;
1286 DDR_PHY_ADR_I_REGSET_SIZE =
1287 DDR_PHY_ADR_I_REGSET_SIZE_H3;
1288 DDR_PHY_ADR_G_REGSET_SIZE =
1289 DDR_PHY_ADR_G_REGSET_SIZE_H3;
1290 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_H3;
1291 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_H3;
1292 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_H3;
1293 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_H3;
1294 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_H3;
1295 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_H3;
1296
1297 DDR_PHY_ADR_I_NUM = 1;
1298 } else {
1299 /* H3 Ver.2.0 or later */
1300 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1301 DDR_PHY_SLICE_REGSET_H3VER2,
1302 DDR_PHY_SLICE_REGSET_NUM_H3VER2);
1303 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1304 DDR_PHY_ADR_V_REGSET_H3VER2,
1305 DDR_PHY_ADR_V_REGSET_NUM_H3VER2);
1306 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1307 DDR_PHY_ADR_G_REGSET_H3VER2,
1308 DDR_PHY_ADR_G_REGSET_NUM_H3VER2);
1309 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_H3VER2,
1310 DDR_PI_REGSET_NUM_H3VER2);
1311
1312 DDR_PHY_SLICE_REGSET_OFS =
1313 DDR_PHY_SLICE_REGSET_OFS_H3VER2;
1314 DDR_PHY_ADR_V_REGSET_OFS =
1315 DDR_PHY_ADR_V_REGSET_OFS_H3VER2;
1316 DDR_PHY_ADR_G_REGSET_OFS =
1317 DDR_PHY_ADR_G_REGSET_OFS_H3VER2;
1318 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_H3VER2;
1319 DDR_PHY_SLICE_REGSET_SIZE =
1320 DDR_PHY_SLICE_REGSET_SIZE_H3VER2;
1321 DDR_PHY_ADR_V_REGSET_SIZE =
1322 DDR_PHY_ADR_V_REGSET_SIZE_H3VER2;
1323 DDR_PHY_ADR_G_REGSET_SIZE =
1324 DDR_PHY_ADR_G_REGSET_SIZE_H3VER2;
1325 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_H3VER2;
1326 DDR_PHY_SLICE_REGSET_NUM =
1327 DDR_PHY_SLICE_REGSET_NUM_H3VER2;
1328 DDR_PHY_ADR_V_REGSET_NUM =
1329 DDR_PHY_ADR_V_REGSET_NUM_H3VER2;
1330 DDR_PHY_ADR_G_REGSET_NUM =
1331 DDR_PHY_ADR_G_REGSET_NUM_H3VER2;
1332 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_H3VER2;
1333
1334 DDR_PHY_ADR_I_NUM = 0;
1335 }
1336 } else if (Prr_Product == PRR_PRODUCT_M3) {
1337 /* M3-W */
1338 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1339 DDR_PHY_SLICE_REGSET_M3, DDR_PHY_SLICE_REGSET_NUM_M3);
1340 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1341 DDR_PHY_ADR_V_REGSET_M3, DDR_PHY_ADR_V_REGSET_NUM_M3);
1342 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET,
1343 DDR_PHY_ADR_I_REGSET_M3, DDR_PHY_ADR_I_REGSET_NUM_M3);
1344 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1345 DDR_PHY_ADR_G_REGSET_M3, DDR_PHY_ADR_G_REGSET_NUM_M3);
1346 _tblcopy(_cnf_DDR_PI_REGSET,
1347 DDR_PI_REGSET_M3, DDR_PI_REGSET_NUM_M3);
1348
1349 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_M3;
1350 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_M3;
1351 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_M3;
1352 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_M3;
1353 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_M3;
1354 DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_M3;
1355 DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_M3;
1356 DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_M3;
1357 DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_M3;
1358 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_M3;
1359 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_M3;
1360 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_M3;
1361 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_M3;
1362 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_M3;
1363 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_M3;
1364
1365 DDR_PHY_ADR_I_NUM = 2;
1366 } else {
1367 /* M3-N/V3H */
1368 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1369 DDR_PHY_SLICE_REGSET_M3N,
1370 DDR_PHY_SLICE_REGSET_NUM_M3N);
1371 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET, DDR_PHY_ADR_V_REGSET_M3N,
1372 DDR_PHY_ADR_V_REGSET_NUM_M3N);
1373 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET, DDR_PHY_ADR_I_REGSET_M3N,
1374 DDR_PHY_ADR_I_REGSET_NUM_M3N);
1375 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET, DDR_PHY_ADR_G_REGSET_M3N,
1376 DDR_PHY_ADR_G_REGSET_NUM_M3N);
1377 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_M3N,
1378 DDR_PI_REGSET_NUM_M3N);
1379
1380 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_M3N;
1381 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_M3N;
1382 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_M3N;
1383 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_M3N;
1384 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_M3N;
1385 DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_M3N;
1386 DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_M3N;
1387 DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_M3N;
1388 DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_M3N;
1389 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_M3N;
1390 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_M3N;
1391 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_M3N;
1392 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_M3N;
1393 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_M3N;
1394 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_M3N;
1395
1396 DDR_PHY_ADR_I_NUM = 2;
1397 }
1398
1399 /***********************************************************************
1400 PLL CODE CHANGE
1401 ***********************************************************************/
1402 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_11)) {
1403 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, _reg_PHY_PLL_CTRL,
1404 0x1142);
1405 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET,
1406 _reg_PHY_LP4_BOOT_PLL_CTRL, 0x1142);
1407 }
1408
1409 /***********************************************************************
1410 on fly gate adjust
1411 ***********************************************************************/
1412 if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut == PRR_PRODUCT_10)) {
1413 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1414 _reg_ON_FLY_GATE_ADJUST_EN, 0x00);
1415 }
1416
1417 /***********************************************************************
Marek Vasut6c245a52018-12-12 18:06:39 +01001418 Adjust PI parameters
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001419 ***********************************************************************/
1420#ifdef _def_LPDDR4_ODT
Marek Vasut6c245a52018-12-12 18:06:39 +01001421 for (i = 0; i < 2; i++) {
1422 for (csab = 0; csab < CSAB_CNT; csab++) {
1423 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1424 _reg_PI_MR11_DATA_Fx_CSx[i][csab],
1425 _def_LPDDR4_ODT);
1426 }
1427 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001428#endif /* _def_LPDDR4_ODT */
1429
1430#ifdef _def_LPDDR4_VREFCA
Marek Vasut6c245a52018-12-12 18:06:39 +01001431 for (i = 0; i < 2; i++) {
1432 for (csab = 0; csab < CSAB_CNT; csab++) {
1433 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1434 _reg_PI_MR12_DATA_Fx_CSx[i][csab],
1435 _def_LPDDR4_VREFCA);
1436 }
1437 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001438#endif /* _def_LPDDR4_VREFCA */
1439 if ((Prr_Product == PRR_PRODUCT_M3N)
1440 || (Prr_Product == PRR_PRODUCT_V3H)) {
1441 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 7000, 0) + 7;
1442 if (js2[JS2_tIEdly] > (RL))
1443 js2[JS2_tIEdly] = RL;
1444 } else if ((Prr_Product == PRR_PRODUCT_H3)
1445 && (Prr_Cut > PRR_PRODUCT_11)) {
1446 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 9000, 0) + 4;
1447 } else if ((Prr_Product == PRR_PRODUCT_H3)
1448 && (Prr_Cut <= PRR_PRODUCT_11)) {
1449 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 10000, 0);
1450 }
1451
1452 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
1453 || (Prr_Product == PRR_PRODUCT_M3N)
1454 || (Prr_Product == PRR_PRODUCT_V3H)) {
1455 if ((js2[JS2_tIEdly]) >= 0x1e)
1456 dataS = 0x1e;
1457 else
1458 dataS = js2[JS2_tIEdly];
1459 } else {
1460 if ((js2[JS2_tIEdly]) >= 0x0e)
1461 dataS = 0x0e;
1462 else
1463 dataS = js2[JS2_tIEdly];
1464 }
1465
1466 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_DLY, dataS);
1467 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_TSEL_DLY,
1468 (dataS - 2));
1469 if ((Prr_Product == PRR_PRODUCT_M3N)
1470 || (Prr_Product == PRR_PRODUCT_V3H)) {
1471 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1472 _reg_PHY_RDDATA_EN_OE_DLY, dataS);
1473 }
1474 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS);
1475
1476 if (ddrtbl_getval
1477 (_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD)) {
1478 dataL = WL - 1;
1479 } else {
1480 dataL = WL;
1481 }
1482 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1, dataL - 2);
1483 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1, dataL);
1484
1485 if (Boardcnf->dbi_en) {
1486 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE,
1487 0x01);
1488 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1489 _reg_PHY_WDQLVL_DATADM_MASK, 0x000);
1490 } else {
1491 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE,
1492 0x00);
1493 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1494 _reg_PHY_WDQLVL_DATADM_MASK, 0x100);
1495 }
1496
1497 tmp[0] = js1[js1_ind].MR1;
1498 tmp[1] = js1[js1_ind].MR2;
1499 dataL = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_MR3_DATA_F1_0);
1500 if (Boardcnf->dbi_en)
1501 tmp[2] = dataL | 0xc0;
1502 else
1503 tmp[2] = dataL & (~0xc0);
1504
1505 for (i = 0; i < 2; i++) {
1506 for (csab = 0; csab < CSAB_CNT; csab++) {
1507 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1508 _reg_PI_MR1_DATA_Fx_CSx[i][csab], tmp[0]);
1509 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1510 _reg_PI_MR2_DATA_Fx_CSx[i][csab], tmp[1]);
1511 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1512 _reg_PI_MR3_DATA_Fx_CSx[i][csab], tmp[2]);
1513 }
1514 }
1515
1516 /***********************************************************************
1517 DDRPHY INT START
1518 ***********************************************************************/
1519 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1520 /* non */
1521 } else {
1522 regif_pll_wa();
1523 }
1524
1525 /***********************************************************************
1526 FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety)
1527 ***********************************************************************/
1528 ddr_setval_ach(_reg_PHY_FREQ_SEL_MULTICAST_EN, 0x01);
1529 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x01);
1530
1531 /***********************************************************************
1532 SET DATA SLICE TABLE
1533 ***********************************************************************/
1534 for (slice = 0; slice < SLICE_CNT; slice++) {
1535 adr =
1536 DDR_PHY_SLICE_REGSET_OFS +
1537 DDR_PHY_SLICE_REGSET_SIZE * slice;
1538 for (i = 0; i < DDR_PHY_SLICE_REGSET_NUM; i++) {
1539 reg_ddrphy_write_a(adr + i,
1540 _cnf_DDR_PHY_SLICE_REGSET[i]);
1541 }
1542 }
1543
1544 /***********************************************************************
1545 SET ADR SLICE TABLE
1546 ***********************************************************************/
1547 adr = DDR_PHY_ADR_V_REGSET_OFS;
1548 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM; i++) {
1549 reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_V_REGSET[i]);
1550 }
1551
Marek Vasut6c245a52018-12-12 18:06:39 +01001552 if (((Prr_Product == PRR_PRODUCT_M3)
1553 || (Prr_Product == PRR_PRODUCT_M3N)) &&
1554 ((0x00ffffff & (uint32_t)((Boardcnf->ch[0].ca_swap) >> 40))
1555 != 0x00)) {
1556 adr = DDR_PHY_ADR_I_REGSET_OFS + DDR_PHY_ADR_I_REGSET_SIZE;
1557 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM; i++) {
1558 reg_ddrphy_write_a(adr + i,
1559 _cnf_DDR_PHY_ADR_V_REGSET[i]);
1560 }
1561 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, _reg_PHY_ADR_DISABLE, 0x02);
1562 DDR_PHY_ADR_I_NUM -= 1;
1563 ddr_phycaslice = 1;
1564
1565#ifndef _def_LPDDR4_ODT
1566 for (i = 0; i < 2; i++) {
1567 for (csab = 0; csab < CSAB_CNT; csab++) {
1568 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1569 _reg_PI_MR11_DATA_Fx_CSx[i][csab],
1570 0x66);
1571 }
1572 }
1573#endif/* _def_LPDDR4_ODT */
1574 } else {
1575 ddr_phycaslice = 0;
1576 }
1577
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001578 if (DDR_PHY_ADR_I_NUM > 0) {
1579 for (slice = 0; slice < DDR_PHY_ADR_I_NUM; slice++) {
1580 adr =
1581 DDR_PHY_ADR_I_REGSET_OFS +
1582 DDR_PHY_ADR_I_REGSET_SIZE * slice;
1583 for (i = 0; i < DDR_PHY_ADR_I_REGSET_NUM; i++) {
1584 reg_ddrphy_write_a(adr + i,
1585 _cnf_DDR_PHY_ADR_I_REGSET
1586 [i]);
1587 }
1588 }
1589 }
1590
1591 /***********************************************************************
1592 SET ADRCTRL SLICE TABLE
1593 ***********************************************************************/
1594 adr = DDR_PHY_ADR_G_REGSET_OFS;
1595 for (i = 0; i < DDR_PHY_ADR_G_REGSET_NUM; i++) {
1596 reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_G_REGSET[i]);
1597 }
1598
1599 /***********************************************************************
1600 SET PI REGISTERS
1601 ***********************************************************************/
1602 adr = DDR_PI_REGSET_OFS;
1603 for (i = 0; i < DDR_PI_REGSET_NUM; i++) {
1604 reg_ddrphy_write_a(adr + i, _cnf_DDR_PI_REGSET[i]);
1605 }
1606}
1607
1608/*******************************************************************************
1609 * CONFIGURE DDR REGISTERS
1610 ******************************************************************************/
1611static void ddr_config_sub(void)
1612{
1613 int32_t i;
1614 uint32_t ch, slice;
1615 uint32_t dataL;
1616 uint32_t tmp;
1617 uint8_t high_byte[SLICE_CNT];
1618 foreach_vch(ch) {
1619 /***********************************************************************
1620 BOARD SETTINGS (DQ,DM,VREF_DRIVING)
1621 ***********************************************************************/
1622 for (slice = 0; slice < SLICE_CNT; slice++) {
1623 high_byte[slice] =
1624 (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) % 2;
1625 ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE0,
1626 Boardcnf->ch[ch].dq_swap[slice]);
1627 ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE1,
1628 Boardcnf->ch[ch].dm_swap[slice]);
1629 if (high_byte[slice]) {
1630 /* HIGHER 16 BYTE */
1631 ddr_setval_s(ch, slice,
1632 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1633 0x00);
1634 } else {
1635 /* LOWER 16 BYTE */
1636 ddr_setval_s(ch, slice,
1637 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1638 0x01);
1639 }
1640 }
1641
1642 /***********************************************************************
1643 BOARD SETTINGS (CA,ADDR_SEL)
1644 ***********************************************************************/
1645 const uint32_t _par_CALVL_DEVICE_MAP = 1;
Marek Vasut6c245a52018-12-12 18:06:39 +01001646
1647 dataL = (0x00ffffff & (uint32_t)(Boardcnf->ch[ch].ca_swap)) |
1648 0x00888888;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001649
1650 /* --- ADR_CALVL_SWIZZLE --- */
1651 if (Prr_Product == PRR_PRODUCT_M3) {
1652 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, dataL);
1653 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0,
1654 0x00000000);
1655 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, dataL);
1656 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1,
1657 0x00000000);
1658 ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP,
1659 _par_CALVL_DEVICE_MAP);
1660 } else {
1661 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0, dataL);
1662 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1, 0x00000000);
1663 ddr_setval(ch, _reg_PHY_CALVL_DEVICE_MAP,
1664 _par_CALVL_DEVICE_MAP);
1665 }
1666
1667 /* --- ADR_ADDR_SEL --- */
1668 if ((Prr_Product == PRR_PRODUCT_H3)
1669 && (Prr_Cut > PRR_PRODUCT_11)) {
1670 dataL = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
1671 } else {
1672 dataL = 0;
1673 tmp = Boardcnf->ch[ch].ca_swap;
1674 for (i = 0; i < 6; i++) {
1675 dataL |= ((tmp & 0x0f) << (i * 5));
1676 tmp = tmp >> 4;
1677 }
1678 }
1679 ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, dataL);
Marek Vasut6c245a52018-12-12 18:06:39 +01001680 if (ddr_phycaslice == 1) {
1681 /* ----------- adr slice2 swap ----------- */
1682 tmp = (uint32_t)((Boardcnf->ch[ch].ca_swap) >> 40);
1683 dataL = (tmp & 0x00ffffff) | 0x00888888;
1684
1685 /* --- ADR_CALVL_SWIZZLE --- */
1686 if (Prr_Product == PRR_PRODUCT_M3) {
1687 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0_0, dataL);
1688 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1_0,
1689 0x00000000);
1690 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0_1, dataL);
1691 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1_1,
1692 0x00000000);
1693 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_DEVICE_MAP,
1694 _par_CALVL_DEVICE_MAP);
1695 } else {
1696 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0, dataL);
1697 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1,
1698 0x00000000);
1699 ddr_setval_s(ch, 2, _reg_PHY_CALVL_DEVICE_MAP,
1700 _par_CALVL_DEVICE_MAP);
1701 }
1702
1703 /* --- ADR_ADDR_SEL --- */
1704 dataL = 0;
1705 for (i = 0; i < 6; i++) {
1706 dataL |= ((tmp & 0x0f) << (i * 5));
1707 tmp = tmp >> 4;
1708 }
1709
1710 ddr_setval_s(ch, 2, _reg_PHY_ADR_ADDR_SEL, dataL);
1711 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001712
1713 /***********************************************************************
1714 BOARD SETTINGS (BYTE_ORDER_SEL)
1715 ***********************************************************************/
1716 if (Prr_Product == PRR_PRODUCT_M3) {
1717 /* --- DATA_BYTE_SWAP --- */
1718 dataL = 0;
1719 tmp = Boardcnf->ch[ch].dqs_swap;
1720 for (i = 0; i < 4; i++) {
1721 dataL |= ((tmp & 0x03) << (i * 2));
1722 tmp = tmp >> 4;
1723 }
1724 } else {
1725 /* --- DATA_BYTE_SWAP --- */
1726 dataL = Boardcnf->ch[ch].dqs_swap;
1727 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_EN, 0x01);
1728 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE0,
1729 (dataL) & 0x0f);
1730 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE1,
1731 (dataL >> 4 * 1) & 0x0f);
1732 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE2,
1733 (dataL >> 4 * 2) & 0x0f);
1734 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE3,
1735 (dataL >> 4 * 3) & 0x0f);
1736
1737 ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH, 0x00);
1738 }
1739 ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL, dataL);
1740 }
1741}
1742
1743static void get_ca_swizzle(uint32_t ch, uint32_t ddr_csn, uint32_t * p_swz)
1744{
1745 uint32_t slice;
1746 uint32_t tmp;
1747 uint32_t tgt;
1748 if (ddr_csn / 2) {
1749 tgt = 3;
1750 } else {
1751 tgt = 1;
1752 }
1753
1754 for (slice = 0; slice < SLICE_CNT; slice++) {
1755 tmp = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
1756 if (tgt == tmp)
1757 break;
1758 }
Marek Vasut6c245a52018-12-12 18:06:39 +01001759 tmp = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001760 if (slice % 2)
1761 tmp |= 0x00888888;
1762 *p_swz = tmp;
1763}
1764
1765static void ddr_config_sub_h3v1x(void)
1766{
1767 uint32_t ch, slice;
1768 uint32_t dataL;
1769 uint32_t tmp;
1770 uint8_t high_byte[SLICE_CNT];
1771
1772 foreach_vch(ch) {
1773 uint32_t ca_swizzle;
1774 uint32_t ca;
1775 uint32_t csmap;
1776 /***********************************************************************
1777 BOARD SETTINGS (DQ,DM,VREF_DRIVING)
1778 ***********************************************************************/
1779 csmap = 0;
1780 for (slice = 0; slice < SLICE_CNT; slice++) {
1781 tmp = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
1782 high_byte[slice] = tmp % 2;
1783 if (tmp == 1 && (slice >= 2))
1784 csmap |= 0x05;
1785 if (tmp == 3 && (slice >= 2))
1786 csmap |= 0x50;
1787 ddr_setval_s(ch, slice, _reg_PHY_DQ_SWIZZLING,
1788 Boardcnf->ch[ch].dq_swap[slice]);
1789 if (high_byte[slice]) {
1790 /* HIGHER 16 BYTE */
1791 ddr_setval_s(ch, slice,
1792 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1793 0x00);
1794 } else {
1795 /* LOWER 16 BYTE */
1796 ddr_setval_s(ch, slice,
1797 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1798 0x01);
1799 }
1800 }
1801 /***********************************************************************
1802 BOARD SETTINGS (CA,ADDR_SEL)
1803 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01001804 ca = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001805 ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, ca);
1806 ddr_setval(ch, _reg_PHY_CALVL_CS_MAP, csmap);
1807
1808 get_ca_swizzle(ch, 0, &ca_swizzle);
1809
1810 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, ca_swizzle);
1811 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0, 0x00000000);
1812 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, 0x00000000);
1813 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1, 0x00000000);
1814 ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP, 0x01);
1815
1816 for (slice = 0; slice < SLICE_CNT; slice++) {
1817 const uint8_t o_mr15 = 0x55;
1818 const uint8_t o_mr20 = 0x55;
1819 const uint16_t o_mr32_mr40 = 0x5a3c;
1820 uint32_t o_inv;
1821 uint32_t inv;
1822 uint32_t bit_soc;
1823 uint32_t bit_mem;
1824 uint32_t j;
1825
1826 ddr_setval_s(ch, slice, _reg_PI_RDLVL_PATTERN_NUM,
1827 0x01);
1828 ddr_setval_s(ch, slice, _reg_PI_RDLVL_PATTERN_START,
1829 0x08);
1830
1831 if (high_byte[slice])
1832 o_inv = o_mr20;
1833 else
1834 o_inv = o_mr15;
1835
1836 tmp = Boardcnf->ch[ch].dq_swap[slice];
1837 inv = 0;
1838 j = 0;
1839 for (bit_soc = 0; bit_soc < 8; bit_soc++) {
1840 bit_mem = (tmp >> (4 * bit_soc)) & 0x0f;
1841 j |= (1U << bit_mem);
1842 if (o_inv & (1U << bit_mem))
1843 inv |= (1U << bit_soc);
1844 }
1845 dataL = o_mr32_mr40;
1846 if (!high_byte[slice])
1847 dataL |= (inv << 24);
1848 if (high_byte[slice])
1849 dataL |= (inv << 16);
1850 ddr_setval_s(ch, slice, _reg_PHY_LP4_RDLVL_PATT8,
1851 dataL);
1852 }
1853 }
1854}
1855
1856static void ddr_config(void)
1857{
1858 int32_t i;
1859 uint32_t ch, slice;
1860 uint32_t dataL;
1861 uint32_t tmp;
1862
1863 /***********************************************************************
1864 configure ddrphy registers
1865 ***********************************************************************/
1866 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1867 ddr_config_sub_h3v1x();
1868 } else {
1869 ddr_config_sub(); /* H3 Ver.2.0 or later/M3-N/V3H is same as M3-W */
1870 }
1871
1872 /***********************************************************************
1873 WDQ_USER_PATT
1874 ***********************************************************************/
1875 foreach_vch(ch) {
1876 union {
1877 uint32_t ui32[4];
1878 uint8_t ui8[16];
1879 } patt;
1880 uint16_t patm;
1881 for (slice = 0; slice < SLICE_CNT; slice++) {
1882 patm = 0;
1883 for (i = 0; i < 16; i++) {
1884 tmp = Boardcnf->ch[ch].wdqlvl_patt[i];
1885 patt.ui8[i] = tmp & 0xff;
1886 if (tmp & 0x100)
1887 patm |= (1U << i);
1888 }
1889 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT0,
1890 patt.ui32[0]);
1891 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT1,
1892 patt.ui32[1]);
1893 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT2,
1894 patt.ui32[2]);
1895 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT3,
1896 patt.ui32[3]);
1897 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT4, patm);
1898 }
1899 }
1900
1901 /***********************************************************************
1902 CACS DLY
1903 ***********************************************************************/
1904 dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
1905 set_dfifrequency(0x1f);
1906 foreach_vch(ch) {
1907 int16_t adj;
1908 for (i = 0; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
1909 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
1910 ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
1911 dataL + adj);
1912 }
Marek Vasut6c245a52018-12-12 18:06:39 +01001913 if (ddr_phycaslice == 1) {
1914 for (i = 0; i < 6; i++) {
1915 adj =
1916 _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i +
1917 _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM]);
1918 ddr_setval_s(ch, 2,
1919 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
1920 dataL + adj);
1921 }
1922 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001923 }
1924 set_dfifrequency(0x00);
1925
1926 /***********************************************************************
1927 WDQDM DLY
1928 ***********************************************************************/
1929 dataL = Boardcnf->dqdm_dly_w;
1930 foreach_vch(ch) {
1931 int8_t _adj;
1932 int16_t adj;
1933 uint32_t dq;
1934 for (slice = 0; slice < SLICE_CNT; slice++) {
1935 for (i = 0; i <= 8; i++) {
1936 dq = slice * 8 + i;
1937 if (i == 8)
1938 _adj = Boardcnf->ch[ch].dm_adj_w[slice];
1939 else
1940 _adj = Boardcnf->ch[ch].dq_adj_w[dq];
1941 adj = _f_scale_adj(_adj);
1942 ddr_setval_s(ch, slice,
1943 _reg_PHY_CLK_WRX_SLAVE_DELAY[i],
1944 dataL + adj);
1945 }
1946 }
1947 }
1948
1949 /***********************************************************************
1950 RDQDM DLY
1951 ***********************************************************************/
1952 dataL = Boardcnf->dqdm_dly_r;
1953 foreach_vch(ch) {
1954 int8_t _adj;
1955 int16_t adj;
1956 uint32_t dq;
1957 for (slice = 0; slice < SLICE_CNT; slice++) {
1958 for (i = 0; i <= 8; i++) {
1959 dq = slice * 8 + i;
1960 if (i == 8)
1961 _adj = Boardcnf->ch[ch].dm_adj_r[slice];
1962 else
1963 _adj = Boardcnf->ch[ch].dq_adj_r[dq];
1964 adj = _f_scale_adj(_adj);
1965 ddr_setval_s(ch, slice,
1966 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY
1967 [i], dataL + adj);
1968 ddr_setval_s(ch, slice,
1969 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY
1970 [i], dataL + adj);
1971 }
1972 }
1973 }
1974}
1975
1976/*******************************************************************************
1977 * DBSC register setting functions
1978 ******************************************************************************/
1979static void dbsc_regset_pre(void)
1980{
1981 uint32_t ch, csab;
1982 uint32_t dataL;
1983
1984 /***********************************************************************
1985 PRIMARY SETTINGS
1986 ***********************************************************************/
1987 /* LPDDR4, BL=16, DFI interface */
1988 mmio_write_32(DBSC_DBKIND, 0x0000000a);
1989 mmio_write_32(DBSC_DBBL, 0x00000002);
1990 mmio_write_32(DBSC_DBPHYCONF0, 0x00000001);
1991
1992 /* FREQRATIO=2 */
1993 mmio_write_32(DBSC_DBSYSCONF1, 0x00000002);
1994
1995 /* Chanel map (H3 Ver.1.x) */
1996 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
1997 mmio_write_32(DBSC_DBSCHCNT1, 0x00001010);
1998
1999 /* DRAM SIZE REGISTER:
2000 * set all ranks as density=0(4Gb) for PHY initialization
2001 */
2002 foreach_vch(ch)
2003 for (csab = 0; csab < 4; csab++)
2004 mmio_write_32(DBSC_DBMEMCONF(ch, csab), DBMEMCONF_REGD(0));
2005
2006 if (Prr_Product == PRR_PRODUCT_M3) {
2007 dataL = 0xe4e4e4e4;
2008 foreach_ech(ch) {
2009 if ((ddr_phyvalid & (1U << ch)))
2010 dataL = (dataL & (~(0x000000FF << (ch * 8))))
2011 | (((Boardcnf->ch[ch].dqs_swap & 0x0003)
2012 | ((Boardcnf->ch[ch].dqs_swap & 0x0030)
2013 >> 2)
2014 | ((Boardcnf->ch[ch].dqs_swap & 0x0300)
2015 >> 4)
2016 | ((Boardcnf->ch[ch].dqs_swap & 0x3000)
2017 >> 6)) << (ch * 8));
2018 }
2019 mmio_write_32(DBSC_DBBSWAP, dataL);
2020 }
2021}
2022
2023static void dbsc_regset(void)
2024{
2025 int32_t i;
2026 uint32_t ch;
2027 uint32_t dataL;
2028 uint32_t tmp[4];
2029
2030 /* RFC */
2031 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_20)
2032 && (max_density == 0)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002033 js2[JS2_tRFCab] =
2034 _f_scale(ddr_mbps, ddr_mbpsdiv,
Marek Vasut6c245a52018-12-12 18:06:39 +01002035 1UL * jedec_spec2_tRFC_ab[1] * 1000, 0);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002036 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002037 js2[JS2_tRFCab] =
2038 _f_scale(ddr_mbps, ddr_mbpsdiv,
Marek Vasut6c245a52018-12-12 18:06:39 +01002039 1UL * jedec_spec2_tRFC_ab[max_density] *
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002040 1000, 0);
2041 }
2042
2043 /* DBTR0.CL : RL */
2044 mmio_write_32(DBSC_DBTR(0), RL);
2045
2046 /* DBTR1.CWL : WL */
2047 mmio_write_32(DBSC_DBTR(1), WL);
2048
2049 /* DBTR2.AL : 0 */
2050 mmio_write_32(DBSC_DBTR(2), 0);
2051
2052 /* DBTR3.TRCD: tRCD */
2053 mmio_write_32(DBSC_DBTR(3), js2[JS2_tRCD]);
2054
2055 /* DBTR4.TRPA,TRP: tRPab,tRPpb */
2056 mmio_write_32(DBSC_DBTR(4), (js2[JS2_tRPab] << 16) | js2[JS2_tRPpb]);
2057
2058 /* DBTR5.TRC : use tRCpb */
2059 mmio_write_32(DBSC_DBTR(5), js2[JS2_tRCpb]);
2060
2061 /* DBTR6.TRAS : tRAS */
2062 mmio_write_32(DBSC_DBTR(6), js2[JS2_tRAS]);
2063
2064 /* DBTR7.TRRD : tRRD */
2065 mmio_write_32(DBSC_DBTR(7), (js2[JS2_tRRD] << 16) | js2[JS2_tRRD]);
2066
2067 /* DBTR8.TFAW : tFAW */
2068 mmio_write_32(DBSC_DBTR(8), js2[JS2_tFAW]);
2069
2070 /* DBTR9.TRDPR : tRTP */
2071 mmio_write_32(DBSC_DBTR(9), js2[JS2_tRTP]);
2072
2073 /* DBTR10.TWR : nWR */
2074 mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nWR);
2075
2076 /* DBTR11.TRDWR : RL + tDQSCK + BL/2 + Rounddown(tRPST) - WL + tWPRE */
2077 mmio_write_32(DBSC_DBTR(11),
2078 RL + js2[JS2_tDQSCK] + (16 / 2) + 1 - WL + 2 + 2);
2079
2080 /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */
2081 dataL = WL + 1 + (16 / 2) + js2[JS2_tWTR];
2082 mmio_write_32(DBSC_DBTR(12), (dataL << 16) | dataL);
2083
Marek Vasut6c245a52018-12-12 18:06:39 +01002084 /* DBTR13.TRFCAB : tRFCab */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002085 mmio_write_32(DBSC_DBTR(13), (js2[JS2_tRFCab]));
2086
2087 /* DBTR14.TCKEHDLL,tCKEH : tCKEHCMD,tCKEHCMD */
2088 mmio_write_32(DBSC_DBTR(14),
2089 (js2[JS2_tCKEHCMD] << 16) | (js2[JS2_tCKEHCMD]));
2090
2091 /* DBTR15.TCKESR,TCKEL : tSR,tCKELPD */
2092 mmio_write_32(DBSC_DBTR(15), (js2[JS2_tSR] << 16) | (js2[JS2_tCKELPD]));
2093
2094 /* DBTR16 */
2095 /* WDQL : tphy_wrlat + tphy_wrdata */
2096 tmp[0] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1);
Marek Vasut3af20052019-02-25 14:57:08 +01002097 /* DQENLTNCY : tphy_wrlat = WL-2 : PHY_WRITE_PATH_LAT_ADD == 0
2098 * tphy_wrlat = WL-3 : PHY_WRITE_PATH_LAT_ADD != 0
2099 */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002100 tmp[1] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1);
2101 /* DQL : tphy_rdlat + trdata_en */
2102 /* it is not important for dbsc */
2103 tmp[2] = RL + 16;
2104 /* DQIENLTNCY : trdata_en */
2105 tmp[3] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1) - 1;
2106 mmio_write_32(DBSC_DBTR(16),
2107 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2108
2109 /* DBTR24 */
2110 /* WRCSLAT = WRLAT -5 */
2111 tmp[0] -= 5;
2112 /* WRCSGAP = 5 */
2113 tmp[1] = 5;
2114 /* RDCSLAT = RDLAT_ADJ +2 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002115 if (Prr_Product == PRR_PRODUCT_M3) {
2116 tmp[2] = tmp[3];
2117 } else {
2118 tmp[2] = tmp[3] + 2;
2119 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002120 /* RDCSGAP = 6 */
2121 if (Prr_Product == PRR_PRODUCT_M3) {
2122 tmp[3] = 4;
2123 } else {
2124 tmp[3] = 6;
2125 }
2126 mmio_write_32(DBSC_DBTR(24),
2127 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2128
2129 /* DBTR17.TMODRD,TMOD,TRDMR: tMRR,tMRD,(0) */
2130 mmio_write_32(DBSC_DBTR(17),
2131 (js2[JS2_tMRR] << 24) | (js2[JS2_tMRD] << 16));
2132
2133 /* DBTR18.RODTL, RODTA, WODTL, WODTA : do not use in LPDDR4 */
2134 mmio_write_32(DBSC_DBTR(18), 0);
2135
2136 /* DBTR19.TZQCL, TZQCS : do not use in LPDDR4 */
2137 mmio_write_32(DBSC_DBTR(19), 0);
2138
2139 /* DBTR20.TXSDLL, TXS : tRFCab+tCKEHCMD */
2140 dataL = js2[JS2_tRFCab] + js2[JS2_tCKEHCMD];
2141 mmio_write_32(DBSC_DBTR(20), (dataL << 16) | dataL);
2142
2143 /* DBTR21.TCCD */
2144 /* DBTR23.TCCD */
2145 /* H3 Ver.1.0 cannot use TBTR23 feature */
2146 if (ddr_tccd == 8 &&
2147 !((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_10))
2148 ) {
2149 dataL = 8;
2150 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2151 mmio_write_32(DBSC_DBTR(23), 0x00000002);
2152 } else if (ddr_tccd <= 11) {
2153 dataL = 11;
2154 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2155 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2156 } else {
2157 dataL = ddr_tccd;
2158 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2159 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2160 }
2161
2162 /* DBTR22.ZQLAT : */
2163 dataL = js2[JS2_tZQCALns] * 100; /* 1000 * 1000 ps */
2164 dataL = (dataL << 16) | (js2[JS2_tZQLAT] + 24 + 20);
2165 mmio_write_32(DBSC_DBTR(22), dataL);
2166
2167 /* DBTR25 : do not use in LPDDR4 */
2168 mmio_write_32(DBSC_DBTR(25), 0);
2169
2170 /* DBRNK : */
2171 /*
2172 * DBSC_DBRNK2 rkrr
2173 * DBSC_DBRNK3 rkrw
2174 * DBSC_DBRNK4 rkwr
2175 * DBSC_DBRNK5 rkww
2176 */
2177#define _par_DBRNK_VAL (0x7007)
2178
2179 for (i = 0; i < 4; i++) {
2180 uint32_t dataL2;
2181 dataL = (_par_DBRNK_VAL >> (i * 4)) & 0x0f;
2182 if ((Prr_Product == PRR_PRODUCT_H3)
2183 && (Prr_Cut > PRR_PRODUCT_11) && (i == 0)) {
2184 dataL += 1;
2185 }
2186 dataL2 = 0;
2187 foreach_vch(ch) {
2188 dataL2 = dataL2 | (dataL << (4 * ch));
2189 }
2190 mmio_write_32(DBSC_DBRNK(2 + i), dataL2);
2191 }
2192 mmio_write_32(DBSC_DBADJ0, 0x00000000);
2193
2194 /***********************************************************************
2195 timing registers for Scheduler
2196 ***********************************************************************/
2197 /* SCFCTST0 */
2198 /* SCFCTST0 ACT-ACT */
2199 tmp[3] = 1UL * js2[JS2_tRCpb] * 800 * ddr_mbpsdiv / ddr_mbps;
2200 /* SCFCTST0 RDA-ACT */
2201 tmp[2] =
2202 1UL * ((16 / 2) + js2[JS2_tRTP] - 8 +
2203 js2[JS2_tRPpb]) * 800 * ddr_mbpsdiv / ddr_mbps;
2204 /* SCFCTST0 WRA-ACT */
2205 tmp[1] =
2206 1UL * (WL + 1 + (16 / 2) +
2207 js1[js1_ind].nWR) * 800 * ddr_mbpsdiv / ddr_mbps;
2208 /* SCFCTST0 PRE-ACT */
2209 tmp[0] = 1UL * js2[JS2_tRPpb];
2210 mmio_write_32(DBSC_SCFCTST0,
2211 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2212
2213 /* SCFCTST1 */
2214 /* SCFCTST1 RD-WR */
2215 tmp[3] =
2216 1UL * (mmio_read_32(DBSC_DBTR(11)) & 0xff) * 800 * ddr_mbpsdiv /
2217 ddr_mbps;
2218 /* SCFCTST1 WR-RD */
2219 tmp[2] =
2220 1UL * (mmio_read_32(DBSC_DBTR(12)) & 0xff) * 800 * ddr_mbpsdiv /
2221 ddr_mbps;
2222 /* SCFCTST1 ACT-RD/WR */
2223 tmp[1] = 1UL * js2[JS2_tRCD] * 800 * ddr_mbpsdiv / ddr_mbps;
2224 /* SCFCTST1 ASYNCOFS */
2225 tmp[0] = 12;
2226 mmio_write_32(DBSC_SCFCTST1,
2227 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2228
2229 /* DBSCHRW1 */
2230 /* DBSCHRW1 SCTRFCAB */
2231 tmp[0] = 1UL * js2[JS2_tRFCab] * 800 * ddr_mbpsdiv / ddr_mbps;
2232 dataL = (((mmio_read_32(DBSC_DBTR(16)) & 0x00FF0000) >> 16)
2233 + (mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
2234 + (0x28 * 2)) * 400 * 2 * ddr_mbpsdiv / ddr_mbps + 7;
2235 if (tmp[0] < dataL)
2236 tmp[0] = dataL;
2237 mmio_write_32(DBSC_DBSCHRW1, tmp[0]);
2238
2239 /***********************************************************************
2240 QOS and CAM
2241 ***********************************************************************/
2242#ifdef ddr_qos_init_setting /* only for non qos_init */
2243 /*wbkwait(0004), wbkmdhi(4,2),wbkmdlo(1,8) */
2244 mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218);
2245 /*0(fillunit),8(dirtymax),4(dirtymin) */
2246 mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4);
2247 /*stop_tolerance */
2248 mmio_write_32(DBSC_DBSCHRW0, 0x22421111);
2249 /*rd-wr/wr-rd toggle priority */
2250 mmio_write_32(DBSC_SCFCTST2, 0x012F1123);
2251 mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
2252 mmio_write_32(DBSC_DBSCHCNT0, 0x000F0037);
2253
2254 /* QoS Settings */
2255 mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00U);
2256 mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00U);
2257 mmio_write_32(DBSC_DBSCHQOS02, 0x00000000U);
2258 mmio_write_32(DBSC_DBSCHQOS03, 0x00000000U);
2259 mmio_write_32(DBSC_DBSCHQOS40, 0x00000300U);
2260 mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0U);
2261 mmio_write_32(DBSC_DBSCHQOS42, 0x00000200U);
2262 mmio_write_32(DBSC_DBSCHQOS43, 0x00000100U);
2263 mmio_write_32(DBSC_DBSCHQOS90, 0x00000100U);
2264 mmio_write_32(DBSC_DBSCHQOS91, 0x000000F0U);
2265 mmio_write_32(DBSC_DBSCHQOS92, 0x000000A0U);
2266 mmio_write_32(DBSC_DBSCHQOS93, 0x00000040U);
2267 mmio_write_32(DBSC_DBSCHQOS120, 0x00000040U);
2268 mmio_write_32(DBSC_DBSCHQOS121, 0x00000030U);
2269 mmio_write_32(DBSC_DBSCHQOS122, 0x00000020U);
2270 mmio_write_32(DBSC_DBSCHQOS123, 0x00000010U);
2271 mmio_write_32(DBSC_DBSCHQOS130, 0x00000100U);
2272 mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0U);
2273 mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0U);
2274 mmio_write_32(DBSC_DBSCHQOS133, 0x00000040U);
2275 mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0U);
2276 mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0U);
2277 mmio_write_32(DBSC_DBSCHQOS142, 0x00000080U);
2278 mmio_write_32(DBSC_DBSCHQOS143, 0x00000040U);
2279 mmio_write_32(DBSC_DBSCHQOS150, 0x00000040U);
2280 mmio_write_32(DBSC_DBSCHQOS151, 0x00000030U);
2281 mmio_write_32(DBSC_DBSCHQOS152, 0x00000020U);
2282 mmio_write_32(DBSC_DBSCHQOS153, 0x00000010U);
2283
2284 mmio_write_32(QOSCTRL_RAEN, 0x00000001U);
2285#endif /* ddr_qos_init_setting */
2286 /* H3 Ver.1.1 need to set monitor function */
2287 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_11)) {
2288 mmio_write_32(DBSC_DBMONCONF4, 0x00700000);
2289 }
2290
2291 if (Prr_Product == PRR_PRODUCT_H3) {
2292 if (Prr_Cut == PRR_PRODUCT_10) {
2293 /* resrdis, simple mode, sc off */
2294 mmio_write_32(DBSC_DBBCAMDIS, 0x00000007);
2295 } else if (Prr_Cut == PRR_PRODUCT_11) {
2296 /* resrdis, simple mode */
2297 mmio_write_32(DBSC_DBBCAMDIS, 0x00000005);
2298 } else if (Prr_Cut < PRR_PRODUCT_30) {
2299 /* H3 Ver.2.0 */
2300 /* resrdis */
2301 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2302 } else { /* H3 Ver.3.0(include H3N) */
2303 /* exprespque */
2304 mmio_write_32(DBSC_DBBCAMDIS, 0x00000010);
2305 }
2306 } else { /* M3-W/M3-N/V3H */
2307 /* resrdis */
2308 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2309 }
2310}
2311
2312static void dbsc_regset_post(void)
2313{
2314 uint32_t ch, cs;
2315 uint32_t dataL;
2316 uint32_t slice, rdlat_max, rdlat_min;
2317
2318 rdlat_max = 0;
2319 rdlat_min = 0xffff;
2320 foreach_vch(ch) {
2321 for (cs = 0; cs < CS_CNT; cs++) {
2322 if ((ch_have_this_cs[cs] & (1U << ch)) != 0) {
2323 for (slice = 0; slice < SLICE_CNT; slice++) {
2324 ddr_setval_s(ch, slice,
2325 _reg_PHY_PER_CS_TRAINING_INDEX,
2326 cs);
2327 dataL =
2328 ddr_getval_s(ch, slice,
2329 _reg_PHY_RDDQS_LATENCY_ADJUST);
2330 if (dataL > rdlat_max)
2331 rdlat_max = dataL;
2332 if (dataL < rdlat_min)
2333 rdlat_min = dataL;
2334 }
2335 }
2336 }
2337 }
2338 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11)) {
2339 mmio_write_32(DBSC_DBTR(24),
2340 ((rdlat_max * 2 - rdlat_min + 4) << 24) +
2341 ((rdlat_min + 2) << 16) +
2342 mmio_read_32(DBSC_DBTR(24)));
2343 } else {
2344 mmio_write_32(DBSC_DBTR(24),
2345 ((rdlat_max + 2) << 24) +
2346 ((rdlat_max + 2) << 16) +
2347 mmio_read_32(DBSC_DBTR(24)));
2348 }
2349
2350 /* set ddr density information */
2351 foreach_ech(ch) {
2352 for (cs = 0; cs < CS_CNT; cs++) {
2353 if (ddr_density[ch][cs] == 0xff) {
2354 mmio_write_32(DBSC_DBMEMCONF(ch, cs), 0x00);
2355 } else {
2356 mmio_write_32(DBSC_DBMEMCONF(ch, cs),
2357 DBMEMCONF_REGD(ddr_density[ch]
2358 [cs]));
2359 }
2360 }
2361 mmio_write_32(DBSC_DBMEMCONF(ch, 2), 0x00000000);
2362 mmio_write_32(DBSC_DBMEMCONF(ch, 3), 0x00000000);
2363 }
2364
2365 mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
2366
2367 /*set DBI */
2368 if (Boardcnf->dbi_en)
2369 mmio_write_32(DBSC_DBDBICNT, 0x00000003);
2370
2371 /* H3 Ver.2.0 or later/M3-N/V3H DBI wa */
2372 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
2373 || (Prr_Product == PRR_PRODUCT_M3N)
2374 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
2375 reg_ddrphy_write_a(0x00001010, 0x01000000);
2376
2377 /*set REFCYCLE */
2378 dataL = (get_refperiod()) * ddr_mbps / 2000 / ddr_mbpsdiv;
2379 mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (dataL & 0x0000ffff));
2380 mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS);
2381#if RCAR_REWT_TRAINING != 0
2382 /* Periodic-WriteDQ Training seeting */
2383 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
2384 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut == PRR_PRODUCT_10))) {
2385 /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */
2386 } else {
2387 /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H -> Periodic-WriteDQ Training seeting */
2388
2389 /* Periodic WriteDQ Training seeting */
2390 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000);
2391
2392 ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04);
2393 ddr_setval_ach_as(_reg_PHY_WDQLVL_QTR_DLY_STEP, 0x0F);
2394 ddr_setval_ach_as(_reg_PHY_WDQLVL_DLY_STEP, 0x50);
2395 ddr_setval_ach_as(_reg_PHY_WDQLVL_DQDM_SLV_DLY_START, 0x0300);
2396
2397 ddr_setval_ach(_reg_PI_WDQLVL_CS_MAP,
2398 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2399 _reg_PI_WDQLVL_CS_MAP));
2400 ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f);
2401 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
2402 ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100);
2403 ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01);
2404 ddr_setval_ach(_reg_PI_TREF_F0, 0x0000);
2405 ddr_setval_ach(_reg_PI_TREF_F1, 0x0000);
2406 ddr_setval_ach(_reg_PI_TREF_F2, 0x0000);
2407
2408 if (Prr_Product == PRR_PRODUCT_M3) {
2409 ddr_setval_ach(_reg_PI_WDQLVL_EN, 0x02);
2410 } else {
2411 ddr_setval_ach(_reg_PI_WDQLVL_EN_F1, 0x02);
2412 }
2413 ddr_setval_ach(_reg_PI_WDQLVL_PERIODIC, 0x01);
2414
2415 /* DFI_PHYMSTR_ACK , WTmode setting */
2416 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011); /* DFI_PHYMSTR_ACK: WTmode =b'01 */
2417 }
2418#endif /* RCAR_REWT_TRAINING */
2419 /* periodic dram zqcal and phy ctrl update enable */
2420 mmio_write_32(DBSC_DBCALCNF, 0x01000010);
2421 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01002422 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002423 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
2424 } else {
2425#if RCAR_DRAM_SPLIT == 2
2426 if ((Prr_Product == PRR_PRODUCT_H3)
2427 && (Boardcnf->phyvalid == 0x05))
2428 mmio_write_32(DBSC_DBDFICUPDCNF, 0x2a240001);
2429 else
2430 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2431#else /* RCAR_DRAM_SPLIT == 2 */
2432 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2433#endif /* RCAR_DRAM_SPLIT == 2 */
2434 }
2435
2436#ifdef DDR_BACKUPMODE
2437 if (ddrBackup == DRAM_BOOT_STATUS_WARM) {
2438#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */
2439 PutStr(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
2440 send_dbcmd(0x08040001);
2441 wait_dbcmd();
2442 send_dbcmd(0x0A040001);
2443 wait_dbcmd();
2444 send_dbcmd(0x04040010);
2445 wait_dbcmd();
2446
2447 if (Prr_Product == PRR_PRODUCT_H3) {
2448 send_dbcmd(0x08140001);
2449 wait_dbcmd();
2450 send_dbcmd(0x0A140001);
2451 wait_dbcmd();
2452 send_dbcmd(0x04140010);
2453 wait_dbcmd();
2454 }
2455#else /* DDR_BACKUPMODE_HALF //for All channels */
2456 send_dbcmd(0x08840001);
2457 wait_dbcmd();
2458 send_dbcmd(0x0A840001);
2459 wait_dbcmd();
2460
2461 send_dbcmd(0x04840010);
2462 wait_dbcmd();
2463#endif /* DDR_BACKUPMODE_HALF */
2464 }
2465#endif /* DDR_BACKUPMODE */
2466
2467 mmio_write_32(DBSC_DBRFEN, 0x00000001);
2468 /* dram access enable */
2469 mmio_write_32(DBSC_DBACEN, 0x00000001);
2470
2471 MSG_LF("dbsc_regset_post(done)");
2472
2473}
2474
2475/*******************************************************************************
2476 * DFI_INIT_START
2477 ******************************************************************************/
2478static uint32_t dfi_init_start(void)
2479{
2480 uint32_t ch;
2481 uint32_t phytrainingok;
2482 uint32_t retry;
2483 uint32_t dataL;
2484 const uint32_t RETRY_MAX = 0x10000;
2485
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002486 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002487 /***********************************************************************
2488 PLL3 Disable
2489 ***********************************************************************/
2490 /* protect register interface */
2491 ddrphy_regif_idle();
2492
2493 pll3_control(0);
2494
2495 /***********************************************************************
2496 init start
2497 ***********************************************************************/
2498 /* dbdficnt0:
2499 * dfi_dram_clk_disable=1
2500 * dfi_frequency = 0
2501 * freq_ratio = 01 (2:1)
2502 * init_start =0
2503 */
2504 foreach_vch(ch)
2505 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10);
2506 dsb_sev();
2507
2508 /* dbdficnt0:
2509 * dfi_dram_clk_disable=1
2510 * dfi_frequency = 0
2511 * freq_ratio = 01 (2:1)
2512 * init_start =1
2513 */
2514 foreach_vch(ch)
2515 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11);
2516 dsb_sev();
2517
2518 } else {
2519 ddr_setval_ach_as(_reg_PHY_DLL_RST_EN, 0x02);
2520 dsb_sev();
2521 ddrphy_regif_idle();
2522 }
2523
2524 /* dll_rst negate */
2525 foreach_vch(ch)
2526 mmio_write_32(DBSC_DBPDCNT3(ch), 0x0000CF01);
2527 dsb_sev();
2528
2529 /***********************************************************************
2530 wait init_complete
2531 ***********************************************************************/
2532 phytrainingok = 0;
2533 retry = 0;
2534 while (retry++ < RETRY_MAX) {
2535 foreach_vch(ch) {
2536 dataL = mmio_read_32(DBSC_INITCOMP(ch));
2537 if (dataL & 0x00000001)
2538 phytrainingok |= (1U << ch);
2539 }
2540 dsb_sev();
2541 if (phytrainingok == ddr_phyvalid)
2542 break;
2543 if (retry % 256 == 0)
2544 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
2545 }
2546
2547 /***********************************************************************
2548 all ch ok?
2549 ***********************************************************************/
2550 if ((phytrainingok & ddr_phyvalid) != ddr_phyvalid) {
2551 return (0xff);
2552 }
2553 /* dbdficnt0:
2554 * dfi_dram_clk_disable=0
2555 * dfi_frequency = 0
2556 * freq_ratio = 01 (2:1)
2557 * init_start =0
2558 */
2559 foreach_vch(ch)
2560 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000010);
2561 dsb_sev();
2562
2563 return 0;
2564}
2565
2566/*******************************************************************************
2567 * drivablity setting : CMOS MODE ON/OFF
2568 ******************************************************************************/
2569static void change_lpddr4_en(uint32_t mode)
2570{
2571 uint32_t ch;
2572 uint32_t i;
2573 uint32_t dataL;
2574 const uint32_t _reg_PHY_PAD_DRIVE_X[3] = {
2575 _reg_PHY_PAD_ADDR_DRIVE,
2576 _reg_PHY_PAD_CLK_DRIVE,
2577 _reg_PHY_PAD_CS_DRIVE
2578 };
2579
Marek Vasut6c245a52018-12-12 18:06:39 +01002580 foreach_vch(ch) {
2581 for (i = 0; i < 3; i++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002582 dataL = ddr_getval(ch, _reg_PHY_PAD_DRIVE_X[i]);
2583 if (mode) {
2584 dataL |= (1U << 14);
2585 } else {
2586 dataL &= ~(1U << 14);
2587 }
2588 ddr_setval(ch, _reg_PHY_PAD_DRIVE_X[i], dataL);
2589 }
2590 }
2591}
2592
2593/*******************************************************************************
2594 * drivablity setting
2595 ******************************************************************************/
2596static uint32_t set_term_code(void)
2597{
2598 int32_t i;
2599 uint32_t ch, index;
2600 uint32_t dataL;
2601 uint32_t chip_id[2];
2602 uint32_t term_code;
2603 uint32_t override;
2604 term_code = ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2605 _reg_PHY_PAD_DATA_TERM);
2606 override = 0;
2607 for (i = 0; i < 2; i++)
2608 chip_id[i] = mmio_read_32(LIFEC_CHIPID(i));
2609
2610 index = 0;
2611 while (1) {
2612 if (TermcodeBySample[index][0] == 0xffffffff) {
2613 break;
2614 }
2615 if ((TermcodeBySample[index][0] == chip_id[0])
2616 && (TermcodeBySample[index][1] == chip_id[1])) {
2617 term_code = TermcodeBySample[index][2];
2618 override = 1;
2619 break;
2620 }
2621 index++;
2622 }
2623
2624 if (override) {
2625 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM; index++) {
2626 dataL =
2627 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2628 _reg_PHY_PAD_TERM_X[index]);
2629 dataL = (dataL & ~0x0001ffff) | term_code;
2630 ddr_setval_ach(_reg_PHY_PAD_TERM_X[index], dataL);
2631 }
2632 } else if ((Prr_Product == PRR_PRODUCT_M3)
2633 && (Prr_Cut == PRR_PRODUCT_10)) {
2634 /* non */
2635 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002636 ddr_setval_ach(_reg_PHY_PAD_TERM_X[0],
2637 (ddrtbl_getval
2638 (_cnf_DDR_PHY_ADR_G_REGSET,
2639 _reg_PHY_PAD_TERM_X[0]) & 0xFFFE0000));
2640 ddr_setval_ach(_reg_PHY_CAL_CLEAR_0, 0x01);
2641 ddr_setval_ach(_reg_PHY_CAL_START_0, 0x01);
2642 foreach_vch(ch) {
2643 do {
2644 dataL =
2645 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2646 } while (!(dataL & 0x00800000));
2647 }
2648 if ((Prr_Product == PRR_PRODUCT_H3)
2649 && (Prr_Cut <= PRR_PRODUCT_11)) {
2650 foreach_vch(ch) {
2651 uint32_t pvtr;
2652 uint32_t pvtp;
2653 uint32_t pvtn;
2654 dataL = ddr_getval(ch, _reg_PHY_PAD_TERM_X[0]);
2655 pvtr = (dataL >> 12) & 0x1f;
2656 pvtr += 8;
2657 if (pvtr > 0x1f)
2658 pvtr = 0x1f;
2659 dataL =
2660 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2661 pvtn = (dataL >> 6) & 0x03f;
2662 pvtp = (dataL >> 0) & 0x03f;
2663
2664 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2665 index++) {
2666 dataL =
2667 ddrtbl_getval
2668 (_cnf_DDR_PHY_ADR_G_REGSET,
2669 _reg_PHY_PAD_TERM_X[index]);
2670 dataL = (dataL & ~0x0001ffff)
2671 | (pvtr << 12)
2672 | (pvtn << 6)
2673 | (pvtp);
2674 ddr_setval(ch,
2675 _reg_PHY_PAD_TERM_X[index],
2676 dataL);
2677 }
2678 }
2679 } else { /* M3-W Ver.1.1 or later/H3 Ver.2.0 or later/M3-N/V3H */
2680 foreach_vch(ch) {
2681 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2682 index++) {
2683 dataL =
2684 ddr_getval(ch,
2685 _reg_PHY_PAD_TERM_X
2686 [index]);
2687 ddr_setval(ch,
2688 _reg_PHY_PAD_TERM_X[index],
2689 (dataL & 0xFFFE0FFF) |
2690 0x00015000);
2691 }
2692 }
2693 }
2694 }
2695 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2696 /* non */
2697 } else {
2698 ddr_padcal_tcompensate_getinit(override);
2699 }
2700 return 0;
2701}
2702
2703/*******************************************************************************
2704 * DDR mode register setting
2705 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01002706static void ddr_register_set(void)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002707{
2708 int32_t fspwp;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002709 uint32_t tmp;
2710
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002711 for (fspwp = 1; fspwp >= 0; fspwp--) {
2712 /*MR13,fspwp */
Marek Vasut6c245a52018-12-12 18:06:39 +01002713 send_dbcmd(0x0e840d08 | (fspwp << 6));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002714
2715 tmp =
2716 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2717 _reg_PI_MR1_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002718 send_dbcmd(0x0e840100 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002719
2720 tmp =
2721 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2722 _reg_PI_MR2_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002723 send_dbcmd(0x0e840200 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002724
2725 tmp =
2726 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2727 _reg_PI_MR3_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002728 send_dbcmd(0x0e840300 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002729
2730 tmp =
2731 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2732 _reg_PI_MR11_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002733 send_dbcmd(0x0e840b00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002734
2735 tmp =
2736 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2737 _reg_PI_MR12_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002738 send_dbcmd(0x0e840c00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002739
2740 tmp =
2741 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2742 _reg_PI_MR14_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002743 send_dbcmd(0x0e840e00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002744 /* MR22 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002745 send_dbcmd(0x0e841616);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002746 }
2747}
2748
2749/*******************************************************************************
2750 * Training handshake functions
2751 ******************************************************************************/
2752static inline uint32_t wait_freqchgreq(uint32_t assert)
2753{
2754 uint32_t dataL;
2755 uint32_t count;
2756 uint32_t ch;
2757 count = 100000;
2758
2759 /* H3 Ver.1.x cannot see frqchg_req */
2760 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2761 return 0;
2762 }
2763
2764 if (assert) {
2765 do {
2766 dataL = 1;
2767 foreach_vch(ch) {
2768 dataL &= mmio_read_32(DBSC_DBPDSTAT(ch));
2769 }
2770 count = count - 1;
2771 } while (((dataL & 0x01) != 0x01) & (count != 0));
2772 } else {
2773 do {
2774 dataL = 0;
2775 foreach_vch(ch) {
2776 dataL |= mmio_read_32(DBSC_DBPDSTAT(ch));
2777 }
2778 count = count - 1;
2779 } while (((dataL & 0x01) != 0x00) & (count != 0));
2780 }
2781
2782 return (count == 0);
2783}
2784
2785static inline void set_freqchgack(uint32_t assert)
2786{
2787 uint32_t ch;
2788 uint32_t dataL;
2789 if (assert)
2790 dataL = 0x0CF20000;
2791 else
2792 dataL = 0x00000000;
2793
2794 foreach_vch(ch)
2795 mmio_write_32(DBSC_DBPDCNT2(ch), dataL);
2796}
2797
2798static inline void set_dfifrequency(uint32_t freq)
2799{
2800 uint32_t ch;
2801 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2802 foreach_vch(ch)
2803 mmio_clrsetbits_32(DBSC_DBPDCNT1(ch), 0x1fU, freq);
2804 } else {
2805 foreach_vch(ch) {
2806 mmio_clrsetbits_32(DBSC_DBDFICNT(ch), 0x1fU << 24,
2807 (freq << 24));
2808 }
2809 }
2810 dsb_sev();
2811}
2812
2813static uint32_t pll3_freq(uint32_t on)
2814{
2815 uint32_t timeout;
2816
2817 timeout = wait_freqchgreq(1);
2818
2819 if (timeout) {
2820 return (1);
2821 }
2822
2823 pll3_control(on);
2824 set_dfifrequency(on);
2825
2826 set_freqchgack(1);
2827 timeout = wait_freqchgreq(0);
2828 set_freqchgack(0);
2829
2830 if (timeout) {
Marek Vasut56519892019-01-21 23:11:33 +01002831 FATAL_MSG("BL2: Time out[2]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002832 return (1);
2833 }
2834 return (0);
2835}
2836
2837/*******************************************************************************
2838 * update dly
2839 ******************************************************************************/
2840static void update_dly(void)
2841{
2842 ddr_setval_ach(_reg_SC_PHY_MANUAL_UPDATE, 0x01);
2843 ddr_setval_ach(_reg_PHY_ADRCTL_MANUAL_UPDATE, 0x01);
2844}
2845
2846/*******************************************************************************
2847 * training by pi
2848 ******************************************************************************/
2849static uint32_t pi_training_go(void)
2850{
2851 uint32_t flag;
2852 uint32_t dataL;
2853 uint32_t retry;
2854 const uint32_t RETRY_MAX = 4096 * 16;
2855 uint32_t ch;
2856
2857 uint32_t mst_ch;
2858 uint32_t cur_frq;
2859 uint32_t complete;
2860 uint32_t frqchg_req;
2861
2862 /* ********************************************************************* */
2863
2864 /***********************************************************************
2865 pi_start
2866 ***********************************************************************/
2867 ddr_setval_ach(_reg_PI_START, 0x01);
2868 foreach_vch(ch)
2869 ddr_getval(ch, _reg_PI_INT_STATUS);
2870
2871 /* set dfi_phymstr_ack = 1 */
2872 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000001);
2873 dsb_sev();
2874
2875 /***********************************************************************
2876 wait pi_int_status[0]
2877 ***********************************************************************/
2878 mst_ch = 0;
2879 flag = 0;
2880 complete = 0;
2881 cur_frq = 0;
2882 retry = RETRY_MAX;
2883 do {
2884 frqchg_req = mmio_read_32(DBSC_DBPDSTAT(mst_ch)) & 0x01;
2885
2886 /* H3 Ver.1.x cannot see frqchg_req */
2887 if ((Prr_Product == PRR_PRODUCT_H3)
2888 && (Prr_Cut <= PRR_PRODUCT_11)) {
2889 if ((retry % 4096) == 1) {
2890 frqchg_req = 1;
2891 } else {
2892 frqchg_req = 0;
2893 }
2894 }
2895
2896 if (frqchg_req) {
2897 if (cur_frq) {
2898 /* Low frequency */
2899 flag = pll3_freq(0);
2900 cur_frq = 0;
2901 } else {
2902 /* High frequency */
2903 flag = pll3_freq(1);
2904 cur_frq = 1;
2905 }
2906 if (flag)
2907 break;
2908 } else {
2909 if (cur_frq) {
2910 foreach_vch(ch) {
2911 if (complete & (1U << ch))
2912 continue;
2913 dataL =
2914 ddr_getval(ch, _reg_PI_INT_STATUS);
2915 if (dataL & 0x01) {
2916 complete |= (1U << ch);
2917 }
2918 }
2919 if (complete == ddr_phyvalid)
2920 break;
2921 }
2922 }
2923 } while (--retry);
2924 foreach_vch(ch) {
2925 /* dummy read */
2926 dataL = ddr_getval_s(ch, 0, _reg_PHY_CAL_RESULT2_OBS_0);
2927 dataL = ddr_getval(ch, _reg_PI_INT_STATUS);
2928 ddr_setval(ch, _reg_PI_INT_ACK, dataL);
2929 }
2930 if (ddrphy_regif_chk()) {
2931 return (0xfd);
2932 }
2933 return complete;
2934}
2935
2936/*******************************************************************************
2937 * Initialize ddr
2938 ******************************************************************************/
2939static uint32_t init_ddr(void)
2940{
2941 int32_t i;
2942 uint32_t dataL;
2943 uint32_t phytrainingok;
Marek Vasut6c245a52018-12-12 18:06:39 +01002944 uint32_t ch, slice;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002945 uint32_t err;
2946
2947 MSG_LF("init_ddr:0\n");
2948
2949#ifdef DDR_BACKUPMODE
2950 rcar_dram_get_boot_status(&ddrBackup);
2951#endif
2952
2953 /***********************************************************************
2954 unlock phy
2955 ***********************************************************************/
2956 /* Unlock DDRPHY register(AGAIN) */
2957 foreach_vch(ch)
2958 mmio_write_32(DBSC_DBPDLK(ch), 0x0000A55A);
2959 dsb_sev();
2960
2961 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
2962 || (Prr_Product == PRR_PRODUCT_M3N)
2963 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
2964 reg_ddrphy_write_a(0x00001010, 0x01000001);
2965 else
2966 reg_ddrphy_write_a(0x00001010, 0x00000001);
2967 /***********************************************************************
2968 dbsc register pre-setting
2969 ***********************************************************************/
2970 dbsc_regset_pre();
2971
2972 /***********************************************************************
2973 load ddrphy registers
2974 ***********************************************************************/
2975
2976 ddrtbl_load();
2977
2978 /***********************************************************************
2979 configure ddrphy registers
2980 ***********************************************************************/
2981 ddr_config();
2982
2983 /***********************************************************************
2984 dfi_reset assert
2985 ***********************************************************************/
2986 foreach_vch(ch)
2987 mmio_write_32(DBSC_DBPDCNT0(ch), 0x01);
2988 dsb_sev();
2989
2990 /***********************************************************************
2991 dbsc register set
2992 ***********************************************************************/
2993 dbsc_regset();
2994 MSG_LF("init_ddr:1\n");
2995
2996 /***********************************************************************
2997 dfi_reset negate
2998 ***********************************************************************/
2999 foreach_vch(ch)
3000 mmio_write_32(DBSC_DBPDCNT0(ch), 0x00);
3001 dsb_sev();
3002
3003 /***********************************************************************
3004 dfi_init_start (start ddrphy)
3005 ***********************************************************************/
3006 err = dfi_init_start();
3007 if (err) {
3008 return INITDRAM_ERR_I;
3009 }
3010 MSG_LF("init_ddr:2\n");
3011
3012 /***********************************************************************
3013 ddr backupmode end
3014 ***********************************************************************/
3015#ifdef DDR_BACKUPMODE
3016 if (ddrBackup) {
Marek Vasut56519892019-01-21 23:11:33 +01003017 NOTICE("BL2: [WARM_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003018 } else {
Marek Vasut56519892019-01-21 23:11:33 +01003019 NOTICE("BL2: [COLD_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003020 }
3021 err = rcar_dram_update_boot_status(ddrBackup);
3022 if (err) {
Marek Vasut56519892019-01-21 23:11:33 +01003023 NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003024 return INITDRAM_ERR_I;
3025 }
3026#endif
3027 MSG_LF("init_ddr:3\n");
3028
3029 /***********************************************************************
3030 override term code after dfi_init_complete
3031 ***********************************************************************/
3032 err = set_term_code();
3033 if (err) {
3034 return INITDRAM_ERR_I;
3035 }
3036 MSG_LF("init_ddr:4\n");
3037
3038 /***********************************************************************
3039 rx offset calibration
3040 ***********************************************************************/
3041 if ((Prr_Cut > PRR_PRODUCT_11) || (Prr_Product == PRR_PRODUCT_M3N)
3042 || (Prr_Product == PRR_PRODUCT_V3H)) {
3043 err = rx_offset_cal_hw();
3044 } else {
3045 err = rx_offset_cal();
3046 }
3047 if (err)
3048 return (INITDRAM_ERR_O);
3049 MSG_LF("init_ddr:5\n");
3050
Marek Vasut6c245a52018-12-12 18:06:39 +01003051 /* PDX */
3052 send_dbcmd(0x08840001);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003053
3054 /***********************************************************************
3055 check register i/f is alive
3056 ***********************************************************************/
3057 err = ddrphy_regif_chk();
3058 if (err) {
3059 return (INITDRAM_ERR_O);
3060 }
3061 MSG_LF("init_ddr:6\n");
3062
3063 /***********************************************************************
3064 phy initialize end
3065 ***********************************************************************/
3066
3067 /***********************************************************************
3068 setup DDR mode registers
3069 ***********************************************************************/
3070 /* CMOS MODE */
3071 change_lpddr4_en(0);
3072
Marek Vasut6c245a52018-12-12 18:06:39 +01003073 /* MRS */
3074 ddr_register_set();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003075
3076 /* ZQCAL start */
Marek Vasut6c245a52018-12-12 18:06:39 +01003077 send_dbcmd(0x0d84004F);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003078
3079 /* ZQLAT */
Marek Vasut6c245a52018-12-12 18:06:39 +01003080 send_dbcmd(0x0d840051);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003081
3082 /***********************************************************************
3083 Thermal sensor setting
3084 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003085 /* THCTR Bit6: PONM=0 , Bit0: THSST=1 */
3086 dataL = (mmio_read_32(THS1_THCTR) & 0xFFFFFFBF) | 0x00000001;
3087 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003088
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003089 /* LPDDR4 MODE */
3090 change_lpddr4_en(1);
3091
3092 MSG_LF("init_ddr:7\n");
3093
3094 /***********************************************************************
3095 mask CS_MAP if RANKx is not found
3096 ***********************************************************************/
3097 foreach_vch(ch) {
3098 dataL = ddr_getval(ch, _reg_PI_CS_MAP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003099 if (!(ch_have_this_cs[1] & (1U << ch)))
3100 dataL = dataL & 0x05;
3101 ddr_setval(ch, _reg_PI_CS_MAP, dataL);
3102 }
3103
3104 /***********************************************************************
3105 exec pi_training
3106 ***********************************************************************/
3107 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00);
Marek Vasut6c245a52018-12-12 18:06:39 +01003108
3109 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003110 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003111 } else {
3112 foreach_vch(ch) {
3113 for (slice = 0; slice < SLICE_CNT; slice++) {
3114 ddr_setval_s(ch, slice,
3115 _reg_PHY_PER_CS_TRAINING_EN,
3116 ((ch_have_this_cs[1]) >> ch)
3117 & 0x01);
3118 }
3119 }
3120 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003121
3122 phytrainingok = pi_training_go();
3123
3124 if (ddr_phyvalid != (phytrainingok & ddr_phyvalid)) {
3125 return (INITDRAM_ERR_T | phytrainingok);
3126 }
3127
3128 MSG_LF("init_ddr:8\n");
3129
3130 /***********************************************************************
3131 CACS DLY ADJUST
3132 ***********************************************************************/
3133 dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
3134 foreach_vch(ch) {
3135 int16_t adj;
3136 for (i = 0; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
3137 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
3138 ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3139 dataL + adj);
3140 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003141
3142 if (ddr_phycaslice == 1) {
3143 for (i = 0; i < 6; i++) {
3144 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM]);
3145 ddr_setval_s(ch, 2, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3146 dataL + adj
3147 );
3148 }
3149 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003150 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003151
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003152 update_dly();
3153 MSG_LF("init_ddr:9\n");
3154
3155 /***********************************************************************
3156 H3 fix rd latency to avoid bug in elasitic buffe
3157 ***********************************************************************/
3158 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3159 adjust_rddqs_latency();
3160 }
3161
3162 /***********************************************************************
3163 Adjust Write path latency
3164 ***********************************************************************/
3165 if (ddrtbl_getval
3166 (_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD))
3167 adjust_wpath_latency();
3168
3169 /***********************************************************************
3170 RDQLVL Training
3171 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003172 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003173 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x01);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003174 }
3175
3176 err = rdqdm_man();
Marek Vasut6c245a52018-12-12 18:06:39 +01003177
3178 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
3179 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x00);
3180 }
3181
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003182 if (err) {
3183 return (INITDRAM_ERR_T);
3184 }
3185 update_dly();
3186 MSG_LF("init_ddr:10\n");
3187
3188 /***********************************************************************
3189 WDQLVL Training
3190 ***********************************************************************/
3191 err = wdqdm_man();
3192 if (err) {
3193 return (INITDRAM_ERR_T);
3194 }
3195 update_dly();
3196 MSG_LF("init_ddr:11\n");
3197
3198 /***********************************************************************
3199 training complete, setup dbsc
3200 ***********************************************************************/
3201 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3202 || (Prr_Product == PRR_PRODUCT_M3N)
3203 || (Prr_Product == PRR_PRODUCT_V3H)) {
3204 ddr_setval_ach_as(_reg_PHY_DFI40_POLARITY, 0x00);
3205 ddr_setval_ach(_reg_PI_DFI40_POLARITY, 0x00);
3206 }
3207
3208 dbsc_regset_post();
3209 MSG_LF("init_ddr:12\n");
3210
3211 return phytrainingok;
3212}
3213
3214/*******************************************************************************
3215 * SW LEVELING COMMON
3216 ******************************************************************************/
3217static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick)
3218{
3219 uint32_t ch;
3220 uint32_t dataL;
3221 uint32_t retry;
3222 uint32_t waiting;
3223 uint32_t err;
3224
3225 const uint32_t RETRY_MAX = 0x1000;
3226
3227 err = 0;
3228 /* set EXIT -> OP_DONE is cleared */
3229 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3230
3231 /* kick */
3232 foreach_vch(ch) {
3233 if (ch_have_this_cs[ddr_csn % 2] & (1U << ch)) {
3234 ddr_setval(ch, reg_cs, ddr_csn);
3235 ddr_setval(ch, reg_kick, 0x01);
3236 }
3237 }
3238 foreach_vch(ch) {
3239 /*PREPARE ADDR REGISTER (for SWLVL_OP_DONE) */
3240 ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3241 }
3242 waiting = ch_have_this_cs[ddr_csn % 2];
3243 dsb_sev();
3244 retry = RETRY_MAX;
3245 do {
3246 foreach_vch(ch) {
3247 if (!(waiting & (1U << ch)))
3248 continue;
3249 dataL = ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3250 if (dataL & 0x01)
3251 waiting &= ~(1U << ch);
3252 }
3253 retry--;
3254 } while (waiting && (retry > 0));
3255 if (retry == 0) {
3256 err = 1;
3257 }
3258
3259 dsb_sev();
3260 /* set EXIT -> OP_DONE is cleared */
3261 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3262 dsb_sev();
3263
3264 return err;
3265}
3266
3267/*******************************************************************************
3268 * WDQ TRAINING
3269 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003270#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003271static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3272{
3273 int32_t i, k;
3274 uint32_t cs, slice;
3275 uint32_t dataL;
3276
3277 /***********************************************************************
3278 clr of training results buffer
3279 ***********************************************************************/
3280 cs = ddr_csn % 2;
3281 dataL = Boardcnf->dqdm_dly_w;
3282 for (slice = 0; slice < SLICE_CNT; slice++) {
3283 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3284 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3285 continue;
3286
3287 for (i = 0; i <= 8; i++) {
3288 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch))
3289 wdqdm_dly[ch][cs][slice][i] =
3290 wdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3291 else
3292 wdqdm_dly[ch][cs][slice][i] = dataL;
3293 wdqdm_le[ch][cs][slice][i] = 0;
3294 wdqdm_te[ch][cs][slice][i] = 0;
3295 }
3296 wdqdm_st[ch][cs][slice] = 0;
3297 wdqdm_win[ch][cs][slice] = 0;
3298 }
3299}
3300
3301static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3302{
3303 int32_t i, k;
3304 uint32_t cs, slice;
3305 uint32_t dataL;
3306 uint32_t err;
3307 const uint32_t _par_WDQLVL_RETRY_THRES = 0x7c0;
3308
3309 int32_t min_win;
3310 int32_t win;
3311 int8_t _adj;
3312 int16_t adj;
3313 uint32_t dq;
3314
3315 /***********************************************************************
3316 analysis of training results
3317 ***********************************************************************/
3318 err = 0;
3319 for (slice = 0; slice < SLICE_CNT; slice += 1) {
3320 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3321 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3322 continue;
3323
3324 cs = ddr_csn % 2;
3325 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003326 for (i = 0; i < 9; i++) {
3327 dq = slice * 8 + i;
3328 if (i == 8)
3329 _adj = Boardcnf->ch[ch].dm_adj_w[slice];
3330 else
3331 _adj = Boardcnf->ch[ch].dq_adj_w[dq];
3332 adj = _f_scale_adj(_adj);
3333
3334 dataL =
3335 ddr_getval_s(ch, slice,
3336 _reg_PHY_CLK_WRX_SLAVE_DELAY[i]) + adj;
3337 ddr_setval_s(ch, slice, _reg_PHY_CLK_WRX_SLAVE_DELAY[i],
3338 dataL);
3339 wdqdm_dly[ch][cs][slice][i] = dataL;
3340 }
3341 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x00);
3342 dataL = ddr_getval_s(ch, slice, _reg_PHY_WDQLVL_STATUS_OBS);
3343 wdqdm_st[ch][cs][slice] = dataL;
3344 min_win = INT_LEAST32_MAX;
3345 for (i = 0; i <= 8; i++) {
3346 ddr_setval_s(ch, slice, _reg_PHY_WDQLVL_DQDM_OBS_SELECT,
3347 i);
3348
3349 dataL =
3350 ddr_getval_s(ch, slice,
3351 _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS);
3352 wdqdm_te[ch][cs][slice][i] = dataL;
3353 dataL =
3354 ddr_getval_s(ch, slice,
3355 _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS);
3356 wdqdm_le[ch][cs][slice][i] = dataL;
3357 win =
3358 (int32_t) wdqdm_te[ch][cs][slice][i] -
3359 wdqdm_le[ch][cs][slice][i];
3360 if (min_win > win)
3361 min_win = win;
3362 if (dataL >= _par_WDQLVL_RETRY_THRES)
3363 err = 2;
3364 }
3365 wdqdm_win[ch][cs][slice] = min_win;
Marek Vasut6c245a52018-12-12 18:06:39 +01003366 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003367 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003368 } else {
3369 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN,
3370 ((ch_have_this_cs[1]) >> ch) & 0x01);
3371 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003372 }
3373 return err;
3374}
Marek Vasut6c245a52018-12-12 18:06:39 +01003375#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003376
3377static void wdqdm_cp(uint32_t ddr_csn, uint32_t restore)
3378{
3379 uint32_t i;
3380 uint32_t ch, slice;
3381 uint32_t tgt_cs, src_cs;
3382 uint32_t tmp_r;
3383
3384 /***********************************************************************
3385 copy of training results
3386 ***********************************************************************/
3387 foreach_vch(ch) {
3388 for (tgt_cs = 0; tgt_cs < CS_CNT; tgt_cs++) {
3389 for (slice = 0; slice < SLICE_CNT; slice++) {
3390 ddr_setval_s(ch, slice,
3391 _reg_PHY_PER_CS_TRAINING_INDEX,
3392 tgt_cs);
3393 src_cs = ddr_csn % 2;
3394 if (!(ch_have_this_cs[1] & (1U << ch)))
3395 src_cs = 0;
3396 for (i = 0; i <= 4; i += 4) {
3397 if (restore)
3398 tmp_r =
3399 rdqdm_dly[ch][tgt_cs][slice]
3400 [i];
3401 else
3402 tmp_r =
3403 rdqdm_dly[ch][src_cs][slice]
3404 [i];
3405
3406 ddr_setval_s(ch, slice,
3407 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY
3408 [i], tmp_r);
3409 }
3410 }
3411 }
3412 }
3413}
3414
3415static uint32_t wdqdm_man1(void)
3416{
3417 int32_t k;
3418 uint32_t ch, cs, slice;
3419 uint32_t ddr_csn;
3420 uint32_t dataL;
3421 uint32_t err;
Marek Vasut6c245a52018-12-12 18:06:39 +01003422 uint32_t high_dq[DRAM_CH_CNT];
3423 uint32_t mr14_csab0_bak[DRAM_CH_CNT];
3424#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003425 uint32_t err_flg;
Marek Vasut6c245a52018-12-12 18:06:39 +01003426#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003427
3428 /***********************************************************************
3429 manual execution of training
3430 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003431 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3432 foreach_vch(ch) {
3433 high_dq[ch] = 0;
3434 for (slice = 0; slice < SLICE_CNT; slice++) {
3435 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3436 if (k >= 2)
3437 high_dq[ch] |= (1U << slice);
3438 }
3439 ddr_setval(ch, _reg_PI_16BIT_DRAM_CONNECT, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003440 }
3441 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003442 err = 0;
3443 /* CLEAR PREV RESULT */
3444 for (cs = 0; cs < CS_CNT; cs++) {
3445 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_INDEX, cs);
3446 if (((Prr_Product == PRR_PRODUCT_H3)
3447 && (Prr_Cut > PRR_PRODUCT_11))
3448 || (Prr_Product == PRR_PRODUCT_M3N)
3449 || (Prr_Product == PRR_PRODUCT_V3H)) {
3450 ddr_setval_ach_as(_reg_SC_PHY_WDQLVL_CLR_PREV_RESULTS,
3451 0x01);
3452 } else {
3453 ddr_setval_ach_as(_reg_PHY_WDQLVL_CLR_PREV_RESULTS,
3454 0x01);
3455 }
3456 }
3457 ddrphy_regif_idle();
3458
Marek Vasut6c245a52018-12-12 18:06:39 +01003459#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003460 err_flg = 0;
Marek Vasut6c245a52018-12-12 18:06:39 +01003461#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003462 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3463 if ((Prr_Product == PRR_PRODUCT_H3)
3464 && (Prr_Cut <= PRR_PRODUCT_11)) {
3465 foreach_vch(ch) {
3466 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3467 dataL &= ~(0x00ffU << 16);
3468
3469 if (ddr_csn >= 2)
3470 k = (high_dq[ch] ^ 0x0f);
3471 else
3472 k = high_dq[ch];
3473 dataL |= (k << 16);
3474 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3475 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, k);
3476 }
3477 }
3478 if (((Prr_Product == PRR_PRODUCT_H3)
3479 && (Prr_Cut <= PRR_PRODUCT_11))
3480 || ((Prr_Product == PRR_PRODUCT_M3)
3481 && (Prr_Cut == PRR_PRODUCT_10))) {
3482 wdqdm_cp(ddr_csn, 0);
3483 }
3484
3485 foreach_vch(ch) {
3486 dataL =
3487 ddr_getval(ch,
3488 _reg_PI_MR14_DATA_Fx_CSx[1][ddr_csn]);
3489 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0], dataL);
3490 }
3491
3492 /* KICK WDQLVL */
3493 err = swlvl1(ddr_csn, _reg_PI_WDQLVL_CS, _reg_PI_WDQLVL_REQ);
3494 if (err)
3495 goto err_exit;
3496
3497 if (ddr_csn == 0)
3498 foreach_vch(ch) {
3499 mr14_csab0_bak[ch] =
3500 ddr_getval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0]);
3501 } else
3502 foreach_vch(ch) {
3503 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0],
3504 mr14_csab0_bak[ch]);
3505 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003506#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003507 foreach_vch(ch) {
3508 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3509 wdqdm_clr1(ch, ddr_csn);
3510 continue;
3511 }
3512 err = wdqdm_ana1(ch, ddr_csn);
3513 if (err)
3514 err_flg |= (1U << (ddr_csn * 4 + ch));
3515 ddrphy_regif_idle();
3516 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003517#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003518 }
3519err_exit:
Marek Vasut6c245a52018-12-12 18:06:39 +01003520#ifndef DDR_FAST_INIT
3521 err |= err_flg;
3522#endif/* DDR_FAST_INIT */
3523 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3524 ddr_setval_ach(_reg_PI_16BIT_DRAM_CONNECT, 0x01);
3525 foreach_vch(ch) {
3526 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3527 dataL &= ~(0x00ffU << 16);
3528 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3529 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, 0x00);
3530 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003531 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003532 return (err);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003533}
3534
3535static uint32_t wdqdm_man(void)
3536{
3537 uint32_t err, retry_cnt;
3538 const uint32_t retry_max = 0x10;
3539
3540 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, (DBSC_DBTR(11) & 0xFF) + 12);
3541 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3542 || (Prr_Product == PRR_PRODUCT_M3N)
3543 || (Prr_Product == PRR_PRODUCT_V3H)) {
3544 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR_F1,
3545 (DBSC_DBTR(12) & 0xFF) + 1);
3546 } else {
3547 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR,
3548 (DBSC_DBTR(12) & 0xFF) + 1);
3549 }
3550 ddr_setval_ach(_reg_PI_TRFC_F1, (DBSC_DBTR(13) & 0x1FF));
3551
3552 retry_cnt = 0;
3553 do {
3554 if ((Prr_Product == PRR_PRODUCT_H3)
3555 && (Prr_Cut <= PRR_PRODUCT_11)) {
3556 err = wdqdm_man1();
3557 } else {
3558 uint32_t ch, ddr_csn, mr14_bkup[4][4];
3559
3560 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x01);
3561 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3562 0x01);
3563 if ((Prr_Product == PRR_PRODUCT_M3N)
3564 || (Prr_Product == PRR_PRODUCT_V3H)) {
3565 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3566 0x0C);
3567 } else {
3568 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0C);
3569 }
3570 dsb_sev();
3571 err = wdqdm_man1();
3572 foreach_vch(ch) {
3573 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3574 mr14_bkup[ch][ddr_csn] =
3575 ddr_getval(ch,
3576 _reg_PI_MR14_DATA_Fx_CSx
3577 [1][ddr_csn]);
3578 dsb_sev();
3579 }
3580 }
3581
3582 if ((Prr_Product == PRR_PRODUCT_M3N)
3583 || (Prr_Product == PRR_PRODUCT_V3H)) {
3584 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3585 0x04);
3586 } else {
3587 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x04);
3588 }
3589 pvtcode_update();
3590 err = wdqdm_man1();
3591 foreach_vch(ch) {
3592 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3593 mr14_bkup[ch][ddr_csn] =
3594 (mr14_bkup[ch][ddr_csn] +
3595 ddr_getval(ch,
3596 _reg_PI_MR14_DATA_Fx_CSx
3597 [1][ddr_csn])) / 2;
3598 ddr_setval(ch,
3599 _reg_PI_MR14_DATA_Fx_CSx[1]
3600 [ddr_csn],
3601 mr14_bkup[ch][ddr_csn]);
3602 }
3603 }
3604
3605 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3606 0x00);
3607 if ((Prr_Product == PRR_PRODUCT_M3N)
3608 || (Prr_Product == PRR_PRODUCT_V3H)) {
3609 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3610 0x00);
3611 ddr_setval_ach
3612 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F1,
3613 0x00);
3614 ddr_setval_ach
3615 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1,
3616 0x00);
3617 } else {
3618 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x00);
3619 ddr_setval_ach
3620 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT,
3621 0x00);
3622 ddr_setval_ach
3623 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT,
3624 0x00);
3625 }
3626 ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE,
3627 0x00);
3628
3629 pvtcode_update2();
3630 err = wdqdm_man1();
3631 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
3632 }
3633 } while (err && (++retry_cnt < retry_max));
3634
3635 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
3636 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_10))) {
3637 wdqdm_cp(0, 1);
3638 }
3639
3640 return (retry_cnt >= retry_max);
3641}
3642
3643/*******************************************************************************
3644 * RDQ TRAINING
3645 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003646#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003647static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3648{
3649 int32_t i, k;
3650 uint32_t cs, slice;
3651 uint32_t dataL;
3652
3653 /***********************************************************************
3654 clr of training results buffer
3655 ***********************************************************************/
3656 cs = ddr_csn % 2;
3657 dataL = Boardcnf->dqdm_dly_r;
3658 for (slice = 0; slice < SLICE_CNT; slice++) {
3659 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3660 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3661 continue;
3662
3663 for (i = 0; i <= 8; i++) {
3664 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) {
3665 rdqdm_dly[ch][cs][slice][i] =
3666 rdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3667 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] =
3668 rdqdm_dly[ch][CS_CNT - 1 - cs][slice +
3669 SLICE_CNT]
3670 [i];
3671 } else {
3672 rdqdm_dly[ch][cs][slice][i] = dataL;
3673 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3674 }
3675 rdqdm_le[ch][cs][slice][i] = 0;
3676 rdqdm_le[ch][cs][slice + SLICE_CNT][i] = 0;
3677 rdqdm_te[ch][cs][slice][i] = 0;
3678 rdqdm_te[ch][cs][slice + SLICE_CNT][i] = 0;
3679 rdqdm_nw[ch][cs][slice][i] = 0;
3680 rdqdm_nw[ch][cs][slice + SLICE_CNT][i] = 0;
3681 }
3682 rdqdm_st[ch][cs][slice] = 0;
3683 rdqdm_win[ch][cs][slice] = 0;
3684 }
3685}
3686
3687static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3688{
3689 int32_t i, k;
3690 uint32_t cs, slice;
3691 uint32_t dataL;
3692 uint32_t err;
3693 int8_t _adj;
3694 int16_t adj;
3695 uint32_t dq;
3696
3697 /***********************************************************************
3698 analysis of training results
3699 ***********************************************************************/
3700 err = 0;
3701 for (slice = 0; slice < SLICE_CNT; slice++) {
3702 int32_t min_win;
3703 int32_t win;
3704 uint32_t rdq_status_obs_select;
3705 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3706 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3707 continue;
3708
3709 cs = ddr_csn % 2;
3710 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
3711 ddrphy_regif_idle();
3712
3713 ddr_getval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX);
3714 ddrphy_regif_idle();
3715
3716 for (i = 0; i <= 8; i++) {
3717 dq = slice * 8 + i;
3718 if (i == 8)
3719 _adj = Boardcnf->ch[ch].dm_adj_r[slice];
3720 else
3721 _adj = Boardcnf->ch[ch].dq_adj_r[dq];
3722
3723 adj = _f_scale_adj(_adj);
3724
3725 dataL =
3726 ddr_getval_s(ch, slice,
3727 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) +
3728 adj;
3729 ddr_setval_s(ch, slice,
3730 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i],
3731 dataL);
3732 rdqdm_dly[ch][cs][slice][i] = dataL;
3733
3734 dataL =
3735 ddr_getval_s(ch, slice,
3736 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) +
3737 adj;
3738 ddr_setval_s(ch, slice,
3739 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i],
3740 dataL);
3741 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3742 }
3743 min_win = INT_LEAST32_MAX;
3744 for (i = 0; i <= 8; i++) {
3745 dataL =
3746 ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS);
3747 rdqdm_st[ch][cs][slice] = dataL;
3748 rdqdm_st[ch][cs][slice + SLICE_CNT] = dataL;
3749 /* k : rise/fall */
3750 for (k = 0; k < 2; k++) {
3751 if (i == 8) {
3752 rdq_status_obs_select = 16 + 8 * k;
3753 } else {
3754 rdq_status_obs_select = i + k * 8;
3755 }
3756 ddr_setval_s(ch, slice,
3757 _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3758 rdq_status_obs_select);
3759
3760 dataL =
3761 ddr_getval_s(ch, slice,
3762 _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3763 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i] =
3764 dataL;
3765
3766 dataL =
3767 ddr_getval_s(ch, slice,
3768 _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3769 rdqdm_te[ch][cs][slice + SLICE_CNT * k][i] =
3770 dataL;
3771
3772 dataL =
3773 ddr_getval_s(ch, slice,
3774 _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS);
3775 rdqdm_nw[ch][cs][slice + SLICE_CNT * k][i] =
3776 dataL;
3777
3778 win =
3779 (int32_t) rdqdm_te[ch][cs][slice +
3780 SLICE_CNT *
3781 k][i] -
3782 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i];
3783 if (i != 8) {
3784 if (min_win > win)
3785 min_win = win;
3786 }
3787 }
3788 }
3789 rdqdm_win[ch][cs][slice] = min_win;
3790 if (min_win <= 0) {
3791 err = 2;
3792 }
3793 }
3794 return (err);
3795}
Marek Vasut6c245a52018-12-12 18:06:39 +01003796#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003797
3798static uint32_t rdqdm_man1(void)
3799{
3800 uint32_t ch;
3801 uint32_t ddr_csn;
Marek Vasut6c245a52018-12-12 18:06:39 +01003802#ifdef DDR_FAST_INIT
3803 uint32_t slice;
3804#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003805 uint32_t err;
3806
3807 /***********************************************************************
3808 manual execution of training
3809 ***********************************************************************/
3810 err = 0;
3811
Marek Vasut6c245a52018-12-12 18:06:39 +01003812 for (ddr_csn = 0; ddr_csn < CS_CNT; ddr_csn++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003813 /* KICK RDQLVL */
3814 err = swlvl1(ddr_csn, _reg_PI_RDLVL_CS, _reg_PI_RDLVL_REQ);
3815 if (err)
3816 goto err_exit;
Marek Vasut6c245a52018-12-12 18:06:39 +01003817#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003818 foreach_vch(ch) {
3819 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3820 rdqdm_clr1(ch, ddr_csn);
3821 ddrphy_regif_idle();
3822 continue;
3823 }
3824 err = rdqdm_ana1(ch, ddr_csn);
3825 ddrphy_regif_idle();
3826 if (err)
3827 goto err_exit;
3828 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003829#else/* DDR_FAST_INIT */
3830 foreach_vch(ch) {
3831 if (ch_have_this_cs[ddr_csn] & (1U << ch)) {
3832 for (slice = 0; slice < SLICE_CNT; slice++) {
3833 if (ddr_getval_s(ch, slice,
3834 _reg_PHY_RDLVL_STATUS_OBS) !=
3835 0x0D00FFFF) {
3836 err = (1U << ch) |
3837 (0x10U << slice);
3838 goto err_exit;
3839 }
3840 }
3841 }
3842 if (((Prr_Product == PRR_PRODUCT_H3)
3843 && (Prr_Cut <= PRR_PRODUCT_11))
3844 || ((Prr_Product == PRR_PRODUCT_M3)
3845 && (Prr_Cut <= PRR_PRODUCT_10))) {
3846 uint32_t i, adj, dataL;
3847
3848 for (slice = 0; slice < SLICE_CNT; slice++) {
3849 for (i = 0; i <= 8; i++) {
3850 if (i == 8)
3851 adj = _f_scale_adj(Boardcnf->ch[ch].dm_adj_r[slice]);
3852 else
3853 adj = _f_scale_adj(Boardcnf->ch[ch].dq_adj_r[slice * 8 + i]);
3854 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, ddr_csn);
3855 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj;
3856 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], dataL);
3857 rdqdm_dly[ch][ddr_csn][slice][i] = dataL;
3858 rdqdm_dly[ch][ddr_csn | 1][slice][i] = dataL;
3859
3860 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj;
3861 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], dataL);
3862 rdqdm_dly[ch][ddr_csn][slice + SLICE_CNT][i] = dataL;
3863 rdqdm_dly[ch][ddr_csn | 1][slice + SLICE_CNT][i] = dataL;
3864 }
3865 }
3866 }
3867 }
3868 ddrphy_regif_idle();
3869
3870#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003871 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003872
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003873err_exit:
3874 return (err);
3875}
3876
3877static uint32_t rdqdm_man(void)
3878{
3879 uint32_t err, retry_cnt;
3880 const uint32_t retry_max = 0x01;
3881
3882 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3883 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3884 _reg_PHY_DQ_TSEL_ENABLE));
3885 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3886 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3887 _reg_PHY_DQS_TSEL_ENABLE));
3888 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3889 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3890 _reg_PHY_DQ_TSEL_SELECT));
3891 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3892 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3893 _reg_PHY_DQS_TSEL_SELECT));
3894
3895 retry_cnt = 0;
3896 do {
3897 err = rdqdm_man1();
3898 ddrphy_regif_idle();
3899 } while (err && (++retry_cnt < retry_max));
3900 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3901 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3902 _reg_PHY_DQ_TSEL_ENABLE));
3903 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3904 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3905 _reg_PHY_DQS_TSEL_ENABLE));
3906 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3907 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3908 _reg_PHY_DQ_TSEL_SELECT));
3909 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3910 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3911 _reg_PHY_DQS_TSEL_SELECT));
3912
3913 return (retry_cnt >= retry_max);
3914}
3915
3916/*******************************************************************************
3917 * rx offset calibration
3918 ******************************************************************************/
3919static int32_t _find_change(uint64_t val, uint32_t dir)
3920{
3921 int32_t i;
3922 uint32_t startval;
3923 uint32_t curval;
3924 const uint32_t VAL_END = 0x3f;
3925
3926 if (dir == 0) {
3927 startval = (val & 0x01);
3928 for (i = 1; i <= VAL_END; i++) {
3929 curval = (val >> i) & 0x01;
3930 if (curval != startval)
3931 return (i);
3932 }
3933 return (VAL_END);
3934 } else {
3935 startval = (val >> dir) & 0x01;
3936 for (i = dir - 1; i >= 0; i--) {
3937 curval = (val >> i) & 0x01;
3938 if (curval != startval)
3939 return (i);
3940 }
3941 return (0);
3942 }
3943}
3944
3945static uint32_t _rx_offset_cal_updn(uint32_t code)
3946{
3947 const uint32_t CODE_MAX = 0x40;
3948 uint32_t tmp;
3949
3950 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3951 if (code == 0)
3952 tmp = (1U << 6) | (CODE_MAX - 1);
3953 else if (code <= 0x20)
3954 tmp =
3955 ((CODE_MAX - 1 -
3956 (0x20 - code) * 2) << 6) | (CODE_MAX - 1);
3957 else
3958 tmp =
3959 ((CODE_MAX - 1) << 6) | (CODE_MAX - 1 -
3960 (code - 0x20) * 2);
3961 } else {
3962 if (code == 0)
3963 tmp = (1U << 6) | (CODE_MAX - 1);
3964 else
3965 tmp = (code << 6) | (CODE_MAX - code);
3966 }
3967 return tmp;
3968}
3969
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003970static uint32_t rx_offset_cal(void)
3971{
3972 uint32_t index;
3973 uint32_t code;
3974 const uint32_t CODE_MAX = 0x40;
3975 const uint32_t CODE_STEP = 2;
3976 uint32_t ch, slice;
3977 uint32_t tmp;
3978 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
3979 uint64_t val[DRAM_CH_CNT][SLICE_CNT][_reg_PHY_RX_CAL_X_NUM];
Marek Vasut6c245a52018-12-12 18:06:39 +01003980
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003981 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x01);
3982 foreach_vch(ch) {
3983 for (slice = 0; slice < SLICE_CNT; slice++) {
3984 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
3985 val[ch][slice][index] = 0;
3986 }
3987 }
3988 }
3989
3990 for (code = 0; code < CODE_MAX / CODE_STEP; code++) {
3991 tmp = _rx_offset_cal_updn(code * CODE_STEP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003992 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
3993 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[index], tmp);
3994 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003995 dsb_sev();
3996 ddr_getval_ach_as(_reg_PHY_RX_CAL_OBS, (uint32_t *) tmp_ach_as);
3997
3998 foreach_vch(ch) {
3999 for (slice = 0; slice < SLICE_CNT; slice++) {
4000 tmp = tmp_ach_as[ch][slice];
4001 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM;
4002 index++) {
4003 if (tmp & (1U << index)) {
4004 val[ch][slice][index] |=
4005 (1ULL << code);
4006 } else {
4007 val[ch][slice][index] &=
4008 ~(1ULL << code);
4009 }
4010 }
4011 }
4012 }
4013 }
4014 foreach_vch(ch) {
4015 for (slice = 0; slice < SLICE_CNT; slice++) {
4016 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
4017 uint64_t tmpval;
4018 int32_t lsb, msb;
4019 tmpval = val[ch][slice][index];
4020 lsb = _find_change(tmpval, 0);
4021 msb =
4022 _find_change(tmpval,
4023 (CODE_MAX / CODE_STEP) - 1);
4024 tmp = (lsb + msb) >> 1;
4025
4026 tmp = _rx_offset_cal_updn(tmp * CODE_STEP);
4027 ddr_setval_s(ch, slice,
4028 _reg_PHY_RX_CAL_X[index], tmp);
4029 }
4030 }
4031 }
4032 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004033
4034 return 0;
4035}
4036
4037static uint32_t rx_offset_cal_hw(void)
4038{
4039 uint32_t ch, slice;
4040 uint32_t retry;
4041 uint32_t complete;
4042 uint32_t tmp;
4043 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
4044
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004045 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[9], 0x00);
4046 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
4047 ddr_setval_ach_as(_reg_PHY_RX_CAL_SAMPLE_WAIT, 0x0f);
4048
4049 retry = 0;
4050 while (retry < 4096) {
4051 if ((retry & 0xff) == 0) {
4052 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
4053 }
4054 foreach_vch(ch)
4055 for (slice = 0; slice < SLICE_CNT; slice++)
4056 tmp_ach_as[ch][slice] =
4057 ddr_getval_s(ch, slice, _reg_PHY_RX_CAL_X[9]);
4058
4059 complete = 1;
4060 foreach_vch(ch) {
4061 for (slice = 0; slice < SLICE_CNT; slice++) {
4062 tmp = tmp_ach_as[ch][slice];
4063 tmp = (tmp & 0x3f) + ((tmp >> 6) & 0x3f);
4064 if (((Prr_Product == PRR_PRODUCT_H3)
4065 && (Prr_Cut > PRR_PRODUCT_11))
4066 || (Prr_Product == PRR_PRODUCT_M3N)
4067 || (Prr_Product == PRR_PRODUCT_V3H)) {
4068 if (tmp != 0x3E)
4069 complete = 0;
4070 } else {
4071 if (tmp != 0x40)
4072 complete = 0;
4073 }
4074 }
4075 }
4076 if (complete)
4077 break;
4078
4079 retry++;
4080 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004081
4082 return (complete == 0);
4083}
4084
4085/*******************************************************************************
4086 * adjust rddqs latency
4087 ******************************************************************************/
4088static void adjust_rddqs_latency(void)
4089{
4090 uint32_t ch, slice;
4091 uint32_t dly;
4092 uint32_t maxlatx2;
4093 uint32_t tmp;
4094 uint32_t rdlat_adjx2[SLICE_CNT];
4095 foreach_vch(ch) {
4096 maxlatx2 = 0;
4097 for (slice = 0; slice < SLICE_CNT; slice++) {
4098 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX,
4099 0x00);
4100
4101 dly =
4102 ddr_getval_s(ch, slice,
4103 _reg_PHY_RDDQS_GATE_SLAVE_DELAY);
4104 tmp =
4105 ddr_getval_s(ch, slice,
4106 _reg_PHY_RDDQS_LATENCY_ADJUST);
4107 /* note gate_slave_delay[9] is always 0 */
4108 tmp = (tmp << 1) + (dly >> 8);
4109 rdlat_adjx2[slice] = tmp;
4110 if (maxlatx2 < tmp)
4111 maxlatx2 = tmp;
4112 }
4113 maxlatx2 = ((maxlatx2 + 1) >> 1) << 1;
4114 for (slice = 0; slice < SLICE_CNT; slice++) {
4115 tmp = maxlatx2 - rdlat_adjx2[slice];
4116 tmp = (tmp >> 1);
4117 if (tmp) {
4118 ddr_setval_s(ch, slice, _reg_PHY_RPTR_UPDATE,
4119 ddr_getval_s(ch, slice,
4120 _reg_PHY_RPTR_UPDATE)
4121 + 1);
4122 }
4123 }
4124 }
4125}
4126
4127/*******************************************************************************
4128 * adjust wpath latency
4129 ******************************************************************************/
4130static void adjust_wpath_latency(void)
4131{
4132 uint32_t ch, cs, slice;
4133 uint32_t dly;
4134 uint32_t wpath_add;
4135 const uint32_t _par_EARLY_THRESHOLD_VAL = 0x180;
4136
4137 foreach_vch(ch) {
4138 for (slice = 0; slice < SLICE_CNT; slice += 1) {
4139 for (cs = 0; cs < CS_CNT; cs++) {
4140 ddr_setval_s(ch, slice,
4141 _reg_PHY_PER_CS_TRAINING_INDEX,
4142 cs);
4143 ddr_getval_s(ch, slice,
4144 _reg_PHY_PER_CS_TRAINING_INDEX);
4145 dly =
4146 ddr_getval_s(ch, slice,
4147 _reg_PHY_CLK_WRDQS_SLAVE_DELAY);
4148 if (dly <= _par_EARLY_THRESHOLD_VAL)
4149 continue;
4150
4151 wpath_add =
4152 ddr_getval_s(ch, slice,
4153 _reg_PHY_WRITE_PATH_LAT_ADD);
4154 ddr_setval_s(ch, slice,
4155 _reg_PHY_WRITE_PATH_LAT_ADD,
4156 wpath_add - 1);
4157 }
4158 }
4159 }
4160}
4161
4162/*******************************************************************************
4163 * DDR Initialize entry
4164 ******************************************************************************/
4165int32_t rcar_dram_init(void)
4166{
4167 uint32_t ch, cs;
4168 uint32_t dataL;
4169 uint32_t bus_mbps, bus_mbpsdiv;
4170 uint32_t tmp_tccd;
4171 uint32_t failcount;
4172
4173 /***********************************************************************
4174 Thermal sensor setting
4175 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01004176 dataL = mmio_read_32(CPG_MSTPSR5);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004177 if (dataL & BIT22) { /* case THS/TSC Standby */
4178 dataL &= ~(BIT22);
Marek Vasut6c245a52018-12-12 18:06:39 +01004179 cpg_write_32(CPG_SMSTPCR5, dataL);
4180 while ((BIT22) & mmio_read_32(CPG_MSTPSR5)); /* wait bit=0 */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004181 }
4182
4183 /* THCTR Bit6: PONM=0 , Bit0: THSST=0 */
Marek Vasut6c245a52018-12-12 18:06:39 +01004184 dataL = mmio_read_32(THS1_THCTR) & 0xFFFFFFBE;
4185 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004186
4187 /***********************************************************************
4188 Judge product and cut
4189 ***********************************************************************/
4190#ifdef RCAR_DDR_FIXED_LSI_TYPE
4191#if(RCAR_LSI==RCAR_AUTO)
4192 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4193 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4194#else /* RCAR_LSI */
4195#ifndef RCAR_LSI_CUT
4196 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4197#endif /* RCAR_LSI_CUT */
4198#endif /* RCAR_LSI */
4199#else /* RCAR_DDR_FIXED_LSI_TYPE */
4200 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4201 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4202#endif /* RCAR_DDR_FIXED_LSI_TYPE */
4203
4204 if (Prr_Product == PRR_PRODUCT_H3) {
4205 if (Prr_Cut <= PRR_PRODUCT_11) {
4206 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[0][0];
4207 } else {
4208 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[2][0];
4209 }
4210 } else if (Prr_Product == PRR_PRODUCT_M3) {
4211 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[1][0];
4212 } else if ((Prr_Product == PRR_PRODUCT_M3N)
4213 || (Prr_Product == PRR_PRODUCT_V3H)) {
4214 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[3][0];
4215 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004216 FATAL_MSG("BL2: DDR:Unknown Product\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004217 return 0xff;
4218 }
4219
4220 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01004221 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004222 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4223 } else {
4224 mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
4225 }
4226
4227 /***********************************************************************
4228 Judge board type
4229 ***********************************************************************/
4230 _cnf_BOARDTYPE = boardcnf_get_brd_type();
4231 if (_cnf_BOARDTYPE >= BOARDNUM) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004232 FATAL_MSG("BL2: DDR:Unknown Board\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004233 return 0xff;
4234 }
4235 Boardcnf = (struct _boardcnf *)&boardcnfs[_cnf_BOARDTYPE];
4236
4237/* RCAR_DRAM_SPLIT_2CH (2U) */
4238#if RCAR_DRAM_SPLIT == 2
4239 /***********************************************************************
4240 H3(Test for future H3-N): Swap ch2 and ch1 for 2ch-split
4241 ***********************************************************************/
4242 if ((Prr_Product == PRR_PRODUCT_H3) && (Boardcnf->phyvalid == 0x05)) {
4243 mmio_write_32(DBSC_DBMEMSWAPCONF0, 0x00000006);
4244 ddr_phyvalid = 0x03;
4245 } else {
4246 ddr_phyvalid = Boardcnf->phyvalid;
4247 }
4248#else /* RCAR_DRAM_SPLIT_2CH */
4249 ddr_phyvalid = Boardcnf->phyvalid;
4250#endif /* RCAR_DRAM_SPLIT_2CH */
4251
4252 max_density = 0;
4253
4254 for (cs = 0; cs < CS_CNT; cs++) {
4255 ch_have_this_cs[cs] = 0;
4256 }
4257
4258 foreach_ech(ch)
4259 for (cs = 0; cs < CS_CNT; cs++)
4260 ddr_density[ch][cs] = 0xff;
4261
4262 foreach_vch(ch) {
4263 for (cs = 0; cs < CS_CNT; cs++) {
4264 dataL = Boardcnf->ch[ch].ddr_density[cs];
4265 ddr_density[ch][cs] = dataL;
4266
4267 if (dataL == 0xff)
4268 continue;
4269 if (dataL > max_density)
4270 max_density = dataL;
4271 if ((cs == 1) && (Prr_Product == PRR_PRODUCT_H3)
4272 && (Prr_Cut <= PRR_PRODUCT_11))
4273 continue;
4274 ch_have_this_cs[cs] |= (1U << ch);
4275 }
4276 }
4277
4278 /***********************************************************************
4279 Judge board clock frequency (in MHz)
4280 ***********************************************************************/
4281 boardcnf_get_brd_clk(_cnf_BOARDTYPE, &brd_clk, &brd_clkdiv);
4282 if ((brd_clk / brd_clkdiv) > 25) {
4283 brd_clkdiva = 1;
4284 } else {
4285 brd_clkdiva = 0;
4286 }
4287
4288 /***********************************************************************
4289 Judge ddr operating frequency clock(in Mbps)
4290 ***********************************************************************/
4291 boardcnf_get_ddr_mbps(_cnf_BOARDTYPE, &ddr_mbps, &ddr_mbpsdiv);
4292
4293 ddr0800_mul = CLK_DIV(800, 2, brd_clk, brd_clkdiv * (brd_clkdiva + 1));
4294
4295 ddr_mul =
4296 CLK_DIV(ddr_mbps, ddr_mbpsdiv * 2, brd_clk,
4297 brd_clkdiv * (brd_clkdiva + 1));
4298
4299 /***********************************************************************
4300 Adjust tccd
4301 ***********************************************************************/
4302 dataL = (0x00006000 & mmio_read_32(RST_MODEMR)) >> 13;
4303 switch (dataL) {
4304 case 0:
4305 bus_mbps = brd_clk * 0x60 * 2;
4306 bus_mbpsdiv = brd_clkdiv * 1;
4307 break;
4308 case 1:
4309 bus_mbps = brd_clk * 0x50 * 2;
4310 bus_mbpsdiv = brd_clkdiv * 1;
4311 break;
4312 case 2:
4313 bus_mbps = brd_clk * 0x40 * 2;
4314 bus_mbpsdiv = brd_clkdiv * 1;
4315 break;
4316 case 3:
4317 bus_mbps = brd_clk * 0x60 * 2;
4318 bus_mbpsdiv = brd_clkdiv * 2;
4319 break;
4320 default:
4321 bus_mbps = brd_clk * 0x60 * 2;
4322 bus_mbpsdiv = brd_clkdiv * 2;
4323 break;
4324 }
4325 tmp_tccd = CLK_DIV(ddr_mbps * 8, ddr_mbpsdiv, bus_mbps, bus_mbpsdiv);
4326 if (8 * ddr_mbps * bus_mbpsdiv != tmp_tccd * bus_mbps * ddr_mbpsdiv)
4327 tmp_tccd = tmp_tccd + 1;
4328
4329 if (tmp_tccd < 8)
4330 ddr_tccd = 8;
4331 else
4332 ddr_tccd = tmp_tccd;
4333
Marek Vasut6c245a52018-12-12 18:06:39 +01004334 NOTICE("BL2: DDR%d(%s)\n", ddr_mbps / ddr_mbpsdiv, RCAR_DDR_VERSION);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004335
4336 MSG_LF("Start\n");
4337
4338 /***********************************************************************
4339 PLL Setting
4340 ***********************************************************************/
4341 pll3_control(1);
4342
4343 /***********************************************************************
4344 initialize DDR
4345 ***********************************************************************/
4346 dataL = init_ddr();
4347 if (dataL == ddr_phyvalid) {
4348 failcount = 0;
4349 } else {
4350 failcount = 1;
4351 }
4352
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004353 foreach_vch(ch)
4354 mmio_write_32(DBSC_DBPDLK(ch), 0x00000000);
4355 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01004356 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004357 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4358 } else {
4359 mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
4360 }
4361
4362 if (failcount == 0) {
4363 return INITDRAM_OK;
4364 } else {
4365 return INITDRAM_NG;
4366 }
4367}
4368
4369void pvtcode_update(void)
4370{
4371 uint32_t ch;
Marek Vasut6c245a52018-12-12 18:06:39 +01004372 uint32_t dataL;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004373 uint32_t pvtp[4], pvtn[4], pvtp_init, pvtn_init;
4374 int32_t pvtp_tmp, pvtn_tmp;
4375
4376 foreach_vch(ch) {
4377 pvtn_init = (tcal.tcomp_cal[ch] & 0xFC0) >> 6;
4378 pvtp_init = (tcal.tcomp_cal[ch] & 0x03F) >> 0;
4379
4380 if (8912 * pvtp_init > 44230) {
4381 pvtp_tmp = (5000 + 8912 * pvtp_init - 44230) / 10000;
4382 } else {
4383 pvtp_tmp =
4384 -((-(5000 + 8912 * pvtp_init - 44230)) / 10000);
4385 }
4386 pvtn_tmp = (5000 + 5776 * pvtn_init + 30280) / 10000;
4387
4388 pvtn[ch] = pvtn_tmp + pvtn_init;
4389 pvtp[ch] = pvtp_tmp + pvtp_init;
4390
4391 if (pvtn[ch] > 63) {
4392 pvtn[ch] = 63;
4393 pvtp[ch] =
4394 (pvtp_tmp) * (63 - 6 * pvtn_tmp -
4395 pvtn_init) / (pvtn_tmp) +
4396 6 * pvtp_tmp + pvtp_init;
4397 }
4398 if ((Prr_Product == PRR_PRODUCT_H3)
4399 && (Prr_Cut <= PRR_PRODUCT_11)) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004400 dataL = pvtp[ch] | (pvtn[ch] << 6) | (tcal.tcomp_cal[ch] & 0xfffff000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004401 reg_ddrphy_write(ch,
4402 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004403 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004404 reg_ddrphy_write(ch,
4405 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004406 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004407 reg_ddrphy_write(ch,
4408 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004409 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004410 reg_ddrphy_write(ch,
4411 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004412 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004413 reg_ddrphy_write(ch,
4414 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004415 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004416 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004417 dataL = pvtp[ch] | (pvtn[ch] << 6) | 0x00015000;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004418 reg_ddrphy_write(ch,
4419 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004420 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004421 reg_ddrphy_write(ch,
4422 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004423 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004424 reg_ddrphy_write(ch,
4425 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004426 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004427 reg_ddrphy_write(ch,
4428 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004429 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004430 reg_ddrphy_write(ch,
4431 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004432 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004433 }
4434 }
4435}
4436
4437void pvtcode_update2(void)
4438{
4439 uint32_t ch;
4440 foreach_vch(ch) {
4441 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
4442 tcal.init_cal[ch] | 0x00020000);
4443 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
4444 tcal.init_cal[ch]);
4445 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
4446 tcal.init_cal[ch]);
4447 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
4448 tcal.init_cal[ch]);
4449 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
4450 tcal.init_cal[ch]);
4451 }
4452}
4453
4454void ddr_padcal_tcompensate_getinit(uint32_t override)
4455{
4456 uint32_t ch;
4457 uint32_t dataL;
4458 uint32_t pvtp, pvtn;
4459
4460 tcal.init_temp = 0;
4461 for (ch = 0; ch < 4; ch++) {
4462 tcal.init_cal[ch] = 0;
4463 tcal.tcomp_cal[ch] = 0;
4464 }
4465
4466 foreach_vch(ch) {
4467 tcal.init_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4468 tcal.tcomp_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4469 }
4470
4471 if (!override) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004472 dataL = mmio_read_32(THS1_TEMP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004473 if (dataL < 2800) {
4474 tcal.init_temp =
4475 (143 * (int32_t) dataL - 359000) / 1000;
4476 } else {
4477 tcal.init_temp =
4478 (121 * (int32_t) dataL - 296300) / 1000;
4479 }
4480
4481 foreach_vch(ch) {
4482 pvtp = (tcal.init_cal[ch] >> 0) & 0x000003F;
4483 pvtn = (tcal.init_cal[ch] >> 6) & 0x000003F;
4484 if ((int32_t) pvtp >
4485 ((tcal.init_temp * 29 - 3625) / 1000))
4486 pvtp =
4487 (int32_t) pvtp +
4488 ((3625 - tcal.init_temp * 29) / 1000);
4489 else
4490 pvtp = 0;
4491
4492 if ((int32_t) pvtn >
4493 ((tcal.init_temp * 54 - 6750) / 1000))
4494 pvtn =
4495 (int32_t) pvtn +
4496 ((6750 - tcal.init_temp * 54) / 1000);
4497 else
4498 pvtn = 0;
4499
4500 if ((Prr_Product == PRR_PRODUCT_H3)
4501 && (Prr_Cut <= PRR_PRODUCT_11)) {
4502 tcal.init_cal[ch] =
4503 (tcal.
4504 init_cal[ch] & 0xfffff000) | (pvtn << 6) |
4505 (pvtp);
4506 } else {
4507 tcal.init_cal[ch] =
4508 0x00015000 | (pvtn << 6) | (pvtp);
4509 }
4510 }
4511 tcal.init_temp = 125;
4512 }
4513}
4514
4515#ifndef ddr_qos_init_setting
4516/* for QoS init */
4517uint8_t get_boardcnf_phyvalid(void)
4518{
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004519 return ddr_phyvalid;
4520}
4521#endif /* ddr_qos_init_setting */
4522
4523/*******************************************************************************
4524 * END
4525 ******************************************************************************/