blob: f4bfdde1c4fe6ae35198cc4263b9ce059e9d5335 [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);
2097 /* DQENLTNCY : tphy_wrlat = WL-2 */
2098 tmp[1] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1);
2099 /* DQL : tphy_rdlat + trdata_en */
2100 /* it is not important for dbsc */
2101 tmp[2] = RL + 16;
2102 /* DQIENLTNCY : trdata_en */
2103 tmp[3] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1) - 1;
2104 mmio_write_32(DBSC_DBTR(16),
2105 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2106
2107 /* DBTR24 */
2108 /* WRCSLAT = WRLAT -5 */
2109 tmp[0] -= 5;
2110 /* WRCSGAP = 5 */
2111 tmp[1] = 5;
2112 /* RDCSLAT = RDLAT_ADJ +2 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002113 if (Prr_Product == PRR_PRODUCT_M3) {
2114 tmp[2] = tmp[3];
2115 } else {
2116 tmp[2] = tmp[3] + 2;
2117 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002118 /* RDCSGAP = 6 */
2119 if (Prr_Product == PRR_PRODUCT_M3) {
2120 tmp[3] = 4;
2121 } else {
2122 tmp[3] = 6;
2123 }
2124 mmio_write_32(DBSC_DBTR(24),
2125 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2126
2127 /* DBTR17.TMODRD,TMOD,TRDMR: tMRR,tMRD,(0) */
2128 mmio_write_32(DBSC_DBTR(17),
2129 (js2[JS2_tMRR] << 24) | (js2[JS2_tMRD] << 16));
2130
2131 /* DBTR18.RODTL, RODTA, WODTL, WODTA : do not use in LPDDR4 */
2132 mmio_write_32(DBSC_DBTR(18), 0);
2133
2134 /* DBTR19.TZQCL, TZQCS : do not use in LPDDR4 */
2135 mmio_write_32(DBSC_DBTR(19), 0);
2136
2137 /* DBTR20.TXSDLL, TXS : tRFCab+tCKEHCMD */
2138 dataL = js2[JS2_tRFCab] + js2[JS2_tCKEHCMD];
2139 mmio_write_32(DBSC_DBTR(20), (dataL << 16) | dataL);
2140
2141 /* DBTR21.TCCD */
2142 /* DBTR23.TCCD */
2143 /* H3 Ver.1.0 cannot use TBTR23 feature */
2144 if (ddr_tccd == 8 &&
2145 !((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_10))
2146 ) {
2147 dataL = 8;
2148 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2149 mmio_write_32(DBSC_DBTR(23), 0x00000002);
2150 } else if (ddr_tccd <= 11) {
2151 dataL = 11;
2152 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2153 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2154 } else {
2155 dataL = ddr_tccd;
2156 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2157 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2158 }
2159
2160 /* DBTR22.ZQLAT : */
2161 dataL = js2[JS2_tZQCALns] * 100; /* 1000 * 1000 ps */
2162 dataL = (dataL << 16) | (js2[JS2_tZQLAT] + 24 + 20);
2163 mmio_write_32(DBSC_DBTR(22), dataL);
2164
2165 /* DBTR25 : do not use in LPDDR4 */
2166 mmio_write_32(DBSC_DBTR(25), 0);
2167
2168 /* DBRNK : */
2169 /*
2170 * DBSC_DBRNK2 rkrr
2171 * DBSC_DBRNK3 rkrw
2172 * DBSC_DBRNK4 rkwr
2173 * DBSC_DBRNK5 rkww
2174 */
2175#define _par_DBRNK_VAL (0x7007)
2176
2177 for (i = 0; i < 4; i++) {
2178 uint32_t dataL2;
2179 dataL = (_par_DBRNK_VAL >> (i * 4)) & 0x0f;
2180 if ((Prr_Product == PRR_PRODUCT_H3)
2181 && (Prr_Cut > PRR_PRODUCT_11) && (i == 0)) {
2182 dataL += 1;
2183 }
2184 dataL2 = 0;
2185 foreach_vch(ch) {
2186 dataL2 = dataL2 | (dataL << (4 * ch));
2187 }
2188 mmio_write_32(DBSC_DBRNK(2 + i), dataL2);
2189 }
2190 mmio_write_32(DBSC_DBADJ0, 0x00000000);
2191
2192 /***********************************************************************
2193 timing registers for Scheduler
2194 ***********************************************************************/
2195 /* SCFCTST0 */
2196 /* SCFCTST0 ACT-ACT */
2197 tmp[3] = 1UL * js2[JS2_tRCpb] * 800 * ddr_mbpsdiv / ddr_mbps;
2198 /* SCFCTST0 RDA-ACT */
2199 tmp[2] =
2200 1UL * ((16 / 2) + js2[JS2_tRTP] - 8 +
2201 js2[JS2_tRPpb]) * 800 * ddr_mbpsdiv / ddr_mbps;
2202 /* SCFCTST0 WRA-ACT */
2203 tmp[1] =
2204 1UL * (WL + 1 + (16 / 2) +
2205 js1[js1_ind].nWR) * 800 * ddr_mbpsdiv / ddr_mbps;
2206 /* SCFCTST0 PRE-ACT */
2207 tmp[0] = 1UL * js2[JS2_tRPpb];
2208 mmio_write_32(DBSC_SCFCTST0,
2209 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2210
2211 /* SCFCTST1 */
2212 /* SCFCTST1 RD-WR */
2213 tmp[3] =
2214 1UL * (mmio_read_32(DBSC_DBTR(11)) & 0xff) * 800 * ddr_mbpsdiv /
2215 ddr_mbps;
2216 /* SCFCTST1 WR-RD */
2217 tmp[2] =
2218 1UL * (mmio_read_32(DBSC_DBTR(12)) & 0xff) * 800 * ddr_mbpsdiv /
2219 ddr_mbps;
2220 /* SCFCTST1 ACT-RD/WR */
2221 tmp[1] = 1UL * js2[JS2_tRCD] * 800 * ddr_mbpsdiv / ddr_mbps;
2222 /* SCFCTST1 ASYNCOFS */
2223 tmp[0] = 12;
2224 mmio_write_32(DBSC_SCFCTST1,
2225 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2226
2227 /* DBSCHRW1 */
2228 /* DBSCHRW1 SCTRFCAB */
2229 tmp[0] = 1UL * js2[JS2_tRFCab] * 800 * ddr_mbpsdiv / ddr_mbps;
2230 dataL = (((mmio_read_32(DBSC_DBTR(16)) & 0x00FF0000) >> 16)
2231 + (mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
2232 + (0x28 * 2)) * 400 * 2 * ddr_mbpsdiv / ddr_mbps + 7;
2233 if (tmp[0] < dataL)
2234 tmp[0] = dataL;
2235 mmio_write_32(DBSC_DBSCHRW1, tmp[0]);
2236
2237 /***********************************************************************
2238 QOS and CAM
2239 ***********************************************************************/
2240#ifdef ddr_qos_init_setting /* only for non qos_init */
2241 /*wbkwait(0004), wbkmdhi(4,2),wbkmdlo(1,8) */
2242 mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218);
2243 /*0(fillunit),8(dirtymax),4(dirtymin) */
2244 mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4);
2245 /*stop_tolerance */
2246 mmio_write_32(DBSC_DBSCHRW0, 0x22421111);
2247 /*rd-wr/wr-rd toggle priority */
2248 mmio_write_32(DBSC_SCFCTST2, 0x012F1123);
2249 mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
2250 mmio_write_32(DBSC_DBSCHCNT0, 0x000F0037);
2251
2252 /* QoS Settings */
2253 mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00U);
2254 mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00U);
2255 mmio_write_32(DBSC_DBSCHQOS02, 0x00000000U);
2256 mmio_write_32(DBSC_DBSCHQOS03, 0x00000000U);
2257 mmio_write_32(DBSC_DBSCHQOS40, 0x00000300U);
2258 mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0U);
2259 mmio_write_32(DBSC_DBSCHQOS42, 0x00000200U);
2260 mmio_write_32(DBSC_DBSCHQOS43, 0x00000100U);
2261 mmio_write_32(DBSC_DBSCHQOS90, 0x00000100U);
2262 mmio_write_32(DBSC_DBSCHQOS91, 0x000000F0U);
2263 mmio_write_32(DBSC_DBSCHQOS92, 0x000000A0U);
2264 mmio_write_32(DBSC_DBSCHQOS93, 0x00000040U);
2265 mmio_write_32(DBSC_DBSCHQOS120, 0x00000040U);
2266 mmio_write_32(DBSC_DBSCHQOS121, 0x00000030U);
2267 mmio_write_32(DBSC_DBSCHQOS122, 0x00000020U);
2268 mmio_write_32(DBSC_DBSCHQOS123, 0x00000010U);
2269 mmio_write_32(DBSC_DBSCHQOS130, 0x00000100U);
2270 mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0U);
2271 mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0U);
2272 mmio_write_32(DBSC_DBSCHQOS133, 0x00000040U);
2273 mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0U);
2274 mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0U);
2275 mmio_write_32(DBSC_DBSCHQOS142, 0x00000080U);
2276 mmio_write_32(DBSC_DBSCHQOS143, 0x00000040U);
2277 mmio_write_32(DBSC_DBSCHQOS150, 0x00000040U);
2278 mmio_write_32(DBSC_DBSCHQOS151, 0x00000030U);
2279 mmio_write_32(DBSC_DBSCHQOS152, 0x00000020U);
2280 mmio_write_32(DBSC_DBSCHQOS153, 0x00000010U);
2281
2282 mmio_write_32(QOSCTRL_RAEN, 0x00000001U);
2283#endif /* ddr_qos_init_setting */
2284 /* H3 Ver.1.1 need to set monitor function */
2285 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_11)) {
2286 mmio_write_32(DBSC_DBMONCONF4, 0x00700000);
2287 }
2288
2289 if (Prr_Product == PRR_PRODUCT_H3) {
2290 if (Prr_Cut == PRR_PRODUCT_10) {
2291 /* resrdis, simple mode, sc off */
2292 mmio_write_32(DBSC_DBBCAMDIS, 0x00000007);
2293 } else if (Prr_Cut == PRR_PRODUCT_11) {
2294 /* resrdis, simple mode */
2295 mmio_write_32(DBSC_DBBCAMDIS, 0x00000005);
2296 } else if (Prr_Cut < PRR_PRODUCT_30) {
2297 /* H3 Ver.2.0 */
2298 /* resrdis */
2299 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2300 } else { /* H3 Ver.3.0(include H3N) */
2301 /* exprespque */
2302 mmio_write_32(DBSC_DBBCAMDIS, 0x00000010);
2303 }
2304 } else { /* M3-W/M3-N/V3H */
2305 /* resrdis */
2306 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2307 }
2308}
2309
2310static void dbsc_regset_post(void)
2311{
2312 uint32_t ch, cs;
2313 uint32_t dataL;
2314 uint32_t slice, rdlat_max, rdlat_min;
2315
2316 rdlat_max = 0;
2317 rdlat_min = 0xffff;
2318 foreach_vch(ch) {
2319 for (cs = 0; cs < CS_CNT; cs++) {
2320 if ((ch_have_this_cs[cs] & (1U << ch)) != 0) {
2321 for (slice = 0; slice < SLICE_CNT; slice++) {
2322 ddr_setval_s(ch, slice,
2323 _reg_PHY_PER_CS_TRAINING_INDEX,
2324 cs);
2325 dataL =
2326 ddr_getval_s(ch, slice,
2327 _reg_PHY_RDDQS_LATENCY_ADJUST);
2328 if (dataL > rdlat_max)
2329 rdlat_max = dataL;
2330 if (dataL < rdlat_min)
2331 rdlat_min = dataL;
2332 }
2333 }
2334 }
2335 }
2336 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11)) {
2337 mmio_write_32(DBSC_DBTR(24),
2338 ((rdlat_max * 2 - rdlat_min + 4) << 24) +
2339 ((rdlat_min + 2) << 16) +
2340 mmio_read_32(DBSC_DBTR(24)));
2341 } else {
2342 mmio_write_32(DBSC_DBTR(24),
2343 ((rdlat_max + 2) << 24) +
2344 ((rdlat_max + 2) << 16) +
2345 mmio_read_32(DBSC_DBTR(24)));
2346 }
2347
2348 /* set ddr density information */
2349 foreach_ech(ch) {
2350 for (cs = 0; cs < CS_CNT; cs++) {
2351 if (ddr_density[ch][cs] == 0xff) {
2352 mmio_write_32(DBSC_DBMEMCONF(ch, cs), 0x00);
2353 } else {
2354 mmio_write_32(DBSC_DBMEMCONF(ch, cs),
2355 DBMEMCONF_REGD(ddr_density[ch]
2356 [cs]));
2357 }
2358 }
2359 mmio_write_32(DBSC_DBMEMCONF(ch, 2), 0x00000000);
2360 mmio_write_32(DBSC_DBMEMCONF(ch, 3), 0x00000000);
2361 }
2362
2363 mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
2364
2365 /*set DBI */
2366 if (Boardcnf->dbi_en)
2367 mmio_write_32(DBSC_DBDBICNT, 0x00000003);
2368
2369 /* H3 Ver.2.0 or later/M3-N/V3H DBI wa */
2370 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
2371 || (Prr_Product == PRR_PRODUCT_M3N)
2372 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
2373 reg_ddrphy_write_a(0x00001010, 0x01000000);
2374
2375 /*set REFCYCLE */
2376 dataL = (get_refperiod()) * ddr_mbps / 2000 / ddr_mbpsdiv;
2377 mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (dataL & 0x0000ffff));
2378 mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS);
2379#if RCAR_REWT_TRAINING != 0
2380 /* Periodic-WriteDQ Training seeting */
2381 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
2382 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut == PRR_PRODUCT_10))) {
2383 /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */
2384 } else {
2385 /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H -> Periodic-WriteDQ Training seeting */
2386
2387 /* Periodic WriteDQ Training seeting */
2388 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000);
2389
2390 ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04);
2391 ddr_setval_ach_as(_reg_PHY_WDQLVL_QTR_DLY_STEP, 0x0F);
2392 ddr_setval_ach_as(_reg_PHY_WDQLVL_DLY_STEP, 0x50);
2393 ddr_setval_ach_as(_reg_PHY_WDQLVL_DQDM_SLV_DLY_START, 0x0300);
2394
2395 ddr_setval_ach(_reg_PI_WDQLVL_CS_MAP,
2396 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2397 _reg_PI_WDQLVL_CS_MAP));
2398 ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f);
2399 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
2400 ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100);
2401 ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01);
2402 ddr_setval_ach(_reg_PI_TREF_F0, 0x0000);
2403 ddr_setval_ach(_reg_PI_TREF_F1, 0x0000);
2404 ddr_setval_ach(_reg_PI_TREF_F2, 0x0000);
2405
2406 if (Prr_Product == PRR_PRODUCT_M3) {
2407 ddr_setval_ach(_reg_PI_WDQLVL_EN, 0x02);
2408 } else {
2409 ddr_setval_ach(_reg_PI_WDQLVL_EN_F1, 0x02);
2410 }
2411 ddr_setval_ach(_reg_PI_WDQLVL_PERIODIC, 0x01);
2412
2413 /* DFI_PHYMSTR_ACK , WTmode setting */
2414 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011); /* DFI_PHYMSTR_ACK: WTmode =b'01 */
2415 }
2416#endif /* RCAR_REWT_TRAINING */
2417 /* periodic dram zqcal and phy ctrl update enable */
2418 mmio_write_32(DBSC_DBCALCNF, 0x01000010);
2419 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
2420 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_20))) {
2421 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
2422 } else {
2423#if RCAR_DRAM_SPLIT == 2
2424 if ((Prr_Product == PRR_PRODUCT_H3)
2425 && (Boardcnf->phyvalid == 0x05))
2426 mmio_write_32(DBSC_DBDFICUPDCNF, 0x2a240001);
2427 else
2428 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2429#else /* RCAR_DRAM_SPLIT == 2 */
2430 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2431#endif /* RCAR_DRAM_SPLIT == 2 */
2432 }
2433
2434#ifdef DDR_BACKUPMODE
2435 if (ddrBackup == DRAM_BOOT_STATUS_WARM) {
2436#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */
2437 PutStr(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
2438 send_dbcmd(0x08040001);
2439 wait_dbcmd();
2440 send_dbcmd(0x0A040001);
2441 wait_dbcmd();
2442 send_dbcmd(0x04040010);
2443 wait_dbcmd();
2444
2445 if (Prr_Product == PRR_PRODUCT_H3) {
2446 send_dbcmd(0x08140001);
2447 wait_dbcmd();
2448 send_dbcmd(0x0A140001);
2449 wait_dbcmd();
2450 send_dbcmd(0x04140010);
2451 wait_dbcmd();
2452 }
2453#else /* DDR_BACKUPMODE_HALF //for All channels */
2454 send_dbcmd(0x08840001);
2455 wait_dbcmd();
2456 send_dbcmd(0x0A840001);
2457 wait_dbcmd();
2458
2459 send_dbcmd(0x04840010);
2460 wait_dbcmd();
2461#endif /* DDR_BACKUPMODE_HALF */
2462 }
2463#endif /* DDR_BACKUPMODE */
2464
2465 mmio_write_32(DBSC_DBRFEN, 0x00000001);
2466 /* dram access enable */
2467 mmio_write_32(DBSC_DBACEN, 0x00000001);
2468
2469 MSG_LF("dbsc_regset_post(done)");
2470
2471}
2472
2473/*******************************************************************************
2474 * DFI_INIT_START
2475 ******************************************************************************/
2476static uint32_t dfi_init_start(void)
2477{
2478 uint32_t ch;
2479 uint32_t phytrainingok;
2480 uint32_t retry;
2481 uint32_t dataL;
2482 const uint32_t RETRY_MAX = 0x10000;
2483
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002484 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002485 /***********************************************************************
2486 PLL3 Disable
2487 ***********************************************************************/
2488 /* protect register interface */
2489 ddrphy_regif_idle();
2490
2491 pll3_control(0);
2492
2493 /***********************************************************************
2494 init start
2495 ***********************************************************************/
2496 /* dbdficnt0:
2497 * dfi_dram_clk_disable=1
2498 * dfi_frequency = 0
2499 * freq_ratio = 01 (2:1)
2500 * init_start =0
2501 */
2502 foreach_vch(ch)
2503 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10);
2504 dsb_sev();
2505
2506 /* dbdficnt0:
2507 * dfi_dram_clk_disable=1
2508 * dfi_frequency = 0
2509 * freq_ratio = 01 (2:1)
2510 * init_start =1
2511 */
2512 foreach_vch(ch)
2513 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11);
2514 dsb_sev();
2515
2516 } else {
2517 ddr_setval_ach_as(_reg_PHY_DLL_RST_EN, 0x02);
2518 dsb_sev();
2519 ddrphy_regif_idle();
2520 }
2521
2522 /* dll_rst negate */
2523 foreach_vch(ch)
2524 mmio_write_32(DBSC_DBPDCNT3(ch), 0x0000CF01);
2525 dsb_sev();
2526
2527 /***********************************************************************
2528 wait init_complete
2529 ***********************************************************************/
2530 phytrainingok = 0;
2531 retry = 0;
2532 while (retry++ < RETRY_MAX) {
2533 foreach_vch(ch) {
2534 dataL = mmio_read_32(DBSC_INITCOMP(ch));
2535 if (dataL & 0x00000001)
2536 phytrainingok |= (1U << ch);
2537 }
2538 dsb_sev();
2539 if (phytrainingok == ddr_phyvalid)
2540 break;
2541 if (retry % 256 == 0)
2542 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
2543 }
2544
2545 /***********************************************************************
2546 all ch ok?
2547 ***********************************************************************/
2548 if ((phytrainingok & ddr_phyvalid) != ddr_phyvalid) {
2549 return (0xff);
2550 }
2551 /* dbdficnt0:
2552 * dfi_dram_clk_disable=0
2553 * dfi_frequency = 0
2554 * freq_ratio = 01 (2:1)
2555 * init_start =0
2556 */
2557 foreach_vch(ch)
2558 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000010);
2559 dsb_sev();
2560
2561 return 0;
2562}
2563
2564/*******************************************************************************
2565 * drivablity setting : CMOS MODE ON/OFF
2566 ******************************************************************************/
2567static void change_lpddr4_en(uint32_t mode)
2568{
2569 uint32_t ch;
2570 uint32_t i;
2571 uint32_t dataL;
2572 const uint32_t _reg_PHY_PAD_DRIVE_X[3] = {
2573 _reg_PHY_PAD_ADDR_DRIVE,
2574 _reg_PHY_PAD_CLK_DRIVE,
2575 _reg_PHY_PAD_CS_DRIVE
2576 };
2577
Marek Vasut6c245a52018-12-12 18:06:39 +01002578 foreach_vch(ch) {
2579 for (i = 0; i < 3; i++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002580 dataL = ddr_getval(ch, _reg_PHY_PAD_DRIVE_X[i]);
2581 if (mode) {
2582 dataL |= (1U << 14);
2583 } else {
2584 dataL &= ~(1U << 14);
2585 }
2586 ddr_setval(ch, _reg_PHY_PAD_DRIVE_X[i], dataL);
2587 }
2588 }
2589}
2590
2591/*******************************************************************************
2592 * drivablity setting
2593 ******************************************************************************/
2594static uint32_t set_term_code(void)
2595{
2596 int32_t i;
2597 uint32_t ch, index;
2598 uint32_t dataL;
2599 uint32_t chip_id[2];
2600 uint32_t term_code;
2601 uint32_t override;
2602 term_code = ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2603 _reg_PHY_PAD_DATA_TERM);
2604 override = 0;
2605 for (i = 0; i < 2; i++)
2606 chip_id[i] = mmio_read_32(LIFEC_CHIPID(i));
2607
2608 index = 0;
2609 while (1) {
2610 if (TermcodeBySample[index][0] == 0xffffffff) {
2611 break;
2612 }
2613 if ((TermcodeBySample[index][0] == chip_id[0])
2614 && (TermcodeBySample[index][1] == chip_id[1])) {
2615 term_code = TermcodeBySample[index][2];
2616 override = 1;
2617 break;
2618 }
2619 index++;
2620 }
2621
2622 if (override) {
2623 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM; index++) {
2624 dataL =
2625 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2626 _reg_PHY_PAD_TERM_X[index]);
2627 dataL = (dataL & ~0x0001ffff) | term_code;
2628 ddr_setval_ach(_reg_PHY_PAD_TERM_X[index], dataL);
2629 }
2630 } else if ((Prr_Product == PRR_PRODUCT_M3)
2631 && (Prr_Cut == PRR_PRODUCT_10)) {
2632 /* non */
2633 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002634 ddr_setval_ach(_reg_PHY_PAD_TERM_X[0],
2635 (ddrtbl_getval
2636 (_cnf_DDR_PHY_ADR_G_REGSET,
2637 _reg_PHY_PAD_TERM_X[0]) & 0xFFFE0000));
2638 ddr_setval_ach(_reg_PHY_CAL_CLEAR_0, 0x01);
2639 ddr_setval_ach(_reg_PHY_CAL_START_0, 0x01);
2640 foreach_vch(ch) {
2641 do {
2642 dataL =
2643 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2644 } while (!(dataL & 0x00800000));
2645 }
2646 if ((Prr_Product == PRR_PRODUCT_H3)
2647 && (Prr_Cut <= PRR_PRODUCT_11)) {
2648 foreach_vch(ch) {
2649 uint32_t pvtr;
2650 uint32_t pvtp;
2651 uint32_t pvtn;
2652 dataL = ddr_getval(ch, _reg_PHY_PAD_TERM_X[0]);
2653 pvtr = (dataL >> 12) & 0x1f;
2654 pvtr += 8;
2655 if (pvtr > 0x1f)
2656 pvtr = 0x1f;
2657 dataL =
2658 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2659 pvtn = (dataL >> 6) & 0x03f;
2660 pvtp = (dataL >> 0) & 0x03f;
2661
2662 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2663 index++) {
2664 dataL =
2665 ddrtbl_getval
2666 (_cnf_DDR_PHY_ADR_G_REGSET,
2667 _reg_PHY_PAD_TERM_X[index]);
2668 dataL = (dataL & ~0x0001ffff)
2669 | (pvtr << 12)
2670 | (pvtn << 6)
2671 | (pvtp);
2672 ddr_setval(ch,
2673 _reg_PHY_PAD_TERM_X[index],
2674 dataL);
2675 }
2676 }
2677 } else { /* M3-W Ver.1.1 or later/H3 Ver.2.0 or later/M3-N/V3H */
2678 foreach_vch(ch) {
2679 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2680 index++) {
2681 dataL =
2682 ddr_getval(ch,
2683 _reg_PHY_PAD_TERM_X
2684 [index]);
2685 ddr_setval(ch,
2686 _reg_PHY_PAD_TERM_X[index],
2687 (dataL & 0xFFFE0FFF) |
2688 0x00015000);
2689 }
2690 }
2691 }
2692 }
2693 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2694 /* non */
2695 } else {
2696 ddr_padcal_tcompensate_getinit(override);
2697 }
2698 return 0;
2699}
2700
2701/*******************************************************************************
2702 * DDR mode register setting
2703 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01002704static void ddr_register_set(void)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002705{
2706 int32_t fspwp;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002707 uint32_t tmp;
2708
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002709 for (fspwp = 1; fspwp >= 0; fspwp--) {
2710 /*MR13,fspwp */
Marek Vasut6c245a52018-12-12 18:06:39 +01002711 send_dbcmd(0x0e840d08 | (fspwp << 6));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002712
2713 tmp =
2714 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2715 _reg_PI_MR1_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002716 send_dbcmd(0x0e840100 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002717
2718 tmp =
2719 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2720 _reg_PI_MR2_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002721 send_dbcmd(0x0e840200 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002722
2723 tmp =
2724 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2725 _reg_PI_MR3_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002726 send_dbcmd(0x0e840300 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002727
2728 tmp =
2729 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2730 _reg_PI_MR11_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002731 send_dbcmd(0x0e840b00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002732
2733 tmp =
2734 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2735 _reg_PI_MR12_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002736 send_dbcmd(0x0e840c00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002737
2738 tmp =
2739 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2740 _reg_PI_MR14_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002741 send_dbcmd(0x0e840e00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002742 /* MR22 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002743 send_dbcmd(0x0e841616);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002744 }
2745}
2746
2747/*******************************************************************************
2748 * Training handshake functions
2749 ******************************************************************************/
2750static inline uint32_t wait_freqchgreq(uint32_t assert)
2751{
2752 uint32_t dataL;
2753 uint32_t count;
2754 uint32_t ch;
2755 count = 100000;
2756
2757 /* H3 Ver.1.x cannot see frqchg_req */
2758 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2759 return 0;
2760 }
2761
2762 if (assert) {
2763 do {
2764 dataL = 1;
2765 foreach_vch(ch) {
2766 dataL &= mmio_read_32(DBSC_DBPDSTAT(ch));
2767 }
2768 count = count - 1;
2769 } while (((dataL & 0x01) != 0x01) & (count != 0));
2770 } else {
2771 do {
2772 dataL = 0;
2773 foreach_vch(ch) {
2774 dataL |= mmio_read_32(DBSC_DBPDSTAT(ch));
2775 }
2776 count = count - 1;
2777 } while (((dataL & 0x01) != 0x00) & (count != 0));
2778 }
2779
2780 return (count == 0);
2781}
2782
2783static inline void set_freqchgack(uint32_t assert)
2784{
2785 uint32_t ch;
2786 uint32_t dataL;
2787 if (assert)
2788 dataL = 0x0CF20000;
2789 else
2790 dataL = 0x00000000;
2791
2792 foreach_vch(ch)
2793 mmio_write_32(DBSC_DBPDCNT2(ch), dataL);
2794}
2795
2796static inline void set_dfifrequency(uint32_t freq)
2797{
2798 uint32_t ch;
2799 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2800 foreach_vch(ch)
2801 mmio_clrsetbits_32(DBSC_DBPDCNT1(ch), 0x1fU, freq);
2802 } else {
2803 foreach_vch(ch) {
2804 mmio_clrsetbits_32(DBSC_DBDFICNT(ch), 0x1fU << 24,
2805 (freq << 24));
2806 }
2807 }
2808 dsb_sev();
2809}
2810
2811static uint32_t pll3_freq(uint32_t on)
2812{
2813 uint32_t timeout;
2814
2815 timeout = wait_freqchgreq(1);
2816
2817 if (timeout) {
2818 return (1);
2819 }
2820
2821 pll3_control(on);
2822 set_dfifrequency(on);
2823
2824 set_freqchgack(1);
2825 timeout = wait_freqchgreq(0);
2826 set_freqchgack(0);
2827
2828 if (timeout) {
Marek Vasut56519892019-01-21 23:11:33 +01002829 FATAL_MSG("BL2: Time out[2]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002830 return (1);
2831 }
2832 return (0);
2833}
2834
2835/*******************************************************************************
2836 * update dly
2837 ******************************************************************************/
2838static void update_dly(void)
2839{
2840 ddr_setval_ach(_reg_SC_PHY_MANUAL_UPDATE, 0x01);
2841 ddr_setval_ach(_reg_PHY_ADRCTL_MANUAL_UPDATE, 0x01);
2842}
2843
2844/*******************************************************************************
2845 * training by pi
2846 ******************************************************************************/
2847static uint32_t pi_training_go(void)
2848{
2849 uint32_t flag;
2850 uint32_t dataL;
2851 uint32_t retry;
2852 const uint32_t RETRY_MAX = 4096 * 16;
2853 uint32_t ch;
2854
2855 uint32_t mst_ch;
2856 uint32_t cur_frq;
2857 uint32_t complete;
2858 uint32_t frqchg_req;
2859
2860 /* ********************************************************************* */
2861
2862 /***********************************************************************
2863 pi_start
2864 ***********************************************************************/
2865 ddr_setval_ach(_reg_PI_START, 0x01);
2866 foreach_vch(ch)
2867 ddr_getval(ch, _reg_PI_INT_STATUS);
2868
2869 /* set dfi_phymstr_ack = 1 */
2870 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000001);
2871 dsb_sev();
2872
2873 /***********************************************************************
2874 wait pi_int_status[0]
2875 ***********************************************************************/
2876 mst_ch = 0;
2877 flag = 0;
2878 complete = 0;
2879 cur_frq = 0;
2880 retry = RETRY_MAX;
2881 do {
2882 frqchg_req = mmio_read_32(DBSC_DBPDSTAT(mst_ch)) & 0x01;
2883
2884 /* H3 Ver.1.x cannot see frqchg_req */
2885 if ((Prr_Product == PRR_PRODUCT_H3)
2886 && (Prr_Cut <= PRR_PRODUCT_11)) {
2887 if ((retry % 4096) == 1) {
2888 frqchg_req = 1;
2889 } else {
2890 frqchg_req = 0;
2891 }
2892 }
2893
2894 if (frqchg_req) {
2895 if (cur_frq) {
2896 /* Low frequency */
2897 flag = pll3_freq(0);
2898 cur_frq = 0;
2899 } else {
2900 /* High frequency */
2901 flag = pll3_freq(1);
2902 cur_frq = 1;
2903 }
2904 if (flag)
2905 break;
2906 } else {
2907 if (cur_frq) {
2908 foreach_vch(ch) {
2909 if (complete & (1U << ch))
2910 continue;
2911 dataL =
2912 ddr_getval(ch, _reg_PI_INT_STATUS);
2913 if (dataL & 0x01) {
2914 complete |= (1U << ch);
2915 }
2916 }
2917 if (complete == ddr_phyvalid)
2918 break;
2919 }
2920 }
2921 } while (--retry);
2922 foreach_vch(ch) {
2923 /* dummy read */
2924 dataL = ddr_getval_s(ch, 0, _reg_PHY_CAL_RESULT2_OBS_0);
2925 dataL = ddr_getval(ch, _reg_PI_INT_STATUS);
2926 ddr_setval(ch, _reg_PI_INT_ACK, dataL);
2927 }
2928 if (ddrphy_regif_chk()) {
2929 return (0xfd);
2930 }
2931 return complete;
2932}
2933
2934/*******************************************************************************
2935 * Initialize ddr
2936 ******************************************************************************/
2937static uint32_t init_ddr(void)
2938{
2939 int32_t i;
2940 uint32_t dataL;
2941 uint32_t phytrainingok;
Marek Vasut6c245a52018-12-12 18:06:39 +01002942 uint32_t ch, slice;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002943 uint32_t err;
2944
2945 MSG_LF("init_ddr:0\n");
2946
2947#ifdef DDR_BACKUPMODE
2948 rcar_dram_get_boot_status(&ddrBackup);
2949#endif
2950
2951 /***********************************************************************
2952 unlock phy
2953 ***********************************************************************/
2954 /* Unlock DDRPHY register(AGAIN) */
2955 foreach_vch(ch)
2956 mmio_write_32(DBSC_DBPDLK(ch), 0x0000A55A);
2957 dsb_sev();
2958
2959 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
2960 || (Prr_Product == PRR_PRODUCT_M3N)
2961 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
2962 reg_ddrphy_write_a(0x00001010, 0x01000001);
2963 else
2964 reg_ddrphy_write_a(0x00001010, 0x00000001);
2965 /***********************************************************************
2966 dbsc register pre-setting
2967 ***********************************************************************/
2968 dbsc_regset_pre();
2969
2970 /***********************************************************************
2971 load ddrphy registers
2972 ***********************************************************************/
2973
2974 ddrtbl_load();
2975
2976 /***********************************************************************
2977 configure ddrphy registers
2978 ***********************************************************************/
2979 ddr_config();
2980
2981 /***********************************************************************
2982 dfi_reset assert
2983 ***********************************************************************/
2984 foreach_vch(ch)
2985 mmio_write_32(DBSC_DBPDCNT0(ch), 0x01);
2986 dsb_sev();
2987
2988 /***********************************************************************
2989 dbsc register set
2990 ***********************************************************************/
2991 dbsc_regset();
2992 MSG_LF("init_ddr:1\n");
2993
2994 /***********************************************************************
2995 dfi_reset negate
2996 ***********************************************************************/
2997 foreach_vch(ch)
2998 mmio_write_32(DBSC_DBPDCNT0(ch), 0x00);
2999 dsb_sev();
3000
3001 /***********************************************************************
3002 dfi_init_start (start ddrphy)
3003 ***********************************************************************/
3004 err = dfi_init_start();
3005 if (err) {
3006 return INITDRAM_ERR_I;
3007 }
3008 MSG_LF("init_ddr:2\n");
3009
3010 /***********************************************************************
3011 ddr backupmode end
3012 ***********************************************************************/
3013#ifdef DDR_BACKUPMODE
3014 if (ddrBackup) {
Marek Vasut56519892019-01-21 23:11:33 +01003015 NOTICE("BL2: [WARM_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003016 } else {
Marek Vasut56519892019-01-21 23:11:33 +01003017 NOTICE("BL2: [COLD_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003018 }
3019 err = rcar_dram_update_boot_status(ddrBackup);
3020 if (err) {
Marek Vasut56519892019-01-21 23:11:33 +01003021 NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003022 return INITDRAM_ERR_I;
3023 }
3024#endif
3025 MSG_LF("init_ddr:3\n");
3026
3027 /***********************************************************************
3028 override term code after dfi_init_complete
3029 ***********************************************************************/
3030 err = set_term_code();
3031 if (err) {
3032 return INITDRAM_ERR_I;
3033 }
3034 MSG_LF("init_ddr:4\n");
3035
3036 /***********************************************************************
3037 rx offset calibration
3038 ***********************************************************************/
3039 if ((Prr_Cut > PRR_PRODUCT_11) || (Prr_Product == PRR_PRODUCT_M3N)
3040 || (Prr_Product == PRR_PRODUCT_V3H)) {
3041 err = rx_offset_cal_hw();
3042 } else {
3043 err = rx_offset_cal();
3044 }
3045 if (err)
3046 return (INITDRAM_ERR_O);
3047 MSG_LF("init_ddr:5\n");
3048
Marek Vasut6c245a52018-12-12 18:06:39 +01003049 /* PDX */
3050 send_dbcmd(0x08840001);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003051
3052 /***********************************************************************
3053 check register i/f is alive
3054 ***********************************************************************/
3055 err = ddrphy_regif_chk();
3056 if (err) {
3057 return (INITDRAM_ERR_O);
3058 }
3059 MSG_LF("init_ddr:6\n");
3060
3061 /***********************************************************************
3062 phy initialize end
3063 ***********************************************************************/
3064
3065 /***********************************************************************
3066 setup DDR mode registers
3067 ***********************************************************************/
3068 /* CMOS MODE */
3069 change_lpddr4_en(0);
3070
Marek Vasut6c245a52018-12-12 18:06:39 +01003071 /* MRS */
3072 ddr_register_set();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003073
3074 /* ZQCAL start */
Marek Vasut6c245a52018-12-12 18:06:39 +01003075 send_dbcmd(0x0d84004F);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003076
3077 /* ZQLAT */
Marek Vasut6c245a52018-12-12 18:06:39 +01003078 send_dbcmd(0x0d840051);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003079
3080 /***********************************************************************
3081 Thermal sensor setting
3082 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003083 /* THCTR Bit6: PONM=0 , Bit0: THSST=1 */
3084 dataL = (mmio_read_32(THS1_THCTR) & 0xFFFFFFBF) | 0x00000001;
3085 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003086
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003087 /* LPDDR4 MODE */
3088 change_lpddr4_en(1);
3089
3090 MSG_LF("init_ddr:7\n");
3091
3092 /***********************************************************************
3093 mask CS_MAP if RANKx is not found
3094 ***********************************************************************/
3095 foreach_vch(ch) {
3096 dataL = ddr_getval(ch, _reg_PI_CS_MAP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003097 if (!(ch_have_this_cs[1] & (1U << ch)))
3098 dataL = dataL & 0x05;
3099 ddr_setval(ch, _reg_PI_CS_MAP, dataL);
3100 }
3101
3102 /***********************************************************************
3103 exec pi_training
3104 ***********************************************************************/
3105 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00);
Marek Vasut6c245a52018-12-12 18:06:39 +01003106
3107 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003108 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003109 } else {
3110 foreach_vch(ch) {
3111 for (slice = 0; slice < SLICE_CNT; slice++) {
3112 ddr_setval_s(ch, slice,
3113 _reg_PHY_PER_CS_TRAINING_EN,
3114 ((ch_have_this_cs[1]) >> ch)
3115 & 0x01);
3116 }
3117 }
3118 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003119
3120 phytrainingok = pi_training_go();
3121
3122 if (ddr_phyvalid != (phytrainingok & ddr_phyvalid)) {
3123 return (INITDRAM_ERR_T | phytrainingok);
3124 }
3125
3126 MSG_LF("init_ddr:8\n");
3127
3128 /***********************************************************************
3129 CACS DLY ADJUST
3130 ***********************************************************************/
3131 dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
3132 foreach_vch(ch) {
3133 int16_t adj;
3134 for (i = 0; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
3135 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
3136 ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3137 dataL + adj);
3138 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003139
3140 if (ddr_phycaslice == 1) {
3141 for (i = 0; i < 6; i++) {
3142 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM]);
3143 ddr_setval_s(ch, 2, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3144 dataL + adj
3145 );
3146 }
3147 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003148 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003149
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003150 update_dly();
3151 MSG_LF("init_ddr:9\n");
3152
3153 /***********************************************************************
3154 H3 fix rd latency to avoid bug in elasitic buffe
3155 ***********************************************************************/
3156 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3157 adjust_rddqs_latency();
3158 }
3159
3160 /***********************************************************************
3161 Adjust Write path latency
3162 ***********************************************************************/
3163 if (ddrtbl_getval
3164 (_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD))
3165 adjust_wpath_latency();
3166
3167 /***********************************************************************
3168 RDQLVL Training
3169 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003170 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003171 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x01);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003172 }
3173
3174 err = rdqdm_man();
Marek Vasut6c245a52018-12-12 18:06:39 +01003175
3176 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
3177 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x00);
3178 }
3179
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003180 if (err) {
3181 return (INITDRAM_ERR_T);
3182 }
3183 update_dly();
3184 MSG_LF("init_ddr:10\n");
3185
3186 /***********************************************************************
3187 WDQLVL Training
3188 ***********************************************************************/
3189 err = wdqdm_man();
3190 if (err) {
3191 return (INITDRAM_ERR_T);
3192 }
3193 update_dly();
3194 MSG_LF("init_ddr:11\n");
3195
3196 /***********************************************************************
3197 training complete, setup dbsc
3198 ***********************************************************************/
3199 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3200 || (Prr_Product == PRR_PRODUCT_M3N)
3201 || (Prr_Product == PRR_PRODUCT_V3H)) {
3202 ddr_setval_ach_as(_reg_PHY_DFI40_POLARITY, 0x00);
3203 ddr_setval_ach(_reg_PI_DFI40_POLARITY, 0x00);
3204 }
3205
3206 dbsc_regset_post();
3207 MSG_LF("init_ddr:12\n");
3208
3209 return phytrainingok;
3210}
3211
3212/*******************************************************************************
3213 * SW LEVELING COMMON
3214 ******************************************************************************/
3215static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick)
3216{
3217 uint32_t ch;
3218 uint32_t dataL;
3219 uint32_t retry;
3220 uint32_t waiting;
3221 uint32_t err;
3222
3223 const uint32_t RETRY_MAX = 0x1000;
3224
3225 err = 0;
3226 /* set EXIT -> OP_DONE is cleared */
3227 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3228
3229 /* kick */
3230 foreach_vch(ch) {
3231 if (ch_have_this_cs[ddr_csn % 2] & (1U << ch)) {
3232 ddr_setval(ch, reg_cs, ddr_csn);
3233 ddr_setval(ch, reg_kick, 0x01);
3234 }
3235 }
3236 foreach_vch(ch) {
3237 /*PREPARE ADDR REGISTER (for SWLVL_OP_DONE) */
3238 ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3239 }
3240 waiting = ch_have_this_cs[ddr_csn % 2];
3241 dsb_sev();
3242 retry = RETRY_MAX;
3243 do {
3244 foreach_vch(ch) {
3245 if (!(waiting & (1U << ch)))
3246 continue;
3247 dataL = ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3248 if (dataL & 0x01)
3249 waiting &= ~(1U << ch);
3250 }
3251 retry--;
3252 } while (waiting && (retry > 0));
3253 if (retry == 0) {
3254 err = 1;
3255 }
3256
3257 dsb_sev();
3258 /* set EXIT -> OP_DONE is cleared */
3259 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3260 dsb_sev();
3261
3262 return err;
3263}
3264
3265/*******************************************************************************
3266 * WDQ TRAINING
3267 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003268#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003269static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3270{
3271 int32_t i, k;
3272 uint32_t cs, slice;
3273 uint32_t dataL;
3274
3275 /***********************************************************************
3276 clr of training results buffer
3277 ***********************************************************************/
3278 cs = ddr_csn % 2;
3279 dataL = Boardcnf->dqdm_dly_w;
3280 for (slice = 0; slice < SLICE_CNT; slice++) {
3281 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3282 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3283 continue;
3284
3285 for (i = 0; i <= 8; i++) {
3286 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch))
3287 wdqdm_dly[ch][cs][slice][i] =
3288 wdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3289 else
3290 wdqdm_dly[ch][cs][slice][i] = dataL;
3291 wdqdm_le[ch][cs][slice][i] = 0;
3292 wdqdm_te[ch][cs][slice][i] = 0;
3293 }
3294 wdqdm_st[ch][cs][slice] = 0;
3295 wdqdm_win[ch][cs][slice] = 0;
3296 }
3297}
3298
3299static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3300{
3301 int32_t i, k;
3302 uint32_t cs, slice;
3303 uint32_t dataL;
3304 uint32_t err;
3305 const uint32_t _par_WDQLVL_RETRY_THRES = 0x7c0;
3306
3307 int32_t min_win;
3308 int32_t win;
3309 int8_t _adj;
3310 int16_t adj;
3311 uint32_t dq;
3312
3313 /***********************************************************************
3314 analysis of training results
3315 ***********************************************************************/
3316 err = 0;
3317 for (slice = 0; slice < SLICE_CNT; slice += 1) {
3318 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3319 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3320 continue;
3321
3322 cs = ddr_csn % 2;
3323 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003324 for (i = 0; i < 9; i++) {
3325 dq = slice * 8 + i;
3326 if (i == 8)
3327 _adj = Boardcnf->ch[ch].dm_adj_w[slice];
3328 else
3329 _adj = Boardcnf->ch[ch].dq_adj_w[dq];
3330 adj = _f_scale_adj(_adj);
3331
3332 dataL =
3333 ddr_getval_s(ch, slice,
3334 _reg_PHY_CLK_WRX_SLAVE_DELAY[i]) + adj;
3335 ddr_setval_s(ch, slice, _reg_PHY_CLK_WRX_SLAVE_DELAY[i],
3336 dataL);
3337 wdqdm_dly[ch][cs][slice][i] = dataL;
3338 }
3339 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x00);
3340 dataL = ddr_getval_s(ch, slice, _reg_PHY_WDQLVL_STATUS_OBS);
3341 wdqdm_st[ch][cs][slice] = dataL;
3342 min_win = INT_LEAST32_MAX;
3343 for (i = 0; i <= 8; i++) {
3344 ddr_setval_s(ch, slice, _reg_PHY_WDQLVL_DQDM_OBS_SELECT,
3345 i);
3346
3347 dataL =
3348 ddr_getval_s(ch, slice,
3349 _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS);
3350 wdqdm_te[ch][cs][slice][i] = dataL;
3351 dataL =
3352 ddr_getval_s(ch, slice,
3353 _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS);
3354 wdqdm_le[ch][cs][slice][i] = dataL;
3355 win =
3356 (int32_t) wdqdm_te[ch][cs][slice][i] -
3357 wdqdm_le[ch][cs][slice][i];
3358 if (min_win > win)
3359 min_win = win;
3360 if (dataL >= _par_WDQLVL_RETRY_THRES)
3361 err = 2;
3362 }
3363 wdqdm_win[ch][cs][slice] = min_win;
Marek Vasut6c245a52018-12-12 18:06:39 +01003364 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003365 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003366 } else {
3367 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN,
3368 ((ch_have_this_cs[1]) >> ch) & 0x01);
3369 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003370 }
3371 return err;
3372}
Marek Vasut6c245a52018-12-12 18:06:39 +01003373#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003374
3375static void wdqdm_cp(uint32_t ddr_csn, uint32_t restore)
3376{
3377 uint32_t i;
3378 uint32_t ch, slice;
3379 uint32_t tgt_cs, src_cs;
3380 uint32_t tmp_r;
3381
3382 /***********************************************************************
3383 copy of training results
3384 ***********************************************************************/
3385 foreach_vch(ch) {
3386 for (tgt_cs = 0; tgt_cs < CS_CNT; tgt_cs++) {
3387 for (slice = 0; slice < SLICE_CNT; slice++) {
3388 ddr_setval_s(ch, slice,
3389 _reg_PHY_PER_CS_TRAINING_INDEX,
3390 tgt_cs);
3391 src_cs = ddr_csn % 2;
3392 if (!(ch_have_this_cs[1] & (1U << ch)))
3393 src_cs = 0;
3394 for (i = 0; i <= 4; i += 4) {
3395 if (restore)
3396 tmp_r =
3397 rdqdm_dly[ch][tgt_cs][slice]
3398 [i];
3399 else
3400 tmp_r =
3401 rdqdm_dly[ch][src_cs][slice]
3402 [i];
3403
3404 ddr_setval_s(ch, slice,
3405 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY
3406 [i], tmp_r);
3407 }
3408 }
3409 }
3410 }
3411}
3412
3413static uint32_t wdqdm_man1(void)
3414{
3415 int32_t k;
3416 uint32_t ch, cs, slice;
3417 uint32_t ddr_csn;
3418 uint32_t dataL;
3419 uint32_t err;
Marek Vasut6c245a52018-12-12 18:06:39 +01003420 uint32_t high_dq[DRAM_CH_CNT];
3421 uint32_t mr14_csab0_bak[DRAM_CH_CNT];
3422#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003423 uint32_t err_flg;
Marek Vasut6c245a52018-12-12 18:06:39 +01003424#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003425
3426 /***********************************************************************
3427 manual execution of training
3428 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003429 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3430 foreach_vch(ch) {
3431 high_dq[ch] = 0;
3432 for (slice = 0; slice < SLICE_CNT; slice++) {
3433 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3434 if (k >= 2)
3435 high_dq[ch] |= (1U << slice);
3436 }
3437 ddr_setval(ch, _reg_PI_16BIT_DRAM_CONNECT, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003438 }
3439 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003440 err = 0;
3441 /* CLEAR PREV RESULT */
3442 for (cs = 0; cs < CS_CNT; cs++) {
3443 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_INDEX, cs);
3444 if (((Prr_Product == PRR_PRODUCT_H3)
3445 && (Prr_Cut > PRR_PRODUCT_11))
3446 || (Prr_Product == PRR_PRODUCT_M3N)
3447 || (Prr_Product == PRR_PRODUCT_V3H)) {
3448 ddr_setval_ach_as(_reg_SC_PHY_WDQLVL_CLR_PREV_RESULTS,
3449 0x01);
3450 } else {
3451 ddr_setval_ach_as(_reg_PHY_WDQLVL_CLR_PREV_RESULTS,
3452 0x01);
3453 }
3454 }
3455 ddrphy_regif_idle();
3456
Marek Vasut6c245a52018-12-12 18:06:39 +01003457#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003458 err_flg = 0;
Marek Vasut6c245a52018-12-12 18:06:39 +01003459#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003460 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3461 if ((Prr_Product == PRR_PRODUCT_H3)
3462 && (Prr_Cut <= PRR_PRODUCT_11)) {
3463 foreach_vch(ch) {
3464 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3465 dataL &= ~(0x00ffU << 16);
3466
3467 if (ddr_csn >= 2)
3468 k = (high_dq[ch] ^ 0x0f);
3469 else
3470 k = high_dq[ch];
3471 dataL |= (k << 16);
3472 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3473 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, k);
3474 }
3475 }
3476 if (((Prr_Product == PRR_PRODUCT_H3)
3477 && (Prr_Cut <= PRR_PRODUCT_11))
3478 || ((Prr_Product == PRR_PRODUCT_M3)
3479 && (Prr_Cut == PRR_PRODUCT_10))) {
3480 wdqdm_cp(ddr_csn, 0);
3481 }
3482
3483 foreach_vch(ch) {
3484 dataL =
3485 ddr_getval(ch,
3486 _reg_PI_MR14_DATA_Fx_CSx[1][ddr_csn]);
3487 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0], dataL);
3488 }
3489
3490 /* KICK WDQLVL */
3491 err = swlvl1(ddr_csn, _reg_PI_WDQLVL_CS, _reg_PI_WDQLVL_REQ);
3492 if (err)
3493 goto err_exit;
3494
3495 if (ddr_csn == 0)
3496 foreach_vch(ch) {
3497 mr14_csab0_bak[ch] =
3498 ddr_getval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0]);
3499 } else
3500 foreach_vch(ch) {
3501 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0],
3502 mr14_csab0_bak[ch]);
3503 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003504#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003505 foreach_vch(ch) {
3506 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3507 wdqdm_clr1(ch, ddr_csn);
3508 continue;
3509 }
3510 err = wdqdm_ana1(ch, ddr_csn);
3511 if (err)
3512 err_flg |= (1U << (ddr_csn * 4 + ch));
3513 ddrphy_regif_idle();
3514 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003515#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003516 }
3517err_exit:
Marek Vasut6c245a52018-12-12 18:06:39 +01003518#ifndef DDR_FAST_INIT
3519 err |= err_flg;
3520#endif/* DDR_FAST_INIT */
3521 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3522 ddr_setval_ach(_reg_PI_16BIT_DRAM_CONNECT, 0x01);
3523 foreach_vch(ch) {
3524 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3525 dataL &= ~(0x00ffU << 16);
3526 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3527 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, 0x00);
3528 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003529 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003530 return (err);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003531}
3532
3533static uint32_t wdqdm_man(void)
3534{
3535 uint32_t err, retry_cnt;
3536 const uint32_t retry_max = 0x10;
3537
3538 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, (DBSC_DBTR(11) & 0xFF) + 12);
3539 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3540 || (Prr_Product == PRR_PRODUCT_M3N)
3541 || (Prr_Product == PRR_PRODUCT_V3H)) {
3542 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR_F1,
3543 (DBSC_DBTR(12) & 0xFF) + 1);
3544 } else {
3545 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR,
3546 (DBSC_DBTR(12) & 0xFF) + 1);
3547 }
3548 ddr_setval_ach(_reg_PI_TRFC_F1, (DBSC_DBTR(13) & 0x1FF));
3549
3550 retry_cnt = 0;
3551 do {
3552 if ((Prr_Product == PRR_PRODUCT_H3)
3553 && (Prr_Cut <= PRR_PRODUCT_11)) {
3554 err = wdqdm_man1();
3555 } else {
3556 uint32_t ch, ddr_csn, mr14_bkup[4][4];
3557
3558 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x01);
3559 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3560 0x01);
3561 if ((Prr_Product == PRR_PRODUCT_M3N)
3562 || (Prr_Product == PRR_PRODUCT_V3H)) {
3563 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3564 0x0C);
3565 } else {
3566 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0C);
3567 }
3568 dsb_sev();
3569 err = wdqdm_man1();
3570 foreach_vch(ch) {
3571 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3572 mr14_bkup[ch][ddr_csn] =
3573 ddr_getval(ch,
3574 _reg_PI_MR14_DATA_Fx_CSx
3575 [1][ddr_csn]);
3576 dsb_sev();
3577 }
3578 }
3579
3580 if ((Prr_Product == PRR_PRODUCT_M3N)
3581 || (Prr_Product == PRR_PRODUCT_V3H)) {
3582 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3583 0x04);
3584 } else {
3585 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x04);
3586 }
3587 pvtcode_update();
3588 err = wdqdm_man1();
3589 foreach_vch(ch) {
3590 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3591 mr14_bkup[ch][ddr_csn] =
3592 (mr14_bkup[ch][ddr_csn] +
3593 ddr_getval(ch,
3594 _reg_PI_MR14_DATA_Fx_CSx
3595 [1][ddr_csn])) / 2;
3596 ddr_setval(ch,
3597 _reg_PI_MR14_DATA_Fx_CSx[1]
3598 [ddr_csn],
3599 mr14_bkup[ch][ddr_csn]);
3600 }
3601 }
3602
3603 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3604 0x00);
3605 if ((Prr_Product == PRR_PRODUCT_M3N)
3606 || (Prr_Product == PRR_PRODUCT_V3H)) {
3607 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3608 0x00);
3609 ddr_setval_ach
3610 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F1,
3611 0x00);
3612 ddr_setval_ach
3613 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1,
3614 0x00);
3615 } else {
3616 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x00);
3617 ddr_setval_ach
3618 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT,
3619 0x00);
3620 ddr_setval_ach
3621 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT,
3622 0x00);
3623 }
3624 ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE,
3625 0x00);
3626
3627 pvtcode_update2();
3628 err = wdqdm_man1();
3629 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
3630 }
3631 } while (err && (++retry_cnt < retry_max));
3632
3633 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
3634 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_10))) {
3635 wdqdm_cp(0, 1);
3636 }
3637
3638 return (retry_cnt >= retry_max);
3639}
3640
3641/*******************************************************************************
3642 * RDQ TRAINING
3643 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003644#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003645static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3646{
3647 int32_t i, k;
3648 uint32_t cs, slice;
3649 uint32_t dataL;
3650
3651 /***********************************************************************
3652 clr of training results buffer
3653 ***********************************************************************/
3654 cs = ddr_csn % 2;
3655 dataL = Boardcnf->dqdm_dly_r;
3656 for (slice = 0; slice < SLICE_CNT; slice++) {
3657 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3658 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3659 continue;
3660
3661 for (i = 0; i <= 8; i++) {
3662 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) {
3663 rdqdm_dly[ch][cs][slice][i] =
3664 rdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3665 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] =
3666 rdqdm_dly[ch][CS_CNT - 1 - cs][slice +
3667 SLICE_CNT]
3668 [i];
3669 } else {
3670 rdqdm_dly[ch][cs][slice][i] = dataL;
3671 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3672 }
3673 rdqdm_le[ch][cs][slice][i] = 0;
3674 rdqdm_le[ch][cs][slice + SLICE_CNT][i] = 0;
3675 rdqdm_te[ch][cs][slice][i] = 0;
3676 rdqdm_te[ch][cs][slice + SLICE_CNT][i] = 0;
3677 rdqdm_nw[ch][cs][slice][i] = 0;
3678 rdqdm_nw[ch][cs][slice + SLICE_CNT][i] = 0;
3679 }
3680 rdqdm_st[ch][cs][slice] = 0;
3681 rdqdm_win[ch][cs][slice] = 0;
3682 }
3683}
3684
3685static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3686{
3687 int32_t i, k;
3688 uint32_t cs, slice;
3689 uint32_t dataL;
3690 uint32_t err;
3691 int8_t _adj;
3692 int16_t adj;
3693 uint32_t dq;
3694
3695 /***********************************************************************
3696 analysis of training results
3697 ***********************************************************************/
3698 err = 0;
3699 for (slice = 0; slice < SLICE_CNT; slice++) {
3700 int32_t min_win;
3701 int32_t win;
3702 uint32_t rdq_status_obs_select;
3703 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3704 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3705 continue;
3706
3707 cs = ddr_csn % 2;
3708 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
3709 ddrphy_regif_idle();
3710
3711 ddr_getval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX);
3712 ddrphy_regif_idle();
3713
3714 for (i = 0; i <= 8; i++) {
3715 dq = slice * 8 + i;
3716 if (i == 8)
3717 _adj = Boardcnf->ch[ch].dm_adj_r[slice];
3718 else
3719 _adj = Boardcnf->ch[ch].dq_adj_r[dq];
3720
3721 adj = _f_scale_adj(_adj);
3722
3723 dataL =
3724 ddr_getval_s(ch, slice,
3725 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) +
3726 adj;
3727 ddr_setval_s(ch, slice,
3728 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i],
3729 dataL);
3730 rdqdm_dly[ch][cs][slice][i] = dataL;
3731
3732 dataL =
3733 ddr_getval_s(ch, slice,
3734 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) +
3735 adj;
3736 ddr_setval_s(ch, slice,
3737 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i],
3738 dataL);
3739 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3740 }
3741 min_win = INT_LEAST32_MAX;
3742 for (i = 0; i <= 8; i++) {
3743 dataL =
3744 ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS);
3745 rdqdm_st[ch][cs][slice] = dataL;
3746 rdqdm_st[ch][cs][slice + SLICE_CNT] = dataL;
3747 /* k : rise/fall */
3748 for (k = 0; k < 2; k++) {
3749 if (i == 8) {
3750 rdq_status_obs_select = 16 + 8 * k;
3751 } else {
3752 rdq_status_obs_select = i + k * 8;
3753 }
3754 ddr_setval_s(ch, slice,
3755 _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3756 rdq_status_obs_select);
3757
3758 dataL =
3759 ddr_getval_s(ch, slice,
3760 _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3761 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i] =
3762 dataL;
3763
3764 dataL =
3765 ddr_getval_s(ch, slice,
3766 _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3767 rdqdm_te[ch][cs][slice + SLICE_CNT * k][i] =
3768 dataL;
3769
3770 dataL =
3771 ddr_getval_s(ch, slice,
3772 _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS);
3773 rdqdm_nw[ch][cs][slice + SLICE_CNT * k][i] =
3774 dataL;
3775
3776 win =
3777 (int32_t) rdqdm_te[ch][cs][slice +
3778 SLICE_CNT *
3779 k][i] -
3780 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i];
3781 if (i != 8) {
3782 if (min_win > win)
3783 min_win = win;
3784 }
3785 }
3786 }
3787 rdqdm_win[ch][cs][slice] = min_win;
3788 if (min_win <= 0) {
3789 err = 2;
3790 }
3791 }
3792 return (err);
3793}
Marek Vasut6c245a52018-12-12 18:06:39 +01003794#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003795
3796static uint32_t rdqdm_man1(void)
3797{
3798 uint32_t ch;
3799 uint32_t ddr_csn;
Marek Vasut6c245a52018-12-12 18:06:39 +01003800#ifdef DDR_FAST_INIT
3801 uint32_t slice;
3802#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003803 uint32_t err;
3804
3805 /***********************************************************************
3806 manual execution of training
3807 ***********************************************************************/
3808 err = 0;
3809
Marek Vasut6c245a52018-12-12 18:06:39 +01003810 for (ddr_csn = 0; ddr_csn < CS_CNT; ddr_csn++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003811 /* KICK RDQLVL */
3812 err = swlvl1(ddr_csn, _reg_PI_RDLVL_CS, _reg_PI_RDLVL_REQ);
3813 if (err)
3814 goto err_exit;
Marek Vasut6c245a52018-12-12 18:06:39 +01003815#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003816 foreach_vch(ch) {
3817 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3818 rdqdm_clr1(ch, ddr_csn);
3819 ddrphy_regif_idle();
3820 continue;
3821 }
3822 err = rdqdm_ana1(ch, ddr_csn);
3823 ddrphy_regif_idle();
3824 if (err)
3825 goto err_exit;
3826 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003827#else/* DDR_FAST_INIT */
3828 foreach_vch(ch) {
3829 if (ch_have_this_cs[ddr_csn] & (1U << ch)) {
3830 for (slice = 0; slice < SLICE_CNT; slice++) {
3831 if (ddr_getval_s(ch, slice,
3832 _reg_PHY_RDLVL_STATUS_OBS) !=
3833 0x0D00FFFF) {
3834 err = (1U << ch) |
3835 (0x10U << slice);
3836 goto err_exit;
3837 }
3838 }
3839 }
3840 if (((Prr_Product == PRR_PRODUCT_H3)
3841 && (Prr_Cut <= PRR_PRODUCT_11))
3842 || ((Prr_Product == PRR_PRODUCT_M3)
3843 && (Prr_Cut <= PRR_PRODUCT_10))) {
3844 uint32_t i, adj, dataL;
3845
3846 for (slice = 0; slice < SLICE_CNT; slice++) {
3847 for (i = 0; i <= 8; i++) {
3848 if (i == 8)
3849 adj = _f_scale_adj(Boardcnf->ch[ch].dm_adj_r[slice]);
3850 else
3851 adj = _f_scale_adj(Boardcnf->ch[ch].dq_adj_r[slice * 8 + i]);
3852 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, ddr_csn);
3853 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj;
3854 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], dataL);
3855 rdqdm_dly[ch][ddr_csn][slice][i] = dataL;
3856 rdqdm_dly[ch][ddr_csn | 1][slice][i] = dataL;
3857
3858 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj;
3859 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], dataL);
3860 rdqdm_dly[ch][ddr_csn][slice + SLICE_CNT][i] = dataL;
3861 rdqdm_dly[ch][ddr_csn | 1][slice + SLICE_CNT][i] = dataL;
3862 }
3863 }
3864 }
3865 }
3866 ddrphy_regif_idle();
3867
3868#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003869 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003870
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003871err_exit:
3872 return (err);
3873}
3874
3875static uint32_t rdqdm_man(void)
3876{
3877 uint32_t err, retry_cnt;
3878 const uint32_t retry_max = 0x01;
3879
3880 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3881 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3882 _reg_PHY_DQ_TSEL_ENABLE));
3883 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3884 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3885 _reg_PHY_DQS_TSEL_ENABLE));
3886 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3887 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3888 _reg_PHY_DQ_TSEL_SELECT));
3889 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3890 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3891 _reg_PHY_DQS_TSEL_SELECT));
3892
3893 retry_cnt = 0;
3894 do {
3895 err = rdqdm_man1();
3896 ddrphy_regif_idle();
3897 } while (err && (++retry_cnt < retry_max));
3898 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3899 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3900 _reg_PHY_DQ_TSEL_ENABLE));
3901 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3902 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3903 _reg_PHY_DQS_TSEL_ENABLE));
3904 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3905 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3906 _reg_PHY_DQ_TSEL_SELECT));
3907 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3908 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3909 _reg_PHY_DQS_TSEL_SELECT));
3910
3911 return (retry_cnt >= retry_max);
3912}
3913
3914/*******************************************************************************
3915 * rx offset calibration
3916 ******************************************************************************/
3917static int32_t _find_change(uint64_t val, uint32_t dir)
3918{
3919 int32_t i;
3920 uint32_t startval;
3921 uint32_t curval;
3922 const uint32_t VAL_END = 0x3f;
3923
3924 if (dir == 0) {
3925 startval = (val & 0x01);
3926 for (i = 1; i <= VAL_END; i++) {
3927 curval = (val >> i) & 0x01;
3928 if (curval != startval)
3929 return (i);
3930 }
3931 return (VAL_END);
3932 } else {
3933 startval = (val >> dir) & 0x01;
3934 for (i = dir - 1; i >= 0; i--) {
3935 curval = (val >> i) & 0x01;
3936 if (curval != startval)
3937 return (i);
3938 }
3939 return (0);
3940 }
3941}
3942
3943static uint32_t _rx_offset_cal_updn(uint32_t code)
3944{
3945 const uint32_t CODE_MAX = 0x40;
3946 uint32_t tmp;
3947
3948 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3949 if (code == 0)
3950 tmp = (1U << 6) | (CODE_MAX - 1);
3951 else if (code <= 0x20)
3952 tmp =
3953 ((CODE_MAX - 1 -
3954 (0x20 - code) * 2) << 6) | (CODE_MAX - 1);
3955 else
3956 tmp =
3957 ((CODE_MAX - 1) << 6) | (CODE_MAX - 1 -
3958 (code - 0x20) * 2);
3959 } else {
3960 if (code == 0)
3961 tmp = (1U << 6) | (CODE_MAX - 1);
3962 else
3963 tmp = (code << 6) | (CODE_MAX - code);
3964 }
3965 return tmp;
3966}
3967
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003968static uint32_t rx_offset_cal(void)
3969{
3970 uint32_t index;
3971 uint32_t code;
3972 const uint32_t CODE_MAX = 0x40;
3973 const uint32_t CODE_STEP = 2;
3974 uint32_t ch, slice;
3975 uint32_t tmp;
3976 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
3977 uint64_t val[DRAM_CH_CNT][SLICE_CNT][_reg_PHY_RX_CAL_X_NUM];
Marek Vasut6c245a52018-12-12 18:06:39 +01003978
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003979 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x01);
3980 foreach_vch(ch) {
3981 for (slice = 0; slice < SLICE_CNT; slice++) {
3982 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
3983 val[ch][slice][index] = 0;
3984 }
3985 }
3986 }
3987
3988 for (code = 0; code < CODE_MAX / CODE_STEP; code++) {
3989 tmp = _rx_offset_cal_updn(code * CODE_STEP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003990 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
3991 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[index], tmp);
3992 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003993 dsb_sev();
3994 ddr_getval_ach_as(_reg_PHY_RX_CAL_OBS, (uint32_t *) tmp_ach_as);
3995
3996 foreach_vch(ch) {
3997 for (slice = 0; slice < SLICE_CNT; slice++) {
3998 tmp = tmp_ach_as[ch][slice];
3999 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM;
4000 index++) {
4001 if (tmp & (1U << index)) {
4002 val[ch][slice][index] |=
4003 (1ULL << code);
4004 } else {
4005 val[ch][slice][index] &=
4006 ~(1ULL << code);
4007 }
4008 }
4009 }
4010 }
4011 }
4012 foreach_vch(ch) {
4013 for (slice = 0; slice < SLICE_CNT; slice++) {
4014 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
4015 uint64_t tmpval;
4016 int32_t lsb, msb;
4017 tmpval = val[ch][slice][index];
4018 lsb = _find_change(tmpval, 0);
4019 msb =
4020 _find_change(tmpval,
4021 (CODE_MAX / CODE_STEP) - 1);
4022 tmp = (lsb + msb) >> 1;
4023
4024 tmp = _rx_offset_cal_updn(tmp * CODE_STEP);
4025 ddr_setval_s(ch, slice,
4026 _reg_PHY_RX_CAL_X[index], tmp);
4027 }
4028 }
4029 }
4030 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004031
4032 return 0;
4033}
4034
4035static uint32_t rx_offset_cal_hw(void)
4036{
4037 uint32_t ch, slice;
4038 uint32_t retry;
4039 uint32_t complete;
4040 uint32_t tmp;
4041 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
4042
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004043 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[9], 0x00);
4044 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
4045 ddr_setval_ach_as(_reg_PHY_RX_CAL_SAMPLE_WAIT, 0x0f);
4046
4047 retry = 0;
4048 while (retry < 4096) {
4049 if ((retry & 0xff) == 0) {
4050 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
4051 }
4052 foreach_vch(ch)
4053 for (slice = 0; slice < SLICE_CNT; slice++)
4054 tmp_ach_as[ch][slice] =
4055 ddr_getval_s(ch, slice, _reg_PHY_RX_CAL_X[9]);
4056
4057 complete = 1;
4058 foreach_vch(ch) {
4059 for (slice = 0; slice < SLICE_CNT; slice++) {
4060 tmp = tmp_ach_as[ch][slice];
4061 tmp = (tmp & 0x3f) + ((tmp >> 6) & 0x3f);
4062 if (((Prr_Product == PRR_PRODUCT_H3)
4063 && (Prr_Cut > PRR_PRODUCT_11))
4064 || (Prr_Product == PRR_PRODUCT_M3N)
4065 || (Prr_Product == PRR_PRODUCT_V3H)) {
4066 if (tmp != 0x3E)
4067 complete = 0;
4068 } else {
4069 if (tmp != 0x40)
4070 complete = 0;
4071 }
4072 }
4073 }
4074 if (complete)
4075 break;
4076
4077 retry++;
4078 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004079
4080 return (complete == 0);
4081}
4082
4083/*******************************************************************************
4084 * adjust rddqs latency
4085 ******************************************************************************/
4086static void adjust_rddqs_latency(void)
4087{
4088 uint32_t ch, slice;
4089 uint32_t dly;
4090 uint32_t maxlatx2;
4091 uint32_t tmp;
4092 uint32_t rdlat_adjx2[SLICE_CNT];
4093 foreach_vch(ch) {
4094 maxlatx2 = 0;
4095 for (slice = 0; slice < SLICE_CNT; slice++) {
4096 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX,
4097 0x00);
4098
4099 dly =
4100 ddr_getval_s(ch, slice,
4101 _reg_PHY_RDDQS_GATE_SLAVE_DELAY);
4102 tmp =
4103 ddr_getval_s(ch, slice,
4104 _reg_PHY_RDDQS_LATENCY_ADJUST);
4105 /* note gate_slave_delay[9] is always 0 */
4106 tmp = (tmp << 1) + (dly >> 8);
4107 rdlat_adjx2[slice] = tmp;
4108 if (maxlatx2 < tmp)
4109 maxlatx2 = tmp;
4110 }
4111 maxlatx2 = ((maxlatx2 + 1) >> 1) << 1;
4112 for (slice = 0; slice < SLICE_CNT; slice++) {
4113 tmp = maxlatx2 - rdlat_adjx2[slice];
4114 tmp = (tmp >> 1);
4115 if (tmp) {
4116 ddr_setval_s(ch, slice, _reg_PHY_RPTR_UPDATE,
4117 ddr_getval_s(ch, slice,
4118 _reg_PHY_RPTR_UPDATE)
4119 + 1);
4120 }
4121 }
4122 }
4123}
4124
4125/*******************************************************************************
4126 * adjust wpath latency
4127 ******************************************************************************/
4128static void adjust_wpath_latency(void)
4129{
4130 uint32_t ch, cs, slice;
4131 uint32_t dly;
4132 uint32_t wpath_add;
4133 const uint32_t _par_EARLY_THRESHOLD_VAL = 0x180;
4134
4135 foreach_vch(ch) {
4136 for (slice = 0; slice < SLICE_CNT; slice += 1) {
4137 for (cs = 0; cs < CS_CNT; cs++) {
4138 ddr_setval_s(ch, slice,
4139 _reg_PHY_PER_CS_TRAINING_INDEX,
4140 cs);
4141 ddr_getval_s(ch, slice,
4142 _reg_PHY_PER_CS_TRAINING_INDEX);
4143 dly =
4144 ddr_getval_s(ch, slice,
4145 _reg_PHY_CLK_WRDQS_SLAVE_DELAY);
4146 if (dly <= _par_EARLY_THRESHOLD_VAL)
4147 continue;
4148
4149 wpath_add =
4150 ddr_getval_s(ch, slice,
4151 _reg_PHY_WRITE_PATH_LAT_ADD);
4152 ddr_setval_s(ch, slice,
4153 _reg_PHY_WRITE_PATH_LAT_ADD,
4154 wpath_add - 1);
4155 }
4156 }
4157 }
4158}
4159
4160/*******************************************************************************
4161 * DDR Initialize entry
4162 ******************************************************************************/
4163int32_t rcar_dram_init(void)
4164{
4165 uint32_t ch, cs;
4166 uint32_t dataL;
4167 uint32_t bus_mbps, bus_mbpsdiv;
4168 uint32_t tmp_tccd;
4169 uint32_t failcount;
4170
4171 /***********************************************************************
4172 Thermal sensor setting
4173 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01004174 dataL = mmio_read_32(CPG_MSTPSR5);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004175 if (dataL & BIT22) { /* case THS/TSC Standby */
4176 dataL &= ~(BIT22);
Marek Vasut6c245a52018-12-12 18:06:39 +01004177 cpg_write_32(CPG_SMSTPCR5, dataL);
4178 while ((BIT22) & mmio_read_32(CPG_MSTPSR5)); /* wait bit=0 */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004179 }
4180
4181 /* THCTR Bit6: PONM=0 , Bit0: THSST=0 */
Marek Vasut6c245a52018-12-12 18:06:39 +01004182 dataL = mmio_read_32(THS1_THCTR) & 0xFFFFFFBE;
4183 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004184
4185 /***********************************************************************
4186 Judge product and cut
4187 ***********************************************************************/
4188#ifdef RCAR_DDR_FIXED_LSI_TYPE
4189#if(RCAR_LSI==RCAR_AUTO)
4190 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4191 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4192#else /* RCAR_LSI */
4193#ifndef RCAR_LSI_CUT
4194 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4195#endif /* RCAR_LSI_CUT */
4196#endif /* RCAR_LSI */
4197#else /* RCAR_DDR_FIXED_LSI_TYPE */
4198 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4199 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4200#endif /* RCAR_DDR_FIXED_LSI_TYPE */
4201
4202 if (Prr_Product == PRR_PRODUCT_H3) {
4203 if (Prr_Cut <= PRR_PRODUCT_11) {
4204 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[0][0];
4205 } else {
4206 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[2][0];
4207 }
4208 } else if (Prr_Product == PRR_PRODUCT_M3) {
4209 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[1][0];
4210 } else if ((Prr_Product == PRR_PRODUCT_M3N)
4211 || (Prr_Product == PRR_PRODUCT_V3H)) {
4212 pDDR_REGDEF_TBL = (uint32_t *) & DDR_REGDEF_TBL[3][0];
4213 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004214 FATAL_MSG("BL2: DDR:Unknown Product\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004215 return 0xff;
4216 }
4217
4218 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
4219 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_20))) {
4220 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4221 } else {
4222 mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
4223 }
4224
4225 /***********************************************************************
4226 Judge board type
4227 ***********************************************************************/
4228 _cnf_BOARDTYPE = boardcnf_get_brd_type();
4229 if (_cnf_BOARDTYPE >= BOARDNUM) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004230 FATAL_MSG("BL2: DDR:Unknown Board\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004231 return 0xff;
4232 }
4233 Boardcnf = (struct _boardcnf *)&boardcnfs[_cnf_BOARDTYPE];
4234
4235/* RCAR_DRAM_SPLIT_2CH (2U) */
4236#if RCAR_DRAM_SPLIT == 2
4237 /***********************************************************************
4238 H3(Test for future H3-N): Swap ch2 and ch1 for 2ch-split
4239 ***********************************************************************/
4240 if ((Prr_Product == PRR_PRODUCT_H3) && (Boardcnf->phyvalid == 0x05)) {
4241 mmio_write_32(DBSC_DBMEMSWAPCONF0, 0x00000006);
4242 ddr_phyvalid = 0x03;
4243 } else {
4244 ddr_phyvalid = Boardcnf->phyvalid;
4245 }
4246#else /* RCAR_DRAM_SPLIT_2CH */
4247 ddr_phyvalid = Boardcnf->phyvalid;
4248#endif /* RCAR_DRAM_SPLIT_2CH */
4249
4250 max_density = 0;
4251
4252 for (cs = 0; cs < CS_CNT; cs++) {
4253 ch_have_this_cs[cs] = 0;
4254 }
4255
4256 foreach_ech(ch)
4257 for (cs = 0; cs < CS_CNT; cs++)
4258 ddr_density[ch][cs] = 0xff;
4259
4260 foreach_vch(ch) {
4261 for (cs = 0; cs < CS_CNT; cs++) {
4262 dataL = Boardcnf->ch[ch].ddr_density[cs];
4263 ddr_density[ch][cs] = dataL;
4264
4265 if (dataL == 0xff)
4266 continue;
4267 if (dataL > max_density)
4268 max_density = dataL;
4269 if ((cs == 1) && (Prr_Product == PRR_PRODUCT_H3)
4270 && (Prr_Cut <= PRR_PRODUCT_11))
4271 continue;
4272 ch_have_this_cs[cs] |= (1U << ch);
4273 }
4274 }
4275
4276 /***********************************************************************
4277 Judge board clock frequency (in MHz)
4278 ***********************************************************************/
4279 boardcnf_get_brd_clk(_cnf_BOARDTYPE, &brd_clk, &brd_clkdiv);
4280 if ((brd_clk / brd_clkdiv) > 25) {
4281 brd_clkdiva = 1;
4282 } else {
4283 brd_clkdiva = 0;
4284 }
4285
4286 /***********************************************************************
4287 Judge ddr operating frequency clock(in Mbps)
4288 ***********************************************************************/
4289 boardcnf_get_ddr_mbps(_cnf_BOARDTYPE, &ddr_mbps, &ddr_mbpsdiv);
4290
4291 ddr0800_mul = CLK_DIV(800, 2, brd_clk, brd_clkdiv * (brd_clkdiva + 1));
4292
4293 ddr_mul =
4294 CLK_DIV(ddr_mbps, ddr_mbpsdiv * 2, brd_clk,
4295 brd_clkdiv * (brd_clkdiva + 1));
4296
4297 /***********************************************************************
4298 Adjust tccd
4299 ***********************************************************************/
4300 dataL = (0x00006000 & mmio_read_32(RST_MODEMR)) >> 13;
4301 switch (dataL) {
4302 case 0:
4303 bus_mbps = brd_clk * 0x60 * 2;
4304 bus_mbpsdiv = brd_clkdiv * 1;
4305 break;
4306 case 1:
4307 bus_mbps = brd_clk * 0x50 * 2;
4308 bus_mbpsdiv = brd_clkdiv * 1;
4309 break;
4310 case 2:
4311 bus_mbps = brd_clk * 0x40 * 2;
4312 bus_mbpsdiv = brd_clkdiv * 1;
4313 break;
4314 case 3:
4315 bus_mbps = brd_clk * 0x60 * 2;
4316 bus_mbpsdiv = brd_clkdiv * 2;
4317 break;
4318 default:
4319 bus_mbps = brd_clk * 0x60 * 2;
4320 bus_mbpsdiv = brd_clkdiv * 2;
4321 break;
4322 }
4323 tmp_tccd = CLK_DIV(ddr_mbps * 8, ddr_mbpsdiv, bus_mbps, bus_mbpsdiv);
4324 if (8 * ddr_mbps * bus_mbpsdiv != tmp_tccd * bus_mbps * ddr_mbpsdiv)
4325 tmp_tccd = tmp_tccd + 1;
4326
4327 if (tmp_tccd < 8)
4328 ddr_tccd = 8;
4329 else
4330 ddr_tccd = tmp_tccd;
4331
Marek Vasut6c245a52018-12-12 18:06:39 +01004332 NOTICE("BL2: DDR%d(%s)\n", ddr_mbps / ddr_mbpsdiv, RCAR_DDR_VERSION);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004333
4334 MSG_LF("Start\n");
4335
4336 /***********************************************************************
4337 PLL Setting
4338 ***********************************************************************/
4339 pll3_control(1);
4340
4341 /***********************************************************************
4342 initialize DDR
4343 ***********************************************************************/
4344 dataL = init_ddr();
4345 if (dataL == ddr_phyvalid) {
4346 failcount = 0;
4347 } else {
4348 failcount = 1;
4349 }
4350
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004351 foreach_vch(ch)
4352 mmio_write_32(DBSC_DBPDLK(ch), 0x00000000);
4353 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
4354 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_20))) {
4355 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4356 } else {
4357 mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
4358 }
4359
4360 if (failcount == 0) {
4361 return INITDRAM_OK;
4362 } else {
4363 return INITDRAM_NG;
4364 }
4365}
4366
4367void pvtcode_update(void)
4368{
4369 uint32_t ch;
Marek Vasut6c245a52018-12-12 18:06:39 +01004370 uint32_t dataL;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004371 uint32_t pvtp[4], pvtn[4], pvtp_init, pvtn_init;
4372 int32_t pvtp_tmp, pvtn_tmp;
4373
4374 foreach_vch(ch) {
4375 pvtn_init = (tcal.tcomp_cal[ch] & 0xFC0) >> 6;
4376 pvtp_init = (tcal.tcomp_cal[ch] & 0x03F) >> 0;
4377
4378 if (8912 * pvtp_init > 44230) {
4379 pvtp_tmp = (5000 + 8912 * pvtp_init - 44230) / 10000;
4380 } else {
4381 pvtp_tmp =
4382 -((-(5000 + 8912 * pvtp_init - 44230)) / 10000);
4383 }
4384 pvtn_tmp = (5000 + 5776 * pvtn_init + 30280) / 10000;
4385
4386 pvtn[ch] = pvtn_tmp + pvtn_init;
4387 pvtp[ch] = pvtp_tmp + pvtp_init;
4388
4389 if (pvtn[ch] > 63) {
4390 pvtn[ch] = 63;
4391 pvtp[ch] =
4392 (pvtp_tmp) * (63 - 6 * pvtn_tmp -
4393 pvtn_init) / (pvtn_tmp) +
4394 6 * pvtp_tmp + pvtp_init;
4395 }
4396 if ((Prr_Product == PRR_PRODUCT_H3)
4397 && (Prr_Cut <= PRR_PRODUCT_11)) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004398 dataL = pvtp[ch] | (pvtn[ch] << 6) | (tcal.tcomp_cal[ch] & 0xfffff000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004399 reg_ddrphy_write(ch,
4400 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004401 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004402 reg_ddrphy_write(ch,
4403 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004404 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004405 reg_ddrphy_write(ch,
4406 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004407 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004408 reg_ddrphy_write(ch,
4409 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004410 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004411 reg_ddrphy_write(ch,
4412 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004413 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004414 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004415 dataL = pvtp[ch] | (pvtn[ch] << 6) | 0x00015000;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004416 reg_ddrphy_write(ch,
4417 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004418 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004419 reg_ddrphy_write(ch,
4420 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004421 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004422 reg_ddrphy_write(ch,
4423 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004424 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004425 reg_ddrphy_write(ch,
4426 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004427 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004428 reg_ddrphy_write(ch,
4429 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004430 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004431 }
4432 }
4433}
4434
4435void pvtcode_update2(void)
4436{
4437 uint32_t ch;
4438 foreach_vch(ch) {
4439 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
4440 tcal.init_cal[ch] | 0x00020000);
4441 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
4442 tcal.init_cal[ch]);
4443 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
4444 tcal.init_cal[ch]);
4445 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
4446 tcal.init_cal[ch]);
4447 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
4448 tcal.init_cal[ch]);
4449 }
4450}
4451
4452void ddr_padcal_tcompensate_getinit(uint32_t override)
4453{
4454 uint32_t ch;
4455 uint32_t dataL;
4456 uint32_t pvtp, pvtn;
4457
4458 tcal.init_temp = 0;
4459 for (ch = 0; ch < 4; ch++) {
4460 tcal.init_cal[ch] = 0;
4461 tcal.tcomp_cal[ch] = 0;
4462 }
4463
4464 foreach_vch(ch) {
4465 tcal.init_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4466 tcal.tcomp_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4467 }
4468
4469 if (!override) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004470 dataL = mmio_read_32(THS1_TEMP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004471 if (dataL < 2800) {
4472 tcal.init_temp =
4473 (143 * (int32_t) dataL - 359000) / 1000;
4474 } else {
4475 tcal.init_temp =
4476 (121 * (int32_t) dataL - 296300) / 1000;
4477 }
4478
4479 foreach_vch(ch) {
4480 pvtp = (tcal.init_cal[ch] >> 0) & 0x000003F;
4481 pvtn = (tcal.init_cal[ch] >> 6) & 0x000003F;
4482 if ((int32_t) pvtp >
4483 ((tcal.init_temp * 29 - 3625) / 1000))
4484 pvtp =
4485 (int32_t) pvtp +
4486 ((3625 - tcal.init_temp * 29) / 1000);
4487 else
4488 pvtp = 0;
4489
4490 if ((int32_t) pvtn >
4491 ((tcal.init_temp * 54 - 6750) / 1000))
4492 pvtn =
4493 (int32_t) pvtn +
4494 ((6750 - tcal.init_temp * 54) / 1000);
4495 else
4496 pvtn = 0;
4497
4498 if ((Prr_Product == PRR_PRODUCT_H3)
4499 && (Prr_Cut <= PRR_PRODUCT_11)) {
4500 tcal.init_cal[ch] =
4501 (tcal.
4502 init_cal[ch] & 0xfffff000) | (pvtn << 6) |
4503 (pvtp);
4504 } else {
4505 tcal.init_cal[ch] =
4506 0x00015000 | (pvtn << 6) | (pvtp);
4507 }
4508 }
4509 tcal.init_temp = 125;
4510 }
4511}
4512
4513#ifndef ddr_qos_init_setting
4514/* for QoS init */
4515uint8_t get_boardcnf_phyvalid(void)
4516{
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004517 return ddr_phyvalid;
4518}
4519#endif /* ddr_qos_init_setting */
4520
4521/*******************************************************************************
4522 * END
4523 ******************************************************************************/