blob: 2cce653392909e8f28260e9b5af095bae535f3f5 [file] [log] [blame]
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001/*
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002 * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003 *
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"
Marek Vasutd97f6ee2019-08-06 18:58:38 +020023#include "rcar_def.h"
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020024
25#define DDR_BACKUPMODE
26#define FATAL_MSG(x) NOTICE(x)
27
28/*******************************************************************************
29 * variables
30 ******************************************************************************/
31#ifdef RCAR_DDR_FIXED_LSI_TYPE
32#ifndef RCAR_AUTO
33#define RCAR_AUTO 99
34#define RCAR_H3 0
35#define RCAR_M3 1
36#define RCAR_M3N 2
37#define RCAR_E3 3 /* NON */
38#define RCAR_H3N 4
39
40#define RCAR_CUT_10 0
41#define RCAR_CUT_11 1
42#define RCAR_CUT_20 10
43#define RCAR_CUT_30 20
44#endif
45#ifndef RCAR_LSI
46#define RCAR_LSI RCAR_AUTO
47#endif
48#if(RCAR_LSI==RCAR_AUTO)
49static uint32_t Prr_Product;
50static uint32_t Prr_Cut;
51#else
52#if(RCAR_LSI==RCAR_H3)
53static const uint32_t Prr_Product = PRR_PRODUCT_H3;
54#elif(RCAR_LSI==RCAR_M3)
55static const uint32_t Prr_Product = PRR_PRODUCT_M3;
56#elif(RCAR_LSI==RCAR_M3N)
57static const uint32_t Prr_Product = PRR_PRODUCT_M3N;
58#elif(RCAR_LSI==RCAR_H3N)
59static const uint32_t Prr_Product = PRR_PRODUCT_H3;
60#endif /* RCAR_LSI */
61
62#ifndef RCAR_LSI_CUT
63static uint32_t Prr_Cut;
64#else /* RCAR_LSI_CUT */
65#if(RCAR_LSI_CUT==RCAR_CUT_10)
66static const uint32_t Prr_Cut = PRR_PRODUCT_10;
67#elif(RCAR_LSI_CUT==RCAR_CUT_11)
68static const uint32_t Prr_Cut = PRR_PRODUCT_11;
69#elif(RCAR_LSI_CUT==RCAR_CUT_20)
70static const uint32_t Prr_Cut = PRR_PRODUCT_20;
71#elif(RCAR_LSI_CUT==RCAR_CUT_30)
72static const uint32_t Prr_Cut = PRR_PRODUCT_30;
73#endif /* RCAR_LSI_CUT */
74#endif /* RCAR_LSI_CUT */
75#endif /* RCAR_AUTO_NON */
76#else /* RCAR_DDR_FIXED_LSI_TYPE */
77static uint32_t Prr_Product;
78static uint32_t Prr_Cut;
79#endif /* RCAR_DDR_FIXED_LSI_TYPE */
80
81char *pRCAR_DDR_VERSION;
82uint32_t _cnf_BOARDTYPE;
Chiaki Fujii59263ee2019-05-17 10:45:02 +090083static const uint32_t *pDDR_REGDEF_TBL;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020084static uint32_t brd_clk;
85static uint32_t brd_clkdiv;
86static uint32_t brd_clkdiva;
87static uint32_t ddr_mbps;
88static uint32_t ddr_mbpsdiv;
89static uint32_t ddr_tccd;
Marek Vasut6c245a52018-12-12 18:06:39 +010090static uint32_t ddr_phycaslice;
Chiaki Fujii59263ee2019-05-17 10:45:02 +090091static const struct _boardcnf *Boardcnf;
92static uint32_t ddr_phyvalid;
93static uint32_t ddr_density[DRAM_CH_CNT][CS_CNT];
94static uint32_t ch_have_this_cs[CS_CNT] __attribute__ ((aligned(64)));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020095static uint32_t rdqdm_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT * 2][9];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020096static uint32_t max_density;
97static uint32_t ddr0800_mul;
98static uint32_t ddr_mul;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +020099static 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 ******************************************************************************/
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900232static inline uint32_t vch_nxt(uint32_t pos);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200233static 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 ******************************************************************************/
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900332static inline uint32_t vch_nxt(uint32_t pos)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200333{
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900334 uint32_t posn;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200335
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) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900368 tmpDIV = 3999 * brd_clkdiv * (brd_clkdiva + 1) /
369 (brd_clk * ddr_mul) / 2;
370 dataMUL = (((ddr_mul * tmpDIV) - 1) << 24) |
371 (brd_clkdiva << 7);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200372 Pll3Mode = 1;
373 loop_max = 2;
374 } else {
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900375 tmpDIV = 3999 * brd_clkdiv * (brd_clkdiva + 1) /
376 (brd_clk * ddr0800_mul) / 2;
377 dataMUL = (((ddr0800_mul * tmpDIV) - 1) << 24) |
378 (brd_clkdiva << 7);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200379 Pll3Mode = 0;
380 loop_max = 8;
381 }
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900382
383 switch (tmpDIV) {
384 case 1:
Marek Vasut6c245a52018-12-12 18:06:39 +0100385 dataDIV = 0;
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900386 break;
387 case 2:
388 case 3:
389 case 4:
390 dataDIV = tmpDIV;
391 break;
392 default:
393 dataDIV = 6;
394 dataMUL = (dataMUL * tmpDIV) / 3;
395 break;
Marek Vasut6c245a52018-12-12 18:06:39 +0100396 }
397 dataMUL = dataMUL | (brd_clkdiva << 7);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200398
Marek Vasut6c245a52018-12-12 18:06:39 +0100399 /* PLL3 disable */
400 dataL = mmio_read_32(CPG_PLLECR) & ~CPG_PLLECR_PLL3E_BIT;
401 cpg_write_32(CPG_PLLECR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200402 dsb_sev();
403
Marek Vasut6c245a52018-12-12 18:06:39 +0100404 if ((Prr_Product == PRR_PRODUCT_M3) ||
405 ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_20))) {
406 /* PLL3 DIV resetting(Lowest value:3) */
407 dataL = 0x00030003 | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
408 cpg_write_32(CPG_FRQCRD, dataL);
409 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200410
Marek Vasut6c245a52018-12-12 18:06:39 +0100411 /* zb3 clk stop */
412 dataL = CPG_ZB3CKCR_ZB3ST_BIT | mmio_read_32(CPG_ZB3CKCR);
413 cpg_write_32(CPG_ZB3CKCR, dataL);
414 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200415
Marek Vasut6c245a52018-12-12 18:06:39 +0100416 /* PLL3 enable */
417 dataL = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR);
418 cpg_write_32(CPG_PLLECR, dataL);
419 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200420
Marek Vasut6c245a52018-12-12 18:06:39 +0100421 do {
422 dataL = mmio_read_32(CPG_PLLECR);
423 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
424 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200425
Marek Vasut6c245a52018-12-12 18:06:39 +0100426 /* PLL3 DIV resetting (Highest value:0) */
427 dataL = (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
428 cpg_write_32(CPG_FRQCRD, dataL);
429 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200430
Marek Vasut6c245a52018-12-12 18:06:39 +0100431 /* DIV SET KICK */
432 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
433 cpg_write_32(CPG_FRQCRB, dataL);
434 dsb_sev();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200435
Marek Vasut6c245a52018-12-12 18:06:39 +0100436 /* PLL3 multiplie set */
437 cpg_write_32(CPG_PLL3CR, dataMUL);
438 dsb_sev();
439
440 do {
441 dataL = mmio_read_32(CPG_PLLECR);
442 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
443 dsb_sev();
444
445 /* PLL3 DIV resetting(Target value) */
446 dataL = (dataDIV << 16) | dataDIV | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
447 cpg_write_32(CPG_FRQCRD, dataL);
448 dsb_sev();
449
450 /* DIV SET KICK */
451 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
452 cpg_write_32(CPG_FRQCRB, dataL);
453 dsb_sev();
454
455 do {
456 dataL = mmio_read_32(CPG_PLLECR);
457 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
458 dsb_sev();
459
460 /* zb3 clk start */
461 dataL = (~CPG_ZB3CKCR_ZB3ST_BIT) & mmio_read_32(CPG_ZB3CKCR);
462 cpg_write_32(CPG_ZB3CKCR, dataL);
463 dsb_sev();
464
465 } else { /* H3Ver.3.0/M3N/V3H */
466
467 /* PLL3 multiplie set */
468 cpg_write_32(CPG_PLL3CR, dataMUL);
469 dsb_sev();
470
471 /* PLL3 DIV set(Target value) */
472 dataL = (dataDIV << 16) | dataDIV | (0xFF80FF80 & mmio_read_32(CPG_FRQCRD));
473 cpg_write_32(CPG_FRQCRD, dataL);
474
475 /* DIV SET KICK */
476 dataL = CPG_FRQCRB_KICK_BIT | mmio_read_32(CPG_FRQCRB);
477 cpg_write_32(CPG_FRQCRB, dataL);
478 dsb_sev();
479
480 /* PLL3 enable */
481 dataL = CPG_PLLECR_PLL3E_BIT | mmio_read_32(CPG_PLLECR);
482 cpg_write_32(CPG_PLLECR, dataL);
483 dsb_sev();
484
485 do {
486 dataL = mmio_read_32(CPG_PLLECR);
487 } while ((dataL & CPG_PLLECR_PLL3ST_BIT) == 0);
488 dsb_sev();
489 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200490}
491
492/*******************************************************************************
493 * barrier
494 ******************************************************************************/
495static inline void dsb_sev(void)
496{
497 __asm__ __volatile__("dsb sy");
498}
499
500/*******************************************************************************
501 * DDR memory register access
502 ******************************************************************************/
503static void wait_dbcmd(void)
504{
505 uint32_t dataL;
506 /* dummy read */
507 dataL = mmio_read_32(DBSC_DBCMD);
508 dsb_sev();
509 while (1) {
510 /* wait DBCMD 1=busy, 0=ready */
511 dataL = mmio_read_32(DBSC_DBWAIT);
512 dsb_sev();
513 if ((dataL & 0x00000001) == 0x00)
514 break;
515 }
516}
517
518static void send_dbcmd(uint32_t cmd)
519{
520 /* dummy read */
521 wait_dbcmd();
522 mmio_write_32(DBSC_DBCMD, cmd);
523 dsb_sev();
524}
525
526/*******************************************************************************
527 * DDRPHY register access (raw)
528 ******************************************************************************/
529static uint32_t reg_ddrphy_read(uint32_t phyno, uint32_t regadd)
530{
531 uint32_t val;
532 uint32_t loop;
533
534 val = 0;
535 if ((PRR_PRODUCT_M3N != Prr_Product)
536 && (PRR_PRODUCT_V3H != Prr_Product)) {
537 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
538 dsb_sev();
539
540 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
541 dsb_sev();
542 }
543 dsb_sev();
544
545 for (loop = 0; loop < loop_max; loop++) {
546 val = mmio_read_32(DBSC_DBPDRGD(phyno));
547 dsb_sev();
548 }
549 (void)val;
550 } else {
551 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00004000);
552 dsb_sev();
553 while (mmio_read_32(DBSC_DBPDRGA(phyno)) !=
554 (regadd | 0x0000C000)) {
555 dsb_sev();
556 };
557 val = mmio_read_32(DBSC_DBPDRGA(phyno));
558 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
559 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
560 dsb_sev();
561 };
562 dsb_sev();
563
564 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
565 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
566 dsb_sev();
567 };
568
569 dsb_sev();
570 val = mmio_read_32(DBSC_DBPDRGD(phyno));
571 dsb_sev();
572 (void)val;
573 }
574 return val;
575}
576
577static void reg_ddrphy_write(uint32_t phyno, uint32_t regadd, uint32_t regdata)
578{
579 uint32_t val;
580 uint32_t loop;
581
582 if ((PRR_PRODUCT_M3N != Prr_Product)
583 && (PRR_PRODUCT_V3H != Prr_Product)) {
584 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
585 dsb_sev();
586 for (loop = 0; loop < loop_max; loop++) {
587 val = mmio_read_32(DBSC_DBPDRGA(phyno));
588 dsb_sev();
589 }
590 mmio_write_32(DBSC_DBPDRGD(phyno), regdata);
591 dsb_sev();
592
593 for (loop = 0; loop < loop_max; loop++) {
594 val = mmio_read_32(DBSC_DBPDRGD(phyno));
595 dsb_sev();
596 }
597 } else {
598 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
599 dsb_sev();
600
601 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
602 dsb_sev();
603 };
604 dsb_sev();
605
606 mmio_write_32(DBSC_DBPDRGD(phyno), regdata);
607 dsb_sev();
608
609 while (mmio_read_32(DBSC_DBPDRGA(phyno)) !=
610 (regadd | 0x00008000)) {
611 dsb_sev();
612 };
613 mmio_write_32(DBSC_DBPDRGA(phyno), regadd | 0x00008000);
614
615 while (mmio_read_32(DBSC_DBPDRGA(phyno)) != regadd) {
616 dsb_sev();
617 };
618 dsb_sev();
619
620 mmio_write_32(DBSC_DBPDRGA(phyno), regadd);
621 }
622 (void)val;
623}
624
625static void reg_ddrphy_write_a(uint32_t regadd, uint32_t regdata)
626{
627 uint32_t ch;
628 uint32_t val;
629 uint32_t loop;
630
631 if ((PRR_PRODUCT_M3N != Prr_Product)
632 && (PRR_PRODUCT_V3H != Prr_Product)) {
633 foreach_vch(ch) {
634 mmio_write_32(DBSC_DBPDRGA(ch), regadd);
635 dsb_sev();
636 }
637
638 foreach_vch(ch) {
639 mmio_write_32(DBSC_DBPDRGD(ch), regdata);
640 dsb_sev();
641 }
642
643 for (loop = 0; loop < loop_max; loop++) {
644 val = mmio_read_32(DBSC_DBPDRGD(0));
645 dsb_sev();
646 }
647 (void)val;
648 } else {
649 foreach_vch(ch) {
650 reg_ddrphy_write(ch, regadd, regdata);
651 dsb_sev();
652 }
653 }
654}
655
656static inline void ddrphy_regif_idle()
657{
658 uint32_t val;
659
660 val = reg_ddrphy_read(0, ddr_regdef_adr(_reg_PI_INT_STATUS));
661 dsb_sev();
662 (void)val;
663}
664
665/*******************************************************************************
666 * DDRPHY register access (field modify)
667 ******************************************************************************/
668static inline uint32_t ddr_regdef(uint32_t _regdef)
669{
670 return pDDR_REGDEF_TBL[_regdef];
671}
672
673static inline uint32_t ddr_regdef_adr(uint32_t _regdef)
674{
675 return DDR_REGDEF_ADR(pDDR_REGDEF_TBL[_regdef]);
676}
677
678static inline uint32_t ddr_regdef_lsb(uint32_t _regdef)
679{
680 return DDR_REGDEF_LSB(pDDR_REGDEF_TBL[_regdef]);
681}
682
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200683static void ddr_setval_s(uint32_t ch, uint32_t slice, uint32_t _regdef,
684 uint32_t val)
685{
686 uint32_t adr;
687 uint32_t lsb;
688 uint32_t len;
689 uint32_t msk;
690 uint32_t tmp;
691 uint32_t regdef;
692
693 regdef = ddr_regdef(_regdef);
694 adr = DDR_REGDEF_ADR(regdef) + 0x80 * slice;
695 len = DDR_REGDEF_LEN(regdef);
696 lsb = DDR_REGDEF_LSB(regdef);
697 if (len == 0x20)
698 msk = 0xffffffff;
699 else
700 msk = ((1U << len) - 1) << lsb;
701
702 tmp = reg_ddrphy_read(ch, adr);
703 tmp = (tmp & (~msk)) | ((val << lsb) & msk);
704 reg_ddrphy_write(ch, adr, tmp);
705}
706
707static uint32_t ddr_getval_s(uint32_t ch, uint32_t slice, uint32_t _regdef)
708{
709 uint32_t adr;
710 uint32_t lsb;
711 uint32_t len;
712 uint32_t msk;
713 uint32_t tmp;
714 uint32_t regdef;
715
716 regdef = ddr_regdef(_regdef);
717 adr = DDR_REGDEF_ADR(regdef) + 0x80 * slice;
718 len = DDR_REGDEF_LEN(regdef);
719 lsb = DDR_REGDEF_LSB(regdef);
720 if (len == 0x20)
721 msk = 0xffffffff;
722 else
723 msk = ((1U << len) - 1);
724
725 tmp = reg_ddrphy_read(ch, adr);
726 tmp = (tmp >> lsb) & msk;
727
728 return tmp;
729}
730
731static void ddr_setval(uint32_t ch, uint32_t regdef, uint32_t val)
732{
733 ddr_setval_s(ch, 0, regdef, val);
734}
735
736static void ddr_setval_ach_s(uint32_t slice, uint32_t regdef, uint32_t val)
737{
738 uint32_t ch;
739
740 foreach_vch(ch)
741 ddr_setval_s(ch, slice, regdef, val);
742}
743
744static void ddr_setval_ach(uint32_t regdef, uint32_t val)
745{
746 ddr_setval_ach_s(0, regdef, val);
747}
748
749static void ddr_setval_ach_as(uint32_t regdef, uint32_t val)
750{
751 uint32_t slice;
752
753 for (slice = 0; slice < SLICE_CNT; slice++)
754 ddr_setval_ach_s(slice, regdef, val);
755}
756
757static uint32_t ddr_getval(uint32_t ch, uint32_t regdef)
758{
759 return ddr_getval_s(ch, 0, regdef);
760}
761
762static uint32_t ddr_getval_ach(uint32_t regdef, uint32_t * p)
763{
764 uint32_t ch;
765
766 foreach_vch(ch)
767 p[ch] = ddr_getval_s(ch, 0, regdef);
768 return p[0];
769}
770
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200771static uint32_t ddr_getval_ach_as(uint32_t regdef, uint32_t * p)
772{
773 uint32_t ch, slice;
774 uint32_t *pp;
775
776 pp = p;
777 foreach_vch(ch)
778 for (slice = 0; slice < SLICE_CNT; slice++)
779 *pp++ = ddr_getval_s(ch, slice, regdef);
780 return p[0];
781}
782
783/*******************************************************************************
784 * handling functions for setteing ddrphy value table
785 ******************************************************************************/
786static void _tblcopy(uint32_t * to, const uint32_t * from, uint32_t size)
787{
788 uint32_t i;
789
790 for (i = 0; i < size; i++) {
791 to[i] = from[i];
792 }
793}
794
795static void ddrtbl_setval(uint32_t * tbl, uint32_t _regdef, uint32_t val)
796{
797 uint32_t adr;
798 uint32_t lsb;
799 uint32_t len;
800 uint32_t msk;
801 uint32_t tmp;
802 uint32_t adrmsk;
803 uint32_t regdef;
804
805 regdef = ddr_regdef(_regdef);
806 adr = DDR_REGDEF_ADR(regdef);
807 len = DDR_REGDEF_LEN(regdef);
808 lsb = DDR_REGDEF_LSB(regdef);
809 if (len == 0x20)
810 msk = 0xffffffff;
811 else
812 msk = ((1U << len) - 1) << lsb;
813
814 if (adr < 0x400) {
815 adrmsk = 0xff;
816 } else {
817 adrmsk = 0x7f;
818 }
819
820 tmp = tbl[adr & adrmsk];
821 tmp = (tmp & (~msk)) | ((val << lsb) & msk);
822 tbl[adr & adrmsk] = tmp;
823}
824
825static uint32_t ddrtbl_getval(uint32_t * tbl, uint32_t _regdef)
826{
827 uint32_t adr;
828 uint32_t lsb;
829 uint32_t len;
830 uint32_t msk;
831 uint32_t tmp;
832 uint32_t adrmsk;
833 uint32_t regdef;
834
835 regdef = ddr_regdef(_regdef);
836 adr = DDR_REGDEF_ADR(regdef);
837 len = DDR_REGDEF_LEN(regdef);
838 lsb = DDR_REGDEF_LSB(regdef);
839 if (len == 0x20)
840 msk = 0xffffffff;
841 else
842 msk = ((1U << len) - 1);
843
844 if (adr < 0x400) {
845 adrmsk = 0xff;
846 } else {
847 adrmsk = 0x7f;
848 }
849
850 tmp = tbl[adr & adrmsk];
851 tmp = (tmp >> lsb) & msk;
852
853 return tmp;
854}
855
856/*******************************************************************************
857 * DDRPHY register access handling
858 ******************************************************************************/
859static uint32_t ddrphy_regif_chk(void)
860{
861 uint32_t tmp_ach[DRAM_CH_CNT];
862 uint32_t ch;
863 uint32_t err;
864 uint32_t PI_VERSION_CODE;
865
866 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
867 || (Prr_Product == PRR_PRODUCT_M3)) {
868 PI_VERSION_CODE = 0x2041; /* H3 Ver.1.x/M3-W */
869 } else {
870 PI_VERSION_CODE = 0x2040; /* H3 Ver.2.0 or later/M3-N/V3H */
871 }
872
873 ddr_getval_ach(_reg_PI_VERSION, (uint32_t *) tmp_ach);
874 err = 0;
875 foreach_vch(ch) {
876 if (PI_VERSION_CODE != tmp_ach[ch])
877 err = 1;
878 }
879 return err;
880}
881
882/*******************************************************************************
883 * functions and parameters for timing setting
884 ******************************************************************************/
885struct _jedec_spec1 {
886 uint16_t fx3;
887 uint8_t RLwoDBI;
888 uint8_t RLwDBI;
889 uint8_t WL;
890 uint8_t nWR;
891 uint8_t nRTP;
892 uint8_t MR1;
893 uint8_t MR2;
894};
895#define JS1_USABLEC_SPEC_LO 2
896#define JS1_USABLEC_SPEC_HI 5
897#define JS1_FREQ_TBL_NUM 8
898#define JS1_MR1(f) (0x04 | ((f)<<4))
899#define JS1_MR2(f) (0x00 | ((f)<<3) | (f))
900const struct _jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
Chiaki Fujii59263ee2019-05-17 10:45:02 +0900901 { 800, 6, 6, 4, 6, 8, JS1_MR1(0), JS1_MR2(0)|0x40 }, /* 533.333Mbps */
902 { 1600, 10, 12, 8, 10, 8, JS1_MR1(1), JS1_MR2(1)|0x40 }, /* 1066.666Mbps */
903 { 2400, 14, 16, 12, 16, 8, JS1_MR1(2), JS1_MR2(2)|0x40 }, /* 1600.000Mbps */
904 { 3200, 20, 22, 10, 20, 8, JS1_MR1(3), JS1_MR2(3) }, /* 2133.333Mbps */
905 { 4000, 24, 28, 12, 24, 10, JS1_MR1(4), JS1_MR2(4) }, /* 2666.666Mbps */
906 { 4800, 28, 32, 14, 30, 12, JS1_MR1(5), JS1_MR2(5) }, /* 3200.000Mbps */
907 { 5600, 32, 36, 16, 34, 14, JS1_MR1(6), JS1_MR2(6) }, /* 3733.333Mbps */
908 { 6400, 36, 40, 18, 40, 16, JS1_MR1(7), JS1_MR2(7) } /* 4266.666Mbps */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200909};
910
911struct _jedec_spec2 {
912 uint16_t ps;
913 uint16_t cyc;
914};
915
916#define JS2_tSR 0
917#define JS2_tXP 1
918#define JS2_tRTP 2
919#define JS2_tRCD 3
920#define JS2_tRPpb 4
921#define JS2_tRPab 5
922#define JS2_tRAS 6
923#define JS2_tWR 7
924#define JS2_tWTR 8
925#define JS2_tRRD 9
926#define JS2_tPPD 10
927#define JS2_tFAW 11
928#define JS2_tDQSCK 12
929#define JS2_tCKEHCMD 13
930#define JS2_tCKELCMD 14
931#define JS2_tCKELPD 15
932#define JS2_tMRR 16
933#define JS2_tMRW 17
934#define JS2_tMRD 18
935#define JS2_tZQCALns 19
936#define JS2_tZQLAT 20
937#define JS2_tIEdly 21
938#define JS2_TBLCNT 22
939
940#define JS2_tRCpb (JS2_TBLCNT)
941#define JS2_tRCab (JS2_TBLCNT+1)
Marek Vasut6c245a52018-12-12 18:06:39 +0100942#define JS2_tRFCab (JS2_TBLCNT+2)
943#define JS2_CNT (JS2_TBLCNT+3)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200944
945#ifndef JS2_DERATE
946#define JS2_DERATE 0
947#endif
948const struct _jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = {
949 {
950/*tSR */ {15000, 3},
951/*tXP */ {7500, 3},
952/*tRTP */ {7500, 8},
953/*tRCD */ {18000, 4},
954/*tRPpb */ {18000, 3},
955/*tRPab */ {21000, 3},
956/*tRAS */ {42000, 3},
957/*tWR */ {18000, 4},
958/*tWTR */ {10000, 8},
959/*tRRD */ {10000, 4},
960/*tPPD */ {0, 0},
961/*tFAW */ {40000, 0},
962/*tDQSCK*/ {3500, 0},
963/*tCKEHCMD*/ {7500, 3},
964/*tCKELCMD*/ {7500, 3},
965/*tCKELPD*/ {7500, 3},
966/*tMRR*/ {0, 8},
967/*tMRW*/ {10000, 10},
968/*tMRD*/ {14000, 10},
969/*tZQCALns*/ {1000 * 10, 0},
970/*tZQLAT*/ {30000, 10},
971/*tIEdly*/ {12500, 0}
972 }, {
973/*tSR */ {15000, 3},
974/*tXP */ {7500, 3},
975/*tRTP */ {7500, 8},
976/*tRCD */ {19875, 4},
977/*tRPpb */ {19875, 3},
978/*tRPab */ {22875, 3},
979/*tRAS */ {43875, 3},
980/*tWR */ {18000, 4},
981/*tWTR */ {10000, 8},
982/*tRRD */ {11875, 4},
983/*tPPD */ {0, 0},
984/*tFAW */ {40000, 0},
985/*tDQSCK*/ {3600, 0},
986/*tCKEHCMD*/ {7500, 3},
987/*tCKELCMD*/ {7500, 3},
988/*tCKELPD*/ {7500, 3},
989/*tMRR*/ {0, 8},
990/*tMRW*/ {10000, 10},
991/*tMRD*/ {14000, 10},
992/*tZQCALns*/ {1000 * 10, 0},
993/*tZQLAT*/ {30000, 10},
994/*tIEdly*/ {12500, 0}
995 }
996};
997
Marek Vasut6c245a52018-12-12 18:06:39 +0100998const uint16_t jedec_spec2_tRFC_ab[7] = {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +0200999/* 4Gb, 6Gb, 8Gb,12Gb, 16Gb, 24Gb(non), 32Gb(non) */
Marek Vasut6c245a52018-12-12 18:06:39 +01001000 130, 180, 180, 280, 280, 560, 560
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001001};
1002
1003static uint32_t js1_ind;
1004static uint16_t js2[JS2_CNT];
1005static uint8_t RL;
1006static uint8_t WL;
1007
1008static uint16_t _f_scale(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv, uint32_t ps,
1009 uint16_t cyc)
1010{
1011 uint32_t tmp;
1012 uint32_t div;
1013
1014 tmp = (((uint32_t) (ps) + 9) / 10) * ddr_mbps;
1015 div = tmp / (200000 * ddr_mbpsdiv);
1016 if (tmp != (div * 200000 * ddr_mbpsdiv))
1017 div = div + 1;
1018
1019 if (div > cyc)
1020 return (uint16_t) div;
1021 return cyc;
1022}
1023
1024static void _f_scale_js2(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv,
1025 uint16_t * js2)
1026{
1027 int i;
1028
1029 for (i = 0; i < JS2_TBLCNT; i++) {
1030 js2[i] = _f_scale(ddr_mbps, ddr_mbpsdiv,
1031 1UL * jedec_spec2[JS2_DERATE][i].ps,
1032 jedec_spec2[JS2_DERATE][i].cyc);
1033 }
1034
1035 js2[JS2_tRCpb] = js2[JS2_tRAS] + js2[JS2_tRPpb];
1036 js2[JS2_tRCab] = js2[JS2_tRAS] + js2[JS2_tRPab];
1037}
1038
1039/* scaler for DELAY value */
1040static int16_t _f_scale_adj(int16_t ps)
1041{
1042 int32_t tmp;
1043 /*
1044 tmp = (int32_t)512 * ps * ddr_mbps /2 / ddr_mbpsdiv / 1000 / 1000;
1045 = ps * ddr_mbps /2 / ddr_mbpsdiv *512 / 8 / 8 / 125 / 125
1046 = ps * ddr_mbps / ddr_mbpsdiv *4 / 125 / 125
1047 */
1048 tmp =
1049 (int32_t) 4 *(int32_t) ps *(int32_t) ddr_mbps /
1050 (int32_t) ddr_mbpsdiv;
1051 tmp = (int32_t) tmp / (int32_t) 15625;
1052
1053 return (int16_t) tmp;
1054}
1055
1056const uint32_t _reg_PI_MR1_DATA_Fx_CSx[2][CSAB_CNT] = {
1057 {
1058 _reg_PI_MR1_DATA_F0_0,
1059 _reg_PI_MR1_DATA_F0_1,
1060 _reg_PI_MR1_DATA_F0_2,
1061 _reg_PI_MR1_DATA_F0_3},
1062 {
1063 _reg_PI_MR1_DATA_F1_0,
1064 _reg_PI_MR1_DATA_F1_1,
1065 _reg_PI_MR1_DATA_F1_2,
1066 _reg_PI_MR1_DATA_F1_3}
1067};
1068
1069const uint32_t _reg_PI_MR2_DATA_Fx_CSx[2][CSAB_CNT] = {
1070 {
1071 _reg_PI_MR2_DATA_F0_0,
1072 _reg_PI_MR2_DATA_F0_1,
1073 _reg_PI_MR2_DATA_F0_2,
1074 _reg_PI_MR2_DATA_F0_3},
1075 {
1076 _reg_PI_MR2_DATA_F1_0,
1077 _reg_PI_MR2_DATA_F1_1,
1078 _reg_PI_MR2_DATA_F1_2,
1079 _reg_PI_MR2_DATA_F1_3}
1080};
1081
1082const uint32_t _reg_PI_MR3_DATA_Fx_CSx[2][CSAB_CNT] = {
1083 {
1084 _reg_PI_MR3_DATA_F0_0,
1085 _reg_PI_MR3_DATA_F0_1,
1086 _reg_PI_MR3_DATA_F0_2,
1087 _reg_PI_MR3_DATA_F0_3},
1088 {
1089 _reg_PI_MR3_DATA_F1_0,
1090 _reg_PI_MR3_DATA_F1_1,
1091 _reg_PI_MR3_DATA_F1_2,
1092 _reg_PI_MR3_DATA_F1_3}
1093};
1094
1095const uint32_t _reg_PI_MR11_DATA_Fx_CSx[2][CSAB_CNT] = {
1096 {
1097 _reg_PI_MR11_DATA_F0_0,
1098 _reg_PI_MR11_DATA_F0_1,
1099 _reg_PI_MR11_DATA_F0_2,
1100 _reg_PI_MR11_DATA_F0_3},
1101 {
1102 _reg_PI_MR11_DATA_F1_0,
1103 _reg_PI_MR11_DATA_F1_1,
1104 _reg_PI_MR11_DATA_F1_2,
1105 _reg_PI_MR11_DATA_F1_3}
1106};
1107
1108const uint32_t _reg_PI_MR12_DATA_Fx_CSx[2][CSAB_CNT] = {
1109 {
1110 _reg_PI_MR12_DATA_F0_0,
1111 _reg_PI_MR12_DATA_F0_1,
1112 _reg_PI_MR12_DATA_F0_2,
1113 _reg_PI_MR12_DATA_F0_3},
1114 {
1115 _reg_PI_MR12_DATA_F1_0,
1116 _reg_PI_MR12_DATA_F1_1,
1117 _reg_PI_MR12_DATA_F1_2,
1118 _reg_PI_MR12_DATA_F1_3}
1119};
1120
1121const uint32_t _reg_PI_MR14_DATA_Fx_CSx[2][CSAB_CNT] = {
1122 {
1123 _reg_PI_MR14_DATA_F0_0,
1124 _reg_PI_MR14_DATA_F0_1,
1125 _reg_PI_MR14_DATA_F0_2,
1126 _reg_PI_MR14_DATA_F0_3},
1127 {
1128 _reg_PI_MR14_DATA_F1_0,
1129 _reg_PI_MR14_DATA_F1_1,
1130 _reg_PI_MR14_DATA_F1_2,
1131 _reg_PI_MR14_DATA_F1_3}
1132};
1133
1134/*******************************************************************************
1135 * regif pll w/a ( REGIF H3 Ver.2.0 or later/M3-N/V3H WA )
1136 *******************************************************************************/
1137static void regif_pll_wa(void)
1138{
1139 uint32_t ch;
1140
1141 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Chiaki Fujii61aa8032019-03-01 20:28:55 +09001142 // PLL setting for PHY : H3 Ver.1.x
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001143 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT),
1144 (0x0064U <<
1145 ddr_regdef_lsb(_reg_PHY_PLL_WAIT)));
1146 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL),
1147 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1148 _reg_PHY_PLL_CTRL));
1149
1150 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL),
1151 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1152 _reg_PHY_LP4_BOOT_PLL_CTRL));
1153
1154 } else {
1155 /* PLL setting for PHY : M3-W/M3-N/V3H/H3 Ver.2.0 or later */
1156 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT),
1157 (0x5064U <<
1158 ddr_regdef_lsb(_reg_PHY_PLL_WAIT)));
1159
1160 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL),
1161 (ddrtbl_getval
1162 (_cnf_DDR_PHY_ADR_G_REGSET,
1163 _reg_PHY_PLL_CTRL_TOP) << 16) |
1164 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1165 _reg_PHY_PLL_CTRL));
1166 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_CTRL_CA),
1167 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1168 _reg_PHY_PLL_CTRL_CA));
1169
1170 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LP4_BOOT_PLL_CTRL),
1171 (ddrtbl_getval
1172 (_cnf_DDR_PHY_ADR_G_REGSET,
1173 _reg_PHY_LP4_BOOT_PLL_CTRL_CA) << 16) |
1174 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1175 _reg_PHY_LP4_BOOT_PLL_CTRL));
1176 reg_ddrphy_write_a(ddr_regdef_adr
1177 (_reg_PHY_LP4_BOOT_TOP_PLL_CTRL),
1178 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
1179 _reg_PHY_LP4_BOOT_TOP_PLL_CTRL));
1180 }
1181
Chiaki Fujii61aa8032019-03-01 20:28:55 +09001182 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LPDDR3_CS),
1183 _cnf_DDR_PHY_ADR_G_REGSET[ddr_regdef_adr(_reg_PHY_LPDDR3_CS) - DDR_PHY_ADR_G_REGSET_OFS]);
1184
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001185 /* protect register interface */
1186 ddrphy_regif_idle();
1187 pll3_control(0);
1188
1189 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1190 /* non */
1191 } else {
1192 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_DLL_RST_EN),
1193 (0x01U <<
1194 ddr_regdef_lsb(_reg_PHY_DLL_RST_EN)));
1195 ddrphy_regif_idle();
1196 }
1197
1198 /***********************************************************************
1199 init start
1200 ***********************************************************************/
1201 /* dbdficnt0:
1202 * dfi_dram_clk_disable=1
1203 * dfi_frequency = 0
1204 * freq_ratio = 01 (2:1)
1205 * init_start =0
1206 */
1207 foreach_vch(ch)
1208 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10);
1209 dsb_sev();
1210
1211 /* dbdficnt0:
1212 * dfi_dram_clk_disable=1
1213 * dfi_frequency = 0
1214 * freq_ratio = 01 (2:1)
1215 * init_start =1
1216 */
1217 foreach_vch(ch)
1218 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11);
1219 dsb_sev();
1220
1221 foreach_ech(ch)
1222 if (((Boardcnf->phyvalid) & (1U << ch)))
1223 while ((mmio_read_32(DBSC_PLL_LOCK(ch)) & 0x1f) != 0x1f) ;
1224 dsb_sev();
1225}
1226
1227/*******************************************************************************
1228 * load table data into DDR registers
1229 ******************************************************************************/
1230static void ddrtbl_load(void)
1231{
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001232 uint32_t i;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001233 uint32_t slice;
1234 uint32_t csab;
1235 uint32_t adr;
1236 uint32_t dataL;
1237 uint32_t tmp[3];
1238 uint16_t dataS;
1239
1240 /***********************************************************************
1241 TIMING REGISTERS
1242 ***********************************************************************/
1243 /* search jedec_spec1 index */
1244 for (i = JS1_USABLEC_SPEC_LO; i < JS1_FREQ_TBL_NUM - 1; i++) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001245 if (js1[i].fx3 * 2U * ddr_mbpsdiv >= ddr_mbps * 3U)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001246 break;
1247 }
1248 if (JS1_USABLEC_SPEC_HI < i)
1249 js1_ind = JS1_USABLEC_SPEC_HI;
1250 else
1251 js1_ind = i;
1252
1253 if (Boardcnf->dbi_en)
1254 RL = js1[js1_ind].RLwDBI;
1255 else
1256 RL = js1[js1_ind].RLwoDBI;
1257
1258 WL = js1[js1_ind].WL;
1259
1260 /* calculate jedec_spec2 */
1261 _f_scale_js2(ddr_mbps, ddr_mbpsdiv, js2);
1262
1263 /***********************************************************************
1264 PREPARE TBL
1265 ***********************************************************************/
1266 if (Prr_Product == PRR_PRODUCT_H3) {
1267 if (Prr_Cut <= PRR_PRODUCT_11) {
1268 /* H3 Ver.1.x */
1269 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1270 DDR_PHY_SLICE_REGSET_H3,
1271 DDR_PHY_SLICE_REGSET_NUM_H3);
1272 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1273 DDR_PHY_ADR_V_REGSET_H3,
1274 DDR_PHY_ADR_V_REGSET_NUM_H3);
1275 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET,
1276 DDR_PHY_ADR_I_REGSET_H3,
1277 DDR_PHY_ADR_I_REGSET_NUM_H3);
1278 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1279 DDR_PHY_ADR_G_REGSET_H3,
1280 DDR_PHY_ADR_G_REGSET_NUM_H3);
1281 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_H3,
1282 DDR_PI_REGSET_NUM_H3);
1283
1284 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_H3;
1285 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_H3;
1286 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_H3;
1287 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_H3;
1288 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_H3;
1289 DDR_PHY_SLICE_REGSET_SIZE =
1290 DDR_PHY_SLICE_REGSET_SIZE_H3;
1291 DDR_PHY_ADR_V_REGSET_SIZE =
1292 DDR_PHY_ADR_V_REGSET_SIZE_H3;
1293 DDR_PHY_ADR_I_REGSET_SIZE =
1294 DDR_PHY_ADR_I_REGSET_SIZE_H3;
1295 DDR_PHY_ADR_G_REGSET_SIZE =
1296 DDR_PHY_ADR_G_REGSET_SIZE_H3;
1297 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_H3;
1298 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_H3;
1299 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_H3;
1300 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_H3;
1301 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_H3;
1302 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_H3;
1303
1304 DDR_PHY_ADR_I_NUM = 1;
1305 } else {
1306 /* H3 Ver.2.0 or later */
1307 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1308 DDR_PHY_SLICE_REGSET_H3VER2,
1309 DDR_PHY_SLICE_REGSET_NUM_H3VER2);
1310 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1311 DDR_PHY_ADR_V_REGSET_H3VER2,
1312 DDR_PHY_ADR_V_REGSET_NUM_H3VER2);
1313 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1314 DDR_PHY_ADR_G_REGSET_H3VER2,
1315 DDR_PHY_ADR_G_REGSET_NUM_H3VER2);
1316 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_H3VER2,
1317 DDR_PI_REGSET_NUM_H3VER2);
1318
1319 DDR_PHY_SLICE_REGSET_OFS =
1320 DDR_PHY_SLICE_REGSET_OFS_H3VER2;
1321 DDR_PHY_ADR_V_REGSET_OFS =
1322 DDR_PHY_ADR_V_REGSET_OFS_H3VER2;
1323 DDR_PHY_ADR_G_REGSET_OFS =
1324 DDR_PHY_ADR_G_REGSET_OFS_H3VER2;
1325 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_H3VER2;
1326 DDR_PHY_SLICE_REGSET_SIZE =
1327 DDR_PHY_SLICE_REGSET_SIZE_H3VER2;
1328 DDR_PHY_ADR_V_REGSET_SIZE =
1329 DDR_PHY_ADR_V_REGSET_SIZE_H3VER2;
1330 DDR_PHY_ADR_G_REGSET_SIZE =
1331 DDR_PHY_ADR_G_REGSET_SIZE_H3VER2;
1332 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_H3VER2;
1333 DDR_PHY_SLICE_REGSET_NUM =
1334 DDR_PHY_SLICE_REGSET_NUM_H3VER2;
1335 DDR_PHY_ADR_V_REGSET_NUM =
1336 DDR_PHY_ADR_V_REGSET_NUM_H3VER2;
1337 DDR_PHY_ADR_G_REGSET_NUM =
1338 DDR_PHY_ADR_G_REGSET_NUM_H3VER2;
1339 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_H3VER2;
1340
1341 DDR_PHY_ADR_I_NUM = 0;
1342 }
1343 } else if (Prr_Product == PRR_PRODUCT_M3) {
1344 /* M3-W */
1345 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1346 DDR_PHY_SLICE_REGSET_M3, DDR_PHY_SLICE_REGSET_NUM_M3);
1347 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET,
1348 DDR_PHY_ADR_V_REGSET_M3, DDR_PHY_ADR_V_REGSET_NUM_M3);
1349 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET,
1350 DDR_PHY_ADR_I_REGSET_M3, DDR_PHY_ADR_I_REGSET_NUM_M3);
1351 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET,
1352 DDR_PHY_ADR_G_REGSET_M3, DDR_PHY_ADR_G_REGSET_NUM_M3);
1353 _tblcopy(_cnf_DDR_PI_REGSET,
1354 DDR_PI_REGSET_M3, DDR_PI_REGSET_NUM_M3);
1355
1356 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_M3;
1357 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_M3;
1358 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_M3;
1359 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_M3;
1360 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_M3;
1361 DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_M3;
1362 DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_M3;
1363 DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_M3;
1364 DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_M3;
1365 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_M3;
1366 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_M3;
1367 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_M3;
1368 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_M3;
1369 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_M3;
1370 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_M3;
1371
1372 DDR_PHY_ADR_I_NUM = 2;
1373 } else {
1374 /* M3-N/V3H */
1375 _tblcopy(_cnf_DDR_PHY_SLICE_REGSET,
1376 DDR_PHY_SLICE_REGSET_M3N,
1377 DDR_PHY_SLICE_REGSET_NUM_M3N);
1378 _tblcopy(_cnf_DDR_PHY_ADR_V_REGSET, DDR_PHY_ADR_V_REGSET_M3N,
1379 DDR_PHY_ADR_V_REGSET_NUM_M3N);
1380 _tblcopy(_cnf_DDR_PHY_ADR_I_REGSET, DDR_PHY_ADR_I_REGSET_M3N,
1381 DDR_PHY_ADR_I_REGSET_NUM_M3N);
1382 _tblcopy(_cnf_DDR_PHY_ADR_G_REGSET, DDR_PHY_ADR_G_REGSET_M3N,
1383 DDR_PHY_ADR_G_REGSET_NUM_M3N);
1384 _tblcopy(_cnf_DDR_PI_REGSET, DDR_PI_REGSET_M3N,
1385 DDR_PI_REGSET_NUM_M3N);
1386
1387 DDR_PHY_SLICE_REGSET_OFS = DDR_PHY_SLICE_REGSET_OFS_M3N;
1388 DDR_PHY_ADR_V_REGSET_OFS = DDR_PHY_ADR_V_REGSET_OFS_M3N;
1389 DDR_PHY_ADR_I_REGSET_OFS = DDR_PHY_ADR_I_REGSET_OFS_M3N;
1390 DDR_PHY_ADR_G_REGSET_OFS = DDR_PHY_ADR_G_REGSET_OFS_M3N;
1391 DDR_PI_REGSET_OFS = DDR_PI_REGSET_OFS_M3N;
1392 DDR_PHY_SLICE_REGSET_SIZE = DDR_PHY_SLICE_REGSET_SIZE_M3N;
1393 DDR_PHY_ADR_V_REGSET_SIZE = DDR_PHY_ADR_V_REGSET_SIZE_M3N;
1394 DDR_PHY_ADR_I_REGSET_SIZE = DDR_PHY_ADR_I_REGSET_SIZE_M3N;
1395 DDR_PHY_ADR_G_REGSET_SIZE = DDR_PHY_ADR_G_REGSET_SIZE_M3N;
1396 DDR_PI_REGSET_SIZE = DDR_PI_REGSET_SIZE_M3N;
1397 DDR_PHY_SLICE_REGSET_NUM = DDR_PHY_SLICE_REGSET_NUM_M3N;
1398 DDR_PHY_ADR_V_REGSET_NUM = DDR_PHY_ADR_V_REGSET_NUM_M3N;
1399 DDR_PHY_ADR_I_REGSET_NUM = DDR_PHY_ADR_I_REGSET_NUM_M3N;
1400 DDR_PHY_ADR_G_REGSET_NUM = DDR_PHY_ADR_G_REGSET_NUM_M3N;
1401 DDR_PI_REGSET_NUM = DDR_PI_REGSET_NUM_M3N;
1402
1403 DDR_PHY_ADR_I_NUM = 2;
1404 }
1405
1406 /***********************************************************************
1407 PLL CODE CHANGE
1408 ***********************************************************************/
1409 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_11)) {
1410 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, _reg_PHY_PLL_CTRL,
1411 0x1142);
1412 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET,
1413 _reg_PHY_LP4_BOOT_PLL_CTRL, 0x1142);
1414 }
1415
1416 /***********************************************************************
1417 on fly gate adjust
1418 ***********************************************************************/
1419 if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut == PRR_PRODUCT_10)) {
1420 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1421 _reg_ON_FLY_GATE_ADJUST_EN, 0x00);
1422 }
1423
1424 /***********************************************************************
Marek Vasut6c245a52018-12-12 18:06:39 +01001425 Adjust PI parameters
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001426 ***********************************************************************/
1427#ifdef _def_LPDDR4_ODT
Marek Vasut6c245a52018-12-12 18:06:39 +01001428 for (i = 0; i < 2; i++) {
1429 for (csab = 0; csab < CSAB_CNT; csab++) {
1430 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1431 _reg_PI_MR11_DATA_Fx_CSx[i][csab],
1432 _def_LPDDR4_ODT);
1433 }
1434 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001435#endif /* _def_LPDDR4_ODT */
1436
1437#ifdef _def_LPDDR4_VREFCA
Marek Vasut6c245a52018-12-12 18:06:39 +01001438 for (i = 0; i < 2; i++) {
1439 for (csab = 0; csab < CSAB_CNT; csab++) {
1440 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1441 _reg_PI_MR12_DATA_Fx_CSx[i][csab],
1442 _def_LPDDR4_VREFCA);
1443 }
1444 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001445#endif /* _def_LPDDR4_VREFCA */
1446 if ((Prr_Product == PRR_PRODUCT_M3N)
1447 || (Prr_Product == PRR_PRODUCT_V3H)) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001448 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 7000, 0) + 7U;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001449 if (js2[JS2_tIEdly] > (RL))
1450 js2[JS2_tIEdly] = RL;
1451 } else if ((Prr_Product == PRR_PRODUCT_H3)
1452 && (Prr_Cut > PRR_PRODUCT_11)) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001453 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 9000, 0) + 4U;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001454 } else if ((Prr_Product == PRR_PRODUCT_H3)
1455 && (Prr_Cut <= PRR_PRODUCT_11)) {
1456 js2[JS2_tIEdly] = _f_scale(ddr_mbps, ddr_mbpsdiv, 10000, 0);
1457 }
1458
1459 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
1460 || (Prr_Product == PRR_PRODUCT_M3N)
1461 || (Prr_Product == PRR_PRODUCT_V3H)) {
1462 if ((js2[JS2_tIEdly]) >= 0x1e)
1463 dataS = 0x1e;
1464 else
1465 dataS = js2[JS2_tIEdly];
1466 } else {
1467 if ((js2[JS2_tIEdly]) >= 0x0e)
1468 dataS = 0x0e;
1469 else
1470 dataS = js2[JS2_tIEdly];
1471 }
1472
1473 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_DLY, dataS);
1474 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_RDDATA_EN_TSEL_DLY,
1475 (dataS - 2));
1476 if ((Prr_Product == PRR_PRODUCT_M3N)
1477 || (Prr_Product == PRR_PRODUCT_V3H)) {
1478 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1479 _reg_PHY_RDDATA_EN_OE_DLY, dataS);
1480 }
1481 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1, RL - dataS);
1482
1483 if (ddrtbl_getval
1484 (_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD)) {
1485 dataL = WL - 1;
1486 } else {
1487 dataL = WL;
1488 }
1489 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1, dataL - 2);
1490 ddrtbl_setval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1, dataL);
1491
1492 if (Boardcnf->dbi_en) {
1493 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE,
1494 0x01);
1495 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1496 _reg_PHY_WDQLVL_DATADM_MASK, 0x000);
1497 } else {
1498 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_DBI_MODE,
1499 0x00);
1500 ddrtbl_setval(_cnf_DDR_PHY_SLICE_REGSET,
1501 _reg_PHY_WDQLVL_DATADM_MASK, 0x100);
1502 }
1503
1504 tmp[0] = js1[js1_ind].MR1;
1505 tmp[1] = js1[js1_ind].MR2;
1506 dataL = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_MR3_DATA_F1_0);
1507 if (Boardcnf->dbi_en)
1508 tmp[2] = dataL | 0xc0;
1509 else
1510 tmp[2] = dataL & (~0xc0);
1511
1512 for (i = 0; i < 2; i++) {
1513 for (csab = 0; csab < CSAB_CNT; csab++) {
1514 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1515 _reg_PI_MR1_DATA_Fx_CSx[i][csab], tmp[0]);
1516 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1517 _reg_PI_MR2_DATA_Fx_CSx[i][csab], tmp[1]);
1518 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1519 _reg_PI_MR3_DATA_Fx_CSx[i][csab], tmp[2]);
1520 }
1521 }
1522
1523 /***********************************************************************
1524 DDRPHY INT START
1525 ***********************************************************************/
1526 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1527 /* non */
1528 } else {
1529 regif_pll_wa();
1530 }
1531
1532 /***********************************************************************
1533 FREQ_SEL_MULTICAST & PER_CS_TRAINING_MULTICAST SET (for safety)
1534 ***********************************************************************/
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001535 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN),
1536 (0x01U << ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN)));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001537 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x01);
1538
1539 /***********************************************************************
1540 SET DATA SLICE TABLE
1541 ***********************************************************************/
1542 for (slice = 0; slice < SLICE_CNT; slice++) {
1543 adr =
1544 DDR_PHY_SLICE_REGSET_OFS +
1545 DDR_PHY_SLICE_REGSET_SIZE * slice;
1546 for (i = 0; i < DDR_PHY_SLICE_REGSET_NUM; i++) {
1547 reg_ddrphy_write_a(adr + i,
1548 _cnf_DDR_PHY_SLICE_REGSET[i]);
1549 }
1550 }
1551
1552 /***********************************************************************
1553 SET ADR SLICE TABLE
1554 ***********************************************************************/
1555 adr = DDR_PHY_ADR_V_REGSET_OFS;
1556 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM; i++) {
1557 reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_V_REGSET[i]);
1558 }
1559
Marek Vasut6c245a52018-12-12 18:06:39 +01001560 if (((Prr_Product == PRR_PRODUCT_M3)
1561 || (Prr_Product == PRR_PRODUCT_M3N)) &&
1562 ((0x00ffffff & (uint32_t)((Boardcnf->ch[0].ca_swap) >> 40))
1563 != 0x00)) {
1564 adr = DDR_PHY_ADR_I_REGSET_OFS + DDR_PHY_ADR_I_REGSET_SIZE;
1565 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM; i++) {
1566 reg_ddrphy_write_a(adr + i,
1567 _cnf_DDR_PHY_ADR_V_REGSET[i]);
1568 }
1569 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET, _reg_PHY_ADR_DISABLE, 0x02);
1570 DDR_PHY_ADR_I_NUM -= 1;
1571 ddr_phycaslice = 1;
1572
1573#ifndef _def_LPDDR4_ODT
1574 for (i = 0; i < 2; i++) {
1575 for (csab = 0; csab < CSAB_CNT; csab++) {
1576 ddrtbl_setval(_cnf_DDR_PI_REGSET,
1577 _reg_PI_MR11_DATA_Fx_CSx[i][csab],
1578 0x66);
1579 }
1580 }
1581#endif/* _def_LPDDR4_ODT */
1582 } else {
1583 ddr_phycaslice = 0;
1584 }
1585
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001586 if (DDR_PHY_ADR_I_NUM > 0) {
1587 for (slice = 0; slice < DDR_PHY_ADR_I_NUM; slice++) {
1588 adr =
1589 DDR_PHY_ADR_I_REGSET_OFS +
1590 DDR_PHY_ADR_I_REGSET_SIZE * slice;
1591 for (i = 0; i < DDR_PHY_ADR_I_REGSET_NUM; i++) {
1592 reg_ddrphy_write_a(adr + i,
1593 _cnf_DDR_PHY_ADR_I_REGSET
1594 [i]);
1595 }
1596 }
1597 }
1598
1599 /***********************************************************************
1600 SET ADRCTRL SLICE TABLE
1601 ***********************************************************************/
1602 adr = DDR_PHY_ADR_G_REGSET_OFS;
1603 for (i = 0; i < DDR_PHY_ADR_G_REGSET_NUM; i++) {
1604 reg_ddrphy_write_a(adr + i, _cnf_DDR_PHY_ADR_G_REGSET[i]);
1605 }
1606
1607 /***********************************************************************
1608 SET PI REGISTERS
1609 ***********************************************************************/
1610 adr = DDR_PI_REGSET_OFS;
1611 for (i = 0; i < DDR_PI_REGSET_NUM; i++) {
1612 reg_ddrphy_write_a(adr + i, _cnf_DDR_PI_REGSET[i]);
1613 }
1614}
1615
1616/*******************************************************************************
1617 * CONFIGURE DDR REGISTERS
1618 ******************************************************************************/
1619static void ddr_config_sub(void)
1620{
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001621 uint32_t i;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001622 uint32_t ch, slice;
1623 uint32_t dataL;
1624 uint32_t tmp;
1625 uint8_t high_byte[SLICE_CNT];
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001626 const uint32_t _par_CALVL_DEVICE_MAP = 1;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001627 foreach_vch(ch) {
1628 /***********************************************************************
1629 BOARD SETTINGS (DQ,DM,VREF_DRIVING)
1630 ***********************************************************************/
1631 for (slice = 0; slice < SLICE_CNT; slice++) {
1632 high_byte[slice] =
1633 (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) % 2;
1634 ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE0,
1635 Boardcnf->ch[ch].dq_swap[slice]);
1636 ddr_setval_s(ch, slice, _reg_PHY_DQ_DM_SWIZZLE1,
1637 Boardcnf->ch[ch].dm_swap[slice]);
1638 if (high_byte[slice]) {
1639 /* HIGHER 16 BYTE */
1640 ddr_setval_s(ch, slice,
1641 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1642 0x00);
1643 } else {
1644 /* LOWER 16 BYTE */
1645 ddr_setval_s(ch, slice,
1646 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1647 0x01);
1648 }
1649 }
1650
1651 /***********************************************************************
1652 BOARD SETTINGS (CA,ADDR_SEL)
1653 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01001654 dataL = (0x00ffffff & (uint32_t)(Boardcnf->ch[ch].ca_swap)) |
1655 0x00888888;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001656
1657 /* --- ADR_CALVL_SWIZZLE --- */
1658 if (Prr_Product == PRR_PRODUCT_M3) {
1659 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, dataL);
1660 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0,
1661 0x00000000);
1662 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, dataL);
1663 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1,
1664 0x00000000);
1665 ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP,
1666 _par_CALVL_DEVICE_MAP);
1667 } else {
1668 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0, dataL);
1669 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1, 0x00000000);
1670 ddr_setval(ch, _reg_PHY_CALVL_DEVICE_MAP,
1671 _par_CALVL_DEVICE_MAP);
1672 }
1673
1674 /* --- ADR_ADDR_SEL --- */
1675 if ((Prr_Product == PRR_PRODUCT_H3)
1676 && (Prr_Cut > PRR_PRODUCT_11)) {
1677 dataL = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
1678 } else {
1679 dataL = 0;
1680 tmp = Boardcnf->ch[ch].ca_swap;
1681 for (i = 0; i < 6; i++) {
1682 dataL |= ((tmp & 0x0f) << (i * 5));
1683 tmp = tmp >> 4;
1684 }
1685 }
1686 ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, dataL);
Marek Vasut6c245a52018-12-12 18:06:39 +01001687 if (ddr_phycaslice == 1) {
1688 /* ----------- adr slice2 swap ----------- */
1689 tmp = (uint32_t)((Boardcnf->ch[ch].ca_swap) >> 40);
1690 dataL = (tmp & 0x00ffffff) | 0x00888888;
1691
1692 /* --- ADR_CALVL_SWIZZLE --- */
1693 if (Prr_Product == PRR_PRODUCT_M3) {
1694 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0_0, dataL);
1695 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1_0,
1696 0x00000000);
1697 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0_1, dataL);
1698 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1_1,
1699 0x00000000);
1700 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_DEVICE_MAP,
1701 _par_CALVL_DEVICE_MAP);
1702 } else {
1703 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE0, dataL);
1704 ddr_setval_s(ch, 2, _reg_PHY_ADR_CALVL_SWIZZLE1,
1705 0x00000000);
1706 ddr_setval_s(ch, 2, _reg_PHY_CALVL_DEVICE_MAP,
1707 _par_CALVL_DEVICE_MAP);
1708 }
1709
1710 /* --- ADR_ADDR_SEL --- */
1711 dataL = 0;
1712 for (i = 0; i < 6; i++) {
1713 dataL |= ((tmp & 0x0f) << (i * 5));
1714 tmp = tmp >> 4;
1715 }
1716
1717 ddr_setval_s(ch, 2, _reg_PHY_ADR_ADDR_SEL, dataL);
1718 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001719
1720 /***********************************************************************
1721 BOARD SETTINGS (BYTE_ORDER_SEL)
1722 ***********************************************************************/
1723 if (Prr_Product == PRR_PRODUCT_M3) {
1724 /* --- DATA_BYTE_SWAP --- */
1725 dataL = 0;
1726 tmp = Boardcnf->ch[ch].dqs_swap;
1727 for (i = 0; i < 4; i++) {
1728 dataL |= ((tmp & 0x03) << (i * 2));
1729 tmp = tmp >> 4;
1730 }
1731 } else {
1732 /* --- DATA_BYTE_SWAP --- */
1733 dataL = Boardcnf->ch[ch].dqs_swap;
1734 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_EN, 0x01);
1735 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE0,
1736 (dataL) & 0x0f);
1737 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE1,
1738 (dataL >> 4 * 1) & 0x0f);
1739 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE2,
1740 (dataL >> 4 * 2) & 0x0f);
1741 ddr_setval(ch, _reg_PI_DATA_BYTE_SWAP_SLICE3,
1742 (dataL >> 4 * 3) & 0x0f);
1743
1744 ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL_HIGH, 0x00);
1745 }
1746 ddr_setval(ch, _reg_PHY_DATA_BYTE_ORDER_SEL, dataL);
1747 }
1748}
1749
1750static void get_ca_swizzle(uint32_t ch, uint32_t ddr_csn, uint32_t * p_swz)
1751{
1752 uint32_t slice;
1753 uint32_t tmp;
1754 uint32_t tgt;
1755 if (ddr_csn / 2) {
1756 tgt = 3;
1757 } else {
1758 tgt = 1;
1759 }
1760
1761 for (slice = 0; slice < SLICE_CNT; slice++) {
1762 tmp = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
1763 if (tgt == tmp)
1764 break;
1765 }
Marek Vasut6c245a52018-12-12 18:06:39 +01001766 tmp = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001767 if (slice % 2)
1768 tmp |= 0x00888888;
1769 *p_swz = tmp;
1770}
1771
1772static void ddr_config_sub_h3v1x(void)
1773{
1774 uint32_t ch, slice;
1775 uint32_t dataL;
1776 uint32_t tmp;
1777 uint8_t high_byte[SLICE_CNT];
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001778 uint32_t ca_swizzle;
1779 uint32_t ca;
1780 uint32_t csmap;
1781 uint32_t o_inv;
1782 uint32_t inv;
1783 uint32_t bit_soc;
1784 uint32_t bit_mem;
1785 uint32_t j;
1786
1787 const uint8_t o_mr15 = 0x55;
1788 const uint8_t o_mr20 = 0x55;
1789 const uint16_t o_mr32_mr40 = 0x5a3c;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001790
1791 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001792 /***********************************************************************
1793 BOARD SETTINGS (DQ,DM,VREF_DRIVING)
1794 ***********************************************************************/
1795 csmap = 0;
1796 for (slice = 0; slice < SLICE_CNT; slice++) {
1797 tmp = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
1798 high_byte[slice] = tmp % 2;
1799 if (tmp == 1 && (slice >= 2))
1800 csmap |= 0x05;
1801 if (tmp == 3 && (slice >= 2))
1802 csmap |= 0x50;
1803 ddr_setval_s(ch, slice, _reg_PHY_DQ_SWIZZLING,
1804 Boardcnf->ch[ch].dq_swap[slice]);
1805 if (high_byte[slice]) {
1806 /* HIGHER 16 BYTE */
1807 ddr_setval_s(ch, slice,
1808 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1809 0x00);
1810 } else {
1811 /* LOWER 16 BYTE */
1812 ddr_setval_s(ch, slice,
1813 _reg_PHY_CALVL_VREF_DRIVING_SLICE,
1814 0x01);
1815 }
1816 }
1817 /***********************************************************************
1818 BOARD SETTINGS (CA,ADDR_SEL)
1819 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01001820 ca = 0x00FFFFFF & Boardcnf->ch[ch].ca_swap;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001821 ddr_setval(ch, _reg_PHY_ADR_ADDR_SEL, ca);
1822 ddr_setval(ch, _reg_PHY_CALVL_CS_MAP, csmap);
1823
1824 get_ca_swizzle(ch, 0, &ca_swizzle);
1825
1826 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_0, ca_swizzle);
1827 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_0, 0x00000000);
1828 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE0_1, 0x00000000);
1829 ddr_setval(ch, _reg_PHY_ADR_CALVL_SWIZZLE1_1, 0x00000000);
1830 ddr_setval(ch, _reg_PHY_ADR_CALVL_DEVICE_MAP, 0x01);
1831
1832 for (slice = 0; slice < SLICE_CNT; slice++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001833 ddr_setval_s(ch, slice, _reg_PI_RDLVL_PATTERN_NUM,
1834 0x01);
1835 ddr_setval_s(ch, slice, _reg_PI_RDLVL_PATTERN_START,
1836 0x08);
1837
1838 if (high_byte[slice])
1839 o_inv = o_mr20;
1840 else
1841 o_inv = o_mr15;
1842
1843 tmp = Boardcnf->ch[ch].dq_swap[slice];
1844 inv = 0;
1845 j = 0;
1846 for (bit_soc = 0; bit_soc < 8; bit_soc++) {
1847 bit_mem = (tmp >> (4 * bit_soc)) & 0x0f;
1848 j |= (1U << bit_mem);
1849 if (o_inv & (1U << bit_mem))
1850 inv |= (1U << bit_soc);
1851 }
1852 dataL = o_mr32_mr40;
1853 if (!high_byte[slice])
1854 dataL |= (inv << 24);
1855 if (high_byte[slice])
1856 dataL |= (inv << 16);
1857 ddr_setval_s(ch, slice, _reg_PHY_LP4_RDLVL_PATT8,
1858 dataL);
1859 }
1860 }
1861}
1862
1863static void ddr_config(void)
1864{
1865 int32_t i;
1866 uint32_t ch, slice;
1867 uint32_t dataL;
1868 uint32_t tmp;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001869 int8_t _adj;
1870 int16_t adj;
1871 uint32_t dq;
1872 union {
1873 uint32_t ui32[4];
1874 uint8_t ui8[16];
1875 } patt;
1876 uint16_t patm;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001877
1878 /***********************************************************************
1879 configure ddrphy registers
1880 ***********************************************************************/
1881 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
1882 ddr_config_sub_h3v1x();
1883 } else {
1884 ddr_config_sub(); /* H3 Ver.2.0 or later/M3-N/V3H is same as M3-W */
1885 }
1886
1887 /***********************************************************************
1888 WDQ_USER_PATT
1889 ***********************************************************************/
1890 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001891 for (slice = 0; slice < SLICE_CNT; slice++) {
1892 patm = 0;
1893 for (i = 0; i < 16; i++) {
1894 tmp = Boardcnf->ch[ch].wdqlvl_patt[i];
1895 patt.ui8[i] = tmp & 0xff;
1896 if (tmp & 0x100)
1897 patm |= (1U << i);
1898 }
1899 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT0,
1900 patt.ui32[0]);
1901 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT1,
1902 patt.ui32[1]);
1903 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT2,
1904 patt.ui32[2]);
1905 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT3,
1906 patt.ui32[3]);
1907 ddr_setval_s(ch, slice, _reg_PHY_USER_PATT4, patm);
1908 }
1909 }
1910
1911 /***********************************************************************
1912 CACS DLY
1913 ***********************************************************************/
1914 dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001915 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN), 0x00U);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001916 foreach_vch(ch) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001917 for (i = 0; i < (_reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM - 4); i++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001918 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001919 ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET,
1920 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
1921 dataL + adj);
1922 reg_ddrphy_write(ch,
1923 ddr_regdef_adr(
1924 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]),
1925 _cnf_DDR_PHY_ADR_V_REGSET[
1926 ddr_regdef_adr(
1927 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]) -
1928 DDR_PHY_ADR_V_REGSET_OFS]);
1929 }
1930
1931 for (i = (_reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM - 4);
1932 i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
1933 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
1934 ddrtbl_setval(_cnf_DDR_PHY_ADR_G_REGSET,
1935 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
1936 dataL + adj);
1937 reg_ddrphy_write(ch,
1938 ddr_regdef_adr(
1939 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]),
1940 _cnf_DDR_PHY_ADR_G_REGSET[
1941 ddr_regdef_adr(
1942 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]) -
1943 DDR_PHY_ADR_G_REGSET_OFS]);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001944 }
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001945
Marek Vasut6c245a52018-12-12 18:06:39 +01001946 if (ddr_phycaslice == 1) {
1947 for (i = 0; i < 6; i++) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001948 adj = _f_scale_adj(
1949 Boardcnf->ch[ch].cacs_adj[
1950 i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM]);
1951 ddrtbl_setval(_cnf_DDR_PHY_ADR_V_REGSET,
1952 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
1953 dataL + adj);
1954 reg_ddrphy_write(ch,
1955 ddr_regdef_adr(
1956 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]) +
1957 0x0100,
1958 _cnf_DDR_PHY_ADR_V_REGSET[
1959 ddr_regdef_adr(
1960 _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i]) -
1961 DDR_PHY_ADR_V_REGSET_OFS]);
Marek Vasut6c245a52018-12-12 18:06:39 +01001962 }
1963 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001964 }
Chiaki Fujii61aa8032019-03-01 20:28:55 +09001965
Chiaki Fujii59263ee2019-05-17 10:45:02 +09001966 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN),
1967 (0x01U << ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN)));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001968
1969 /***********************************************************************
1970 WDQDM DLY
1971 ***********************************************************************/
1972 dataL = Boardcnf->dqdm_dly_w;
1973 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001974 for (slice = 0; slice < SLICE_CNT; slice++) {
1975 for (i = 0; i <= 8; i++) {
1976 dq = slice * 8 + i;
1977 if (i == 8)
1978 _adj = Boardcnf->ch[ch].dm_adj_w[slice];
1979 else
1980 _adj = Boardcnf->ch[ch].dq_adj_w[dq];
1981 adj = _f_scale_adj(_adj);
1982 ddr_setval_s(ch, slice,
1983 _reg_PHY_CLK_WRX_SLAVE_DELAY[i],
1984 dataL + adj);
1985 }
1986 }
1987 }
1988
1989 /***********************************************************************
1990 RDQDM DLY
1991 ***********************************************************************/
1992 dataL = Boardcnf->dqdm_dly_r;
1993 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02001994 for (slice = 0; slice < SLICE_CNT; slice++) {
1995 for (i = 0; i <= 8; i++) {
1996 dq = slice * 8 + i;
1997 if (i == 8)
1998 _adj = Boardcnf->ch[ch].dm_adj_r[slice];
1999 else
2000 _adj = Boardcnf->ch[ch].dq_adj_r[dq];
2001 adj = _f_scale_adj(_adj);
2002 ddr_setval_s(ch, slice,
2003 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY
2004 [i], dataL + adj);
2005 ddr_setval_s(ch, slice,
2006 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY
2007 [i], dataL + adj);
2008 }
2009 }
2010 }
2011}
2012
2013/*******************************************************************************
2014 * DBSC register setting functions
2015 ******************************************************************************/
2016static void dbsc_regset_pre(void)
2017{
2018 uint32_t ch, csab;
2019 uint32_t dataL;
2020
2021 /***********************************************************************
2022 PRIMARY SETTINGS
2023 ***********************************************************************/
2024 /* LPDDR4, BL=16, DFI interface */
2025 mmio_write_32(DBSC_DBKIND, 0x0000000a);
2026 mmio_write_32(DBSC_DBBL, 0x00000002);
2027 mmio_write_32(DBSC_DBPHYCONF0, 0x00000001);
2028
2029 /* FREQRATIO=2 */
2030 mmio_write_32(DBSC_DBSYSCONF1, 0x00000002);
2031
2032 /* Chanel map (H3 Ver.1.x) */
2033 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
2034 mmio_write_32(DBSC_DBSCHCNT1, 0x00001010);
2035
2036 /* DRAM SIZE REGISTER:
2037 * set all ranks as density=0(4Gb) for PHY initialization
2038 */
2039 foreach_vch(ch)
2040 for (csab = 0; csab < 4; csab++)
2041 mmio_write_32(DBSC_DBMEMCONF(ch, csab), DBMEMCONF_REGD(0));
2042
2043 if (Prr_Product == PRR_PRODUCT_M3) {
2044 dataL = 0xe4e4e4e4;
2045 foreach_ech(ch) {
2046 if ((ddr_phyvalid & (1U << ch)))
2047 dataL = (dataL & (~(0x000000FF << (ch * 8))))
2048 | (((Boardcnf->ch[ch].dqs_swap & 0x0003)
2049 | ((Boardcnf->ch[ch].dqs_swap & 0x0030)
2050 >> 2)
2051 | ((Boardcnf->ch[ch].dqs_swap & 0x0300)
2052 >> 4)
2053 | ((Boardcnf->ch[ch].dqs_swap & 0x3000)
2054 >> 6)) << (ch * 8));
2055 }
2056 mmio_write_32(DBSC_DBBSWAP, dataL);
2057 }
2058}
2059
2060static void dbsc_regset(void)
2061{
2062 int32_t i;
2063 uint32_t ch;
2064 uint32_t dataL;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002065 uint32_t dataL2;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002066 uint32_t tmp[4];
2067
2068 /* RFC */
2069 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_20)
2070 && (max_density == 0)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002071 js2[JS2_tRFCab] =
2072 _f_scale(ddr_mbps, ddr_mbpsdiv,
Marek Vasut6c245a52018-12-12 18:06:39 +01002073 1UL * jedec_spec2_tRFC_ab[1] * 1000, 0);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002074 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002075 js2[JS2_tRFCab] =
2076 _f_scale(ddr_mbps, ddr_mbpsdiv,
Marek Vasut6c245a52018-12-12 18:06:39 +01002077 1UL * jedec_spec2_tRFC_ab[max_density] *
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002078 1000, 0);
2079 }
2080
2081 /* DBTR0.CL : RL */
2082 mmio_write_32(DBSC_DBTR(0), RL);
2083
2084 /* DBTR1.CWL : WL */
2085 mmio_write_32(DBSC_DBTR(1), WL);
2086
2087 /* DBTR2.AL : 0 */
2088 mmio_write_32(DBSC_DBTR(2), 0);
2089
2090 /* DBTR3.TRCD: tRCD */
2091 mmio_write_32(DBSC_DBTR(3), js2[JS2_tRCD]);
2092
2093 /* DBTR4.TRPA,TRP: tRPab,tRPpb */
2094 mmio_write_32(DBSC_DBTR(4), (js2[JS2_tRPab] << 16) | js2[JS2_tRPpb]);
2095
2096 /* DBTR5.TRC : use tRCpb */
2097 mmio_write_32(DBSC_DBTR(5), js2[JS2_tRCpb]);
2098
2099 /* DBTR6.TRAS : tRAS */
2100 mmio_write_32(DBSC_DBTR(6), js2[JS2_tRAS]);
2101
2102 /* DBTR7.TRRD : tRRD */
2103 mmio_write_32(DBSC_DBTR(7), (js2[JS2_tRRD] << 16) | js2[JS2_tRRD]);
2104
2105 /* DBTR8.TFAW : tFAW */
2106 mmio_write_32(DBSC_DBTR(8), js2[JS2_tFAW]);
2107
2108 /* DBTR9.TRDPR : tRTP */
2109 mmio_write_32(DBSC_DBTR(9), js2[JS2_tRTP]);
2110
2111 /* DBTR10.TWR : nWR */
2112 mmio_write_32(DBSC_DBTR(10), js1[js1_ind].nWR);
2113
2114 /* DBTR11.TRDWR : RL + tDQSCK + BL/2 + Rounddown(tRPST) - WL + tWPRE */
2115 mmio_write_32(DBSC_DBTR(11),
2116 RL + js2[JS2_tDQSCK] + (16 / 2) + 1 - WL + 2 + 2);
2117
2118 /* DBTR12.TWRRD : WL + 1 + BL/2 + tWTR */
2119 dataL = WL + 1 + (16 / 2) + js2[JS2_tWTR];
2120 mmio_write_32(DBSC_DBTR(12), (dataL << 16) | dataL);
2121
Marek Vasut6c245a52018-12-12 18:06:39 +01002122 /* DBTR13.TRFCAB : tRFCab */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002123 mmio_write_32(DBSC_DBTR(13), (js2[JS2_tRFCab]));
2124
2125 /* DBTR14.TCKEHDLL,tCKEH : tCKEHCMD,tCKEHCMD */
2126 mmio_write_32(DBSC_DBTR(14),
2127 (js2[JS2_tCKEHCMD] << 16) | (js2[JS2_tCKEHCMD]));
2128
2129 /* DBTR15.TCKESR,TCKEL : tSR,tCKELPD */
2130 mmio_write_32(DBSC_DBTR(15), (js2[JS2_tSR] << 16) | (js2[JS2_tCKELPD]));
2131
2132 /* DBTR16 */
2133 /* WDQL : tphy_wrlat + tphy_wrdata */
2134 tmp[0] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_F1);
Marek Vasut3af20052019-02-25 14:57:08 +01002135 /* DQENLTNCY : tphy_wrlat = WL-2 : PHY_WRITE_PATH_LAT_ADD == 0
2136 * tphy_wrlat = WL-3 : PHY_WRITE_PATH_LAT_ADD != 0
2137 */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002138 tmp[1] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_WRLAT_ADJ_F1);
2139 /* DQL : tphy_rdlat + trdata_en */
2140 /* it is not important for dbsc */
2141 tmp[2] = RL + 16;
2142 /* DQIENLTNCY : trdata_en */
2143 tmp[3] = ddrtbl_getval(_cnf_DDR_PI_REGSET, _reg_PI_RDLAT_ADJ_F1) - 1;
2144 mmio_write_32(DBSC_DBTR(16),
2145 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2146
2147 /* DBTR24 */
2148 /* WRCSLAT = WRLAT -5 */
2149 tmp[0] -= 5;
2150 /* WRCSGAP = 5 */
2151 tmp[1] = 5;
2152 /* RDCSLAT = RDLAT_ADJ +2 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002153 if (Prr_Product == PRR_PRODUCT_M3) {
2154 tmp[2] = tmp[3];
2155 } else {
2156 tmp[2] = tmp[3] + 2;
2157 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002158 /* RDCSGAP = 6 */
2159 if (Prr_Product == PRR_PRODUCT_M3) {
2160 tmp[3] = 4;
2161 } else {
2162 tmp[3] = 6;
2163 }
2164 mmio_write_32(DBSC_DBTR(24),
2165 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2166
2167 /* DBTR17.TMODRD,TMOD,TRDMR: tMRR,tMRD,(0) */
2168 mmio_write_32(DBSC_DBTR(17),
2169 (js2[JS2_tMRR] << 24) | (js2[JS2_tMRD] << 16));
2170
2171 /* DBTR18.RODTL, RODTA, WODTL, WODTA : do not use in LPDDR4 */
2172 mmio_write_32(DBSC_DBTR(18), 0);
2173
2174 /* DBTR19.TZQCL, TZQCS : do not use in LPDDR4 */
2175 mmio_write_32(DBSC_DBTR(19), 0);
2176
2177 /* DBTR20.TXSDLL, TXS : tRFCab+tCKEHCMD */
2178 dataL = js2[JS2_tRFCab] + js2[JS2_tCKEHCMD];
2179 mmio_write_32(DBSC_DBTR(20), (dataL << 16) | dataL);
2180
2181 /* DBTR21.TCCD */
2182 /* DBTR23.TCCD */
2183 /* H3 Ver.1.0 cannot use TBTR23 feature */
2184 if (ddr_tccd == 8 &&
2185 !((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_10))
2186 ) {
2187 dataL = 8;
2188 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2189 mmio_write_32(DBSC_DBTR(23), 0x00000002);
2190 } else if (ddr_tccd <= 11) {
2191 dataL = 11;
2192 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2193 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2194 } else {
2195 dataL = ddr_tccd;
2196 mmio_write_32(DBSC_DBTR(21), (dataL << 16) | dataL);
2197 mmio_write_32(DBSC_DBTR(23), 0x00000000);
2198 }
2199
2200 /* DBTR22.ZQLAT : */
2201 dataL = js2[JS2_tZQCALns] * 100; /* 1000 * 1000 ps */
2202 dataL = (dataL << 16) | (js2[JS2_tZQLAT] + 24 + 20);
2203 mmio_write_32(DBSC_DBTR(22), dataL);
2204
2205 /* DBTR25 : do not use in LPDDR4 */
2206 mmio_write_32(DBSC_DBTR(25), 0);
2207
2208 /* DBRNK : */
2209 /*
2210 * DBSC_DBRNK2 rkrr
2211 * DBSC_DBRNK3 rkrw
2212 * DBSC_DBRNK4 rkwr
2213 * DBSC_DBRNK5 rkww
2214 */
2215#define _par_DBRNK_VAL (0x7007)
2216
2217 for (i = 0; i < 4; i++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002218 dataL = (_par_DBRNK_VAL >> (i * 4)) & 0x0f;
2219 if ((Prr_Product == PRR_PRODUCT_H3)
2220 && (Prr_Cut > PRR_PRODUCT_11) && (i == 0)) {
2221 dataL += 1;
2222 }
2223 dataL2 = 0;
2224 foreach_vch(ch) {
2225 dataL2 = dataL2 | (dataL << (4 * ch));
2226 }
2227 mmio_write_32(DBSC_DBRNK(2 + i), dataL2);
2228 }
2229 mmio_write_32(DBSC_DBADJ0, 0x00000000);
2230
2231 /***********************************************************************
2232 timing registers for Scheduler
2233 ***********************************************************************/
2234 /* SCFCTST0 */
2235 /* SCFCTST0 ACT-ACT */
2236 tmp[3] = 1UL * js2[JS2_tRCpb] * 800 * ddr_mbpsdiv / ddr_mbps;
2237 /* SCFCTST0 RDA-ACT */
2238 tmp[2] =
2239 1UL * ((16 / 2) + js2[JS2_tRTP] - 8 +
2240 js2[JS2_tRPpb]) * 800 * ddr_mbpsdiv / ddr_mbps;
2241 /* SCFCTST0 WRA-ACT */
2242 tmp[1] =
2243 1UL * (WL + 1 + (16 / 2) +
2244 js1[js1_ind].nWR) * 800 * ddr_mbpsdiv / ddr_mbps;
2245 /* SCFCTST0 PRE-ACT */
2246 tmp[0] = 1UL * js2[JS2_tRPpb];
2247 mmio_write_32(DBSC_SCFCTST0,
2248 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2249
2250 /* SCFCTST1 */
2251 /* SCFCTST1 RD-WR */
2252 tmp[3] =
2253 1UL * (mmio_read_32(DBSC_DBTR(11)) & 0xff) * 800 * ddr_mbpsdiv /
2254 ddr_mbps;
2255 /* SCFCTST1 WR-RD */
2256 tmp[2] =
2257 1UL * (mmio_read_32(DBSC_DBTR(12)) & 0xff) * 800 * ddr_mbpsdiv /
2258 ddr_mbps;
2259 /* SCFCTST1 ACT-RD/WR */
2260 tmp[1] = 1UL * js2[JS2_tRCD] * 800 * ddr_mbpsdiv / ddr_mbps;
2261 /* SCFCTST1 ASYNCOFS */
2262 tmp[0] = 12;
2263 mmio_write_32(DBSC_SCFCTST1,
2264 (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2265
2266 /* DBSCHRW1 */
2267 /* DBSCHRW1 SCTRFCAB */
2268 tmp[0] = 1UL * js2[JS2_tRFCab] * 800 * ddr_mbpsdiv / ddr_mbps;
2269 dataL = (((mmio_read_32(DBSC_DBTR(16)) & 0x00FF0000) >> 16)
2270 + (mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
2271 + (0x28 * 2)) * 400 * 2 * ddr_mbpsdiv / ddr_mbps + 7;
2272 if (tmp[0] < dataL)
2273 tmp[0] = dataL;
Chiaki Fujii61aa8032019-03-01 20:28:55 +09002274
2275 if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30)) {
2276 mmio_write_32(DBSC_DBSCHRW1, tmp[0]
2277 + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
2278 * 400 * 2 * ddr_mbpsdiv +(ddr_mbps-1))/ddr_mbps - 3);
2279 } else {
2280 mmio_write_32(DBSC_DBSCHRW1, tmp[0]
2281 + ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
2282 * 400 * 2 * ddr_mbpsdiv +(ddr_mbps-1))/ddr_mbps);
2283 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002284
2285 /***********************************************************************
2286 QOS and CAM
2287 ***********************************************************************/
2288#ifdef ddr_qos_init_setting /* only for non qos_init */
2289 /*wbkwait(0004), wbkmdhi(4,2),wbkmdlo(1,8) */
2290 mmio_write_32(DBSC_DBCAM0CNF1, 0x00043218);
2291 /*0(fillunit),8(dirtymax),4(dirtymin) */
2292 mmio_write_32(DBSC_DBCAM0CNF2, 0x000000F4);
2293 /*stop_tolerance */
2294 mmio_write_32(DBSC_DBSCHRW0, 0x22421111);
2295 /*rd-wr/wr-rd toggle priority */
2296 mmio_write_32(DBSC_SCFCTST2, 0x012F1123);
2297 mmio_write_32(DBSC_DBSCHSZ0, 0x00000001);
2298 mmio_write_32(DBSC_DBSCHCNT0, 0x000F0037);
2299
2300 /* QoS Settings */
2301 mmio_write_32(DBSC_DBSCHQOS00, 0x00000F00U);
2302 mmio_write_32(DBSC_DBSCHQOS01, 0x00000B00U);
2303 mmio_write_32(DBSC_DBSCHQOS02, 0x00000000U);
2304 mmio_write_32(DBSC_DBSCHQOS03, 0x00000000U);
2305 mmio_write_32(DBSC_DBSCHQOS40, 0x00000300U);
2306 mmio_write_32(DBSC_DBSCHQOS41, 0x000002F0U);
2307 mmio_write_32(DBSC_DBSCHQOS42, 0x00000200U);
2308 mmio_write_32(DBSC_DBSCHQOS43, 0x00000100U);
2309 mmio_write_32(DBSC_DBSCHQOS90, 0x00000100U);
2310 mmio_write_32(DBSC_DBSCHQOS91, 0x000000F0U);
2311 mmio_write_32(DBSC_DBSCHQOS92, 0x000000A0U);
2312 mmio_write_32(DBSC_DBSCHQOS93, 0x00000040U);
2313 mmio_write_32(DBSC_DBSCHQOS120, 0x00000040U);
2314 mmio_write_32(DBSC_DBSCHQOS121, 0x00000030U);
2315 mmio_write_32(DBSC_DBSCHQOS122, 0x00000020U);
2316 mmio_write_32(DBSC_DBSCHQOS123, 0x00000010U);
2317 mmio_write_32(DBSC_DBSCHQOS130, 0x00000100U);
2318 mmio_write_32(DBSC_DBSCHQOS131, 0x000000F0U);
2319 mmio_write_32(DBSC_DBSCHQOS132, 0x000000A0U);
2320 mmio_write_32(DBSC_DBSCHQOS133, 0x00000040U);
2321 mmio_write_32(DBSC_DBSCHQOS140, 0x000000C0U);
2322 mmio_write_32(DBSC_DBSCHQOS141, 0x000000B0U);
2323 mmio_write_32(DBSC_DBSCHQOS142, 0x00000080U);
2324 mmio_write_32(DBSC_DBSCHQOS143, 0x00000040U);
2325 mmio_write_32(DBSC_DBSCHQOS150, 0x00000040U);
2326 mmio_write_32(DBSC_DBSCHQOS151, 0x00000030U);
2327 mmio_write_32(DBSC_DBSCHQOS152, 0x00000020U);
2328 mmio_write_32(DBSC_DBSCHQOS153, 0x00000010U);
2329
2330 mmio_write_32(QOSCTRL_RAEN, 0x00000001U);
2331#endif /* ddr_qos_init_setting */
2332 /* H3 Ver.1.1 need to set monitor function */
2333 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut == PRR_PRODUCT_11)) {
2334 mmio_write_32(DBSC_DBMONCONF4, 0x00700000);
2335 }
2336
2337 if (Prr_Product == PRR_PRODUCT_H3) {
2338 if (Prr_Cut == PRR_PRODUCT_10) {
2339 /* resrdis, simple mode, sc off */
2340 mmio_write_32(DBSC_DBBCAMDIS, 0x00000007);
2341 } else if (Prr_Cut == PRR_PRODUCT_11) {
2342 /* resrdis, simple mode */
2343 mmio_write_32(DBSC_DBBCAMDIS, 0x00000005);
2344 } else if (Prr_Cut < PRR_PRODUCT_30) {
2345 /* H3 Ver.2.0 */
2346 /* resrdis */
2347 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2348 } else { /* H3 Ver.3.0(include H3N) */
2349 /* exprespque */
2350 mmio_write_32(DBSC_DBBCAMDIS, 0x00000010);
2351 }
2352 } else { /* M3-W/M3-N/V3H */
2353 /* resrdis */
2354 mmio_write_32(DBSC_DBBCAMDIS, 0x00000001);
2355 }
2356}
2357
2358static void dbsc_regset_post(void)
2359{
2360 uint32_t ch, cs;
2361 uint32_t dataL;
2362 uint32_t slice, rdlat_max, rdlat_min;
2363
2364 rdlat_max = 0;
2365 rdlat_min = 0xffff;
2366 foreach_vch(ch) {
2367 for (cs = 0; cs < CS_CNT; cs++) {
2368 if ((ch_have_this_cs[cs] & (1U << ch)) != 0) {
2369 for (slice = 0; slice < SLICE_CNT; slice++) {
2370 ddr_setval_s(ch, slice,
2371 _reg_PHY_PER_CS_TRAINING_INDEX,
2372 cs);
2373 dataL =
2374 ddr_getval_s(ch, slice,
2375 _reg_PHY_RDDQS_LATENCY_ADJUST);
2376 if (dataL > rdlat_max)
2377 rdlat_max = dataL;
2378 if (dataL < rdlat_min)
2379 rdlat_min = dataL;
2380 }
2381 }
2382 }
2383 }
2384 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11)) {
2385 mmio_write_32(DBSC_DBTR(24),
2386 ((rdlat_max * 2 - rdlat_min + 4) << 24) +
2387 ((rdlat_min + 2) << 16) +
2388 mmio_read_32(DBSC_DBTR(24)));
2389 } else {
2390 mmio_write_32(DBSC_DBTR(24),
2391 ((rdlat_max + 2) << 24) +
2392 ((rdlat_max + 2) << 16) +
2393 mmio_read_32(DBSC_DBTR(24)));
2394 }
2395
2396 /* set ddr density information */
2397 foreach_ech(ch) {
2398 for (cs = 0; cs < CS_CNT; cs++) {
2399 if (ddr_density[ch][cs] == 0xff) {
2400 mmio_write_32(DBSC_DBMEMCONF(ch, cs), 0x00);
2401 } else {
2402 mmio_write_32(DBSC_DBMEMCONF(ch, cs),
2403 DBMEMCONF_REGD(ddr_density[ch]
2404 [cs]));
2405 }
2406 }
2407 mmio_write_32(DBSC_DBMEMCONF(ch, 2), 0x00000000);
2408 mmio_write_32(DBSC_DBMEMCONF(ch, 3), 0x00000000);
2409 }
2410
2411 mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010);
2412
2413 /*set DBI */
2414 if (Boardcnf->dbi_en)
2415 mmio_write_32(DBSC_DBDBICNT, 0x00000003);
2416
2417 /* H3 Ver.2.0 or later/M3-N/V3H DBI wa */
2418 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
2419 || (Prr_Product == PRR_PRODUCT_M3N)
2420 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
2421 reg_ddrphy_write_a(0x00001010, 0x01000000);
2422
2423 /*set REFCYCLE */
2424 dataL = (get_refperiod()) * ddr_mbps / 2000 / ddr_mbpsdiv;
2425 mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (dataL & 0x0000ffff));
2426 mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS);
Chiaki Fujii61aa8032019-03-01 20:28:55 +09002427
2428#ifdef DDR_BACKUPMODE
2429 if (ddrBackup == DRAM_BOOT_STATUS_WARM) {
2430#ifdef DDR_BACKUPMODE_HALF /* for Half channel(ch0,1 only) */
2431 PutStr(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
2432 send_dbcmd(0x08040001);
2433 wait_dbcmd();
2434 send_dbcmd(0x0A040001);
2435 wait_dbcmd();
2436 send_dbcmd(0x04040010);
2437 wait_dbcmd();
2438
2439 if (Prr_Product == PRR_PRODUCT_H3) {
2440 send_dbcmd(0x08140001);
2441 wait_dbcmd();
2442 send_dbcmd(0x0A140001);
2443 wait_dbcmd();
2444 send_dbcmd(0x04140010);
2445 wait_dbcmd();
2446 }
2447#else /* DDR_BACKUPMODE_HALF //for All channels */
2448 send_dbcmd(0x08840001);
2449 wait_dbcmd();
2450 send_dbcmd(0x0A840001);
2451 wait_dbcmd();
2452
2453 send_dbcmd(0x04840010);
2454 wait_dbcmd();
2455#endif /* DDR_BACKUPMODE_HALF */
2456 }
2457#endif /* DDR_BACKUPMODE */
2458
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002459#if RCAR_REWT_TRAINING != 0
2460 /* Periodic-WriteDQ Training seeting */
2461 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
2462 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut == PRR_PRODUCT_10))) {
2463 /* non : H3 Ver.1.x/M3-W Ver.1.0 not support */
2464 } else {
2465 /* H3 Ver.2.0 or later/M3-W Ver.1.1 or later/M3-N/V3H -> Periodic-WriteDQ Training seeting */
2466
2467 /* Periodic WriteDQ Training seeting */
2468 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000000);
2469
2470 ddr_setval_ach_as(_reg_PHY_WDQLVL_PATT, 0x04);
2471 ddr_setval_ach_as(_reg_PHY_WDQLVL_QTR_DLY_STEP, 0x0F);
2472 ddr_setval_ach_as(_reg_PHY_WDQLVL_DLY_STEP, 0x50);
2473 ddr_setval_ach_as(_reg_PHY_WDQLVL_DQDM_SLV_DLY_START, 0x0300);
2474
2475 ddr_setval_ach(_reg_PI_WDQLVL_CS_MAP,
2476 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2477 _reg_PI_WDQLVL_CS_MAP));
2478 ddr_setval_ach(_reg_PI_LONG_COUNT_MASK, 0x1f);
2479 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
2480 ddr_setval_ach(_reg_PI_WDQLVL_INTERVAL, 0x0100);
2481 ddr_setval_ach(_reg_PI_WDQLVL_ROTATE, 0x01);
2482 ddr_setval_ach(_reg_PI_TREF_F0, 0x0000);
2483 ddr_setval_ach(_reg_PI_TREF_F1, 0x0000);
2484 ddr_setval_ach(_reg_PI_TREF_F2, 0x0000);
2485
2486 if (Prr_Product == PRR_PRODUCT_M3) {
2487 ddr_setval_ach(_reg_PI_WDQLVL_EN, 0x02);
2488 } else {
2489 ddr_setval_ach(_reg_PI_WDQLVL_EN_F1, 0x02);
2490 }
2491 ddr_setval_ach(_reg_PI_WDQLVL_PERIODIC, 0x01);
2492
2493 /* DFI_PHYMSTR_ACK , WTmode setting */
2494 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000011); /* DFI_PHYMSTR_ACK: WTmode =b'01 */
2495 }
2496#endif /* RCAR_REWT_TRAINING */
2497 /* periodic dram zqcal and phy ctrl update enable */
2498 mmio_write_32(DBSC_DBCALCNF, 0x01000010);
2499 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01002500 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002501 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
2502 } else {
2503#if RCAR_DRAM_SPLIT == 2
2504 if ((Prr_Product == PRR_PRODUCT_H3)
2505 && (Boardcnf->phyvalid == 0x05))
2506 mmio_write_32(DBSC_DBDFICUPDCNF, 0x2a240001);
2507 else
2508 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2509#else /* RCAR_DRAM_SPLIT == 2 */
2510 mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
2511#endif /* RCAR_DRAM_SPLIT == 2 */
2512 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002513
2514 mmio_write_32(DBSC_DBRFEN, 0x00000001);
2515 /* dram access enable */
2516 mmio_write_32(DBSC_DBACEN, 0x00000001);
2517
2518 MSG_LF("dbsc_regset_post(done)");
2519
2520}
2521
2522/*******************************************************************************
2523 * DFI_INIT_START
2524 ******************************************************************************/
2525static uint32_t dfi_init_start(void)
2526{
2527 uint32_t ch;
2528 uint32_t phytrainingok;
2529 uint32_t retry;
2530 uint32_t dataL;
2531 const uint32_t RETRY_MAX = 0x10000;
2532
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002533 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002534 /***********************************************************************
2535 PLL3 Disable
2536 ***********************************************************************/
2537 /* protect register interface */
2538 ddrphy_regif_idle();
2539
2540 pll3_control(0);
2541
2542 /***********************************************************************
2543 init start
2544 ***********************************************************************/
2545 /* dbdficnt0:
2546 * dfi_dram_clk_disable=1
2547 * dfi_frequency = 0
2548 * freq_ratio = 01 (2:1)
2549 * init_start =0
2550 */
2551 foreach_vch(ch)
2552 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F10);
2553 dsb_sev();
2554
2555 /* dbdficnt0:
2556 * dfi_dram_clk_disable=1
2557 * dfi_frequency = 0
2558 * freq_ratio = 01 (2:1)
2559 * init_start =1
2560 */
2561 foreach_vch(ch)
2562 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000F11);
2563 dsb_sev();
2564
2565 } else {
2566 ddr_setval_ach_as(_reg_PHY_DLL_RST_EN, 0x02);
2567 dsb_sev();
2568 ddrphy_regif_idle();
2569 }
2570
2571 /* dll_rst negate */
2572 foreach_vch(ch)
2573 mmio_write_32(DBSC_DBPDCNT3(ch), 0x0000CF01);
2574 dsb_sev();
2575
2576 /***********************************************************************
2577 wait init_complete
2578 ***********************************************************************/
2579 phytrainingok = 0;
2580 retry = 0;
2581 while (retry++ < RETRY_MAX) {
2582 foreach_vch(ch) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002583 dataL = mmio_read_32(DBSC_DBDFISTAT(ch));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002584 if (dataL & 0x00000001)
2585 phytrainingok |= (1U << ch);
2586 }
2587 dsb_sev();
2588 if (phytrainingok == ddr_phyvalid)
2589 break;
2590 if (retry % 256 == 0)
2591 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
2592 }
2593
2594 /***********************************************************************
2595 all ch ok?
2596 ***********************************************************************/
2597 if ((phytrainingok & ddr_phyvalid) != ddr_phyvalid) {
2598 return (0xff);
2599 }
2600 /* dbdficnt0:
2601 * dfi_dram_clk_disable=0
2602 * dfi_frequency = 0
2603 * freq_ratio = 01 (2:1)
2604 * init_start =0
2605 */
2606 foreach_vch(ch)
2607 mmio_write_32(DBSC_DBDFICNT(ch), 0x00000010);
2608 dsb_sev();
2609
2610 return 0;
2611}
2612
2613/*******************************************************************************
2614 * drivablity setting : CMOS MODE ON/OFF
2615 ******************************************************************************/
2616static void change_lpddr4_en(uint32_t mode)
2617{
2618 uint32_t ch;
2619 uint32_t i;
2620 uint32_t dataL;
2621 const uint32_t _reg_PHY_PAD_DRIVE_X[3] = {
2622 _reg_PHY_PAD_ADDR_DRIVE,
2623 _reg_PHY_PAD_CLK_DRIVE,
2624 _reg_PHY_PAD_CS_DRIVE
2625 };
2626
Marek Vasut6c245a52018-12-12 18:06:39 +01002627 foreach_vch(ch) {
2628 for (i = 0; i < 3; i++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002629 dataL = ddr_getval(ch, _reg_PHY_PAD_DRIVE_X[i]);
2630 if (mode) {
2631 dataL |= (1U << 14);
2632 } else {
2633 dataL &= ~(1U << 14);
2634 }
2635 ddr_setval(ch, _reg_PHY_PAD_DRIVE_X[i], dataL);
2636 }
2637 }
2638}
2639
2640/*******************************************************************************
2641 * drivablity setting
2642 ******************************************************************************/
2643static uint32_t set_term_code(void)
2644{
2645 int32_t i;
2646 uint32_t ch, index;
2647 uint32_t dataL;
2648 uint32_t chip_id[2];
2649 uint32_t term_code;
2650 uint32_t override;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002651 uint32_t pvtr;
2652 uint32_t pvtp;
2653 uint32_t pvtn;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002654 term_code = ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2655 _reg_PHY_PAD_DATA_TERM);
2656 override = 0;
2657 for (i = 0; i < 2; i++)
2658 chip_id[i] = mmio_read_32(LIFEC_CHIPID(i));
2659
2660 index = 0;
2661 while (1) {
2662 if (TermcodeBySample[index][0] == 0xffffffff) {
2663 break;
2664 }
2665 if ((TermcodeBySample[index][0] == chip_id[0])
2666 && (TermcodeBySample[index][1] == chip_id[1])) {
2667 term_code = TermcodeBySample[index][2];
2668 override = 1;
2669 break;
2670 }
2671 index++;
2672 }
2673
2674 if (override) {
2675 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM; index++) {
2676 dataL =
2677 ddrtbl_getval(_cnf_DDR_PHY_ADR_G_REGSET,
2678 _reg_PHY_PAD_TERM_X[index]);
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002679 dataL = (dataL & 0xfffe0000) | term_code;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002680 ddr_setval_ach(_reg_PHY_PAD_TERM_X[index], dataL);
2681 }
2682 } else if ((Prr_Product == PRR_PRODUCT_M3)
2683 && (Prr_Cut == PRR_PRODUCT_10)) {
2684 /* non */
2685 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002686 ddr_setval_ach(_reg_PHY_PAD_TERM_X[0],
2687 (ddrtbl_getval
2688 (_cnf_DDR_PHY_ADR_G_REGSET,
2689 _reg_PHY_PAD_TERM_X[0]) & 0xFFFE0000));
2690 ddr_setval_ach(_reg_PHY_CAL_CLEAR_0, 0x01);
2691 ddr_setval_ach(_reg_PHY_CAL_START_0, 0x01);
2692 foreach_vch(ch) {
2693 do {
2694 dataL =
2695 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2696 } while (!(dataL & 0x00800000));
2697 }
2698 if ((Prr_Product == PRR_PRODUCT_H3)
2699 && (Prr_Cut <= PRR_PRODUCT_11)) {
2700 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002701 dataL = ddr_getval(ch, _reg_PHY_PAD_TERM_X[0]);
2702 pvtr = (dataL >> 12) & 0x1f;
2703 pvtr += 8;
2704 if (pvtr > 0x1f)
2705 pvtr = 0x1f;
2706 dataL =
2707 ddr_getval(ch, _reg_PHY_CAL_RESULT2_OBS_0);
2708 pvtn = (dataL >> 6) & 0x03f;
2709 pvtp = (dataL >> 0) & 0x03f;
2710
2711 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2712 index++) {
2713 dataL =
2714 ddrtbl_getval
2715 (_cnf_DDR_PHY_ADR_G_REGSET,
2716 _reg_PHY_PAD_TERM_X[index]);
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002717 dataL = (dataL & 0xfffe0000)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002718 | (pvtr << 12)
2719 | (pvtn << 6)
2720 | (pvtp);
2721 ddr_setval(ch,
2722 _reg_PHY_PAD_TERM_X[index],
2723 dataL);
2724 }
2725 }
2726 } else { /* M3-W Ver.1.1 or later/H3 Ver.2.0 or later/M3-N/V3H */
2727 foreach_vch(ch) {
2728 for (index = 0; index < _reg_PHY_PAD_TERM_X_NUM;
2729 index++) {
2730 dataL =
2731 ddr_getval(ch,
2732 _reg_PHY_PAD_TERM_X
2733 [index]);
2734 ddr_setval(ch,
2735 _reg_PHY_PAD_TERM_X[index],
2736 (dataL & 0xFFFE0FFF) |
2737 0x00015000);
2738 }
2739 }
2740 }
2741 }
2742 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2743 /* non */
2744 } else {
2745 ddr_padcal_tcompensate_getinit(override);
2746 }
2747 return 0;
2748}
2749
2750/*******************************************************************************
2751 * DDR mode register setting
2752 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01002753static void ddr_register_set(void)
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002754{
2755 int32_t fspwp;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002756 uint32_t tmp;
2757
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002758 for (fspwp = 1; fspwp >= 0; fspwp--) {
2759 /*MR13,fspwp */
Marek Vasut6c245a52018-12-12 18:06:39 +01002760 send_dbcmd(0x0e840d08 | (fspwp << 6));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002761
2762 tmp =
2763 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2764 _reg_PI_MR1_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002765 send_dbcmd(0x0e840100 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002766
2767 tmp =
2768 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2769 _reg_PI_MR2_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002770 send_dbcmd(0x0e840200 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002771
2772 tmp =
2773 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2774 _reg_PI_MR3_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002775 send_dbcmd(0x0e840300 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002776
2777 tmp =
2778 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2779 _reg_PI_MR11_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002780 send_dbcmd(0x0e840b00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002781
2782 tmp =
2783 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2784 _reg_PI_MR12_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002785 send_dbcmd(0x0e840c00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002786
2787 tmp =
2788 ddrtbl_getval(_cnf_DDR_PI_REGSET,
2789 _reg_PI_MR14_DATA_Fx_CSx[fspwp][0]);
Marek Vasut6c245a52018-12-12 18:06:39 +01002790 send_dbcmd(0x0e840e00 | tmp);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002791 /* MR22 */
Marek Vasut6c245a52018-12-12 18:06:39 +01002792 send_dbcmd(0x0e841616);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002793 }
2794}
2795
2796/*******************************************************************************
2797 * Training handshake functions
2798 ******************************************************************************/
2799static inline uint32_t wait_freqchgreq(uint32_t assert)
2800{
2801 uint32_t dataL;
2802 uint32_t count;
2803 uint32_t ch;
2804 count = 100000;
2805
2806 /* H3 Ver.1.x cannot see frqchg_req */
2807 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2808 return 0;
2809 }
2810
2811 if (assert) {
2812 do {
2813 dataL = 1;
2814 foreach_vch(ch) {
2815 dataL &= mmio_read_32(DBSC_DBPDSTAT(ch));
2816 }
2817 count = count - 1;
2818 } while (((dataL & 0x01) != 0x01) & (count != 0));
2819 } else {
2820 do {
2821 dataL = 0;
2822 foreach_vch(ch) {
2823 dataL |= mmio_read_32(DBSC_DBPDSTAT(ch));
2824 }
2825 count = count - 1;
2826 } while (((dataL & 0x01) != 0x00) & (count != 0));
2827 }
2828
2829 return (count == 0);
2830}
2831
2832static inline void set_freqchgack(uint32_t assert)
2833{
2834 uint32_t ch;
2835 uint32_t dataL;
2836 if (assert)
2837 dataL = 0x0CF20000;
2838 else
2839 dataL = 0x00000000;
2840
2841 foreach_vch(ch)
2842 mmio_write_32(DBSC_DBPDCNT2(ch), dataL);
2843}
2844
2845static inline void set_dfifrequency(uint32_t freq)
2846{
2847 uint32_t ch;
2848 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
2849 foreach_vch(ch)
2850 mmio_clrsetbits_32(DBSC_DBPDCNT1(ch), 0x1fU, freq);
2851 } else {
2852 foreach_vch(ch) {
2853 mmio_clrsetbits_32(DBSC_DBDFICNT(ch), 0x1fU << 24,
2854 (freq << 24));
2855 }
2856 }
2857 dsb_sev();
2858}
2859
2860static uint32_t pll3_freq(uint32_t on)
2861{
2862 uint32_t timeout;
2863
2864 timeout = wait_freqchgreq(1);
2865
2866 if (timeout) {
2867 return (1);
2868 }
2869
2870 pll3_control(on);
2871 set_dfifrequency(on);
2872
2873 set_freqchgack(1);
2874 timeout = wait_freqchgreq(0);
2875 set_freqchgack(0);
2876
2877 if (timeout) {
Marek Vasut56519892019-01-21 23:11:33 +01002878 FATAL_MSG("BL2: Time out[2]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002879 return (1);
2880 }
2881 return (0);
2882}
2883
2884/*******************************************************************************
2885 * update dly
2886 ******************************************************************************/
2887static void update_dly(void)
2888{
2889 ddr_setval_ach(_reg_SC_PHY_MANUAL_UPDATE, 0x01);
2890 ddr_setval_ach(_reg_PHY_ADRCTL_MANUAL_UPDATE, 0x01);
2891}
2892
2893/*******************************************************************************
2894 * training by pi
2895 ******************************************************************************/
2896static uint32_t pi_training_go(void)
2897{
2898 uint32_t flag;
2899 uint32_t dataL;
2900 uint32_t retry;
2901 const uint32_t RETRY_MAX = 4096 * 16;
2902 uint32_t ch;
2903
2904 uint32_t mst_ch;
2905 uint32_t cur_frq;
2906 uint32_t complete;
2907 uint32_t frqchg_req;
2908
2909 /* ********************************************************************* */
2910
2911 /***********************************************************************
2912 pi_start
2913 ***********************************************************************/
2914 ddr_setval_ach(_reg_PI_START, 0x01);
2915 foreach_vch(ch)
2916 ddr_getval(ch, _reg_PI_INT_STATUS);
2917
2918 /* set dfi_phymstr_ack = 1 */
2919 mmio_write_32(DBSC_DBDFIPMSTRCNF, 0x00000001);
2920 dsb_sev();
2921
2922 /***********************************************************************
2923 wait pi_int_status[0]
2924 ***********************************************************************/
2925 mst_ch = 0;
2926 flag = 0;
2927 complete = 0;
2928 cur_frq = 0;
2929 retry = RETRY_MAX;
2930 do {
2931 frqchg_req = mmio_read_32(DBSC_DBPDSTAT(mst_ch)) & 0x01;
2932
2933 /* H3 Ver.1.x cannot see frqchg_req */
2934 if ((Prr_Product == PRR_PRODUCT_H3)
2935 && (Prr_Cut <= PRR_PRODUCT_11)) {
2936 if ((retry % 4096) == 1) {
2937 frqchg_req = 1;
2938 } else {
2939 frqchg_req = 0;
2940 }
2941 }
2942
2943 if (frqchg_req) {
2944 if (cur_frq) {
2945 /* Low frequency */
2946 flag = pll3_freq(0);
2947 cur_frq = 0;
2948 } else {
2949 /* High frequency */
2950 flag = pll3_freq(1);
2951 cur_frq = 1;
2952 }
2953 if (flag)
2954 break;
2955 } else {
2956 if (cur_frq) {
2957 foreach_vch(ch) {
2958 if (complete & (1U << ch))
2959 continue;
2960 dataL =
2961 ddr_getval(ch, _reg_PI_INT_STATUS);
2962 if (dataL & 0x01) {
2963 complete |= (1U << ch);
2964 }
2965 }
2966 if (complete == ddr_phyvalid)
2967 break;
2968 }
2969 }
2970 } while (--retry);
2971 foreach_vch(ch) {
2972 /* dummy read */
2973 dataL = ddr_getval_s(ch, 0, _reg_PHY_CAL_RESULT2_OBS_0);
2974 dataL = ddr_getval(ch, _reg_PI_INT_STATUS);
2975 ddr_setval(ch, _reg_PI_INT_ACK, dataL);
2976 }
2977 if (ddrphy_regif_chk()) {
2978 return (0xfd);
2979 }
2980 return complete;
2981}
2982
2983/*******************************************************************************
2984 * Initialize ddr
2985 ******************************************************************************/
2986static uint32_t init_ddr(void)
2987{
2988 int32_t i;
2989 uint32_t dataL;
2990 uint32_t phytrainingok;
Marek Vasut6c245a52018-12-12 18:06:39 +01002991 uint32_t ch, slice;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002992 uint32_t err;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09002993 int16_t adj;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02002994
2995 MSG_LF("init_ddr:0\n");
2996
2997#ifdef DDR_BACKUPMODE
2998 rcar_dram_get_boot_status(&ddrBackup);
2999#endif
3000
3001 /***********************************************************************
3002 unlock phy
3003 ***********************************************************************/
3004 /* Unlock DDRPHY register(AGAIN) */
3005 foreach_vch(ch)
3006 mmio_write_32(DBSC_DBPDLK(ch), 0x0000A55A);
3007 dsb_sev();
3008
3009 if ((((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3010 || (Prr_Product == PRR_PRODUCT_M3N)
3011 || (Prr_Product == PRR_PRODUCT_V3H)) && (Boardcnf->dbi_en))
3012 reg_ddrphy_write_a(0x00001010, 0x01000001);
3013 else
3014 reg_ddrphy_write_a(0x00001010, 0x00000001);
3015 /***********************************************************************
3016 dbsc register pre-setting
3017 ***********************************************************************/
3018 dbsc_regset_pre();
3019
3020 /***********************************************************************
3021 load ddrphy registers
3022 ***********************************************************************/
3023
3024 ddrtbl_load();
3025
3026 /***********************************************************************
3027 configure ddrphy registers
3028 ***********************************************************************/
3029 ddr_config();
3030
3031 /***********************************************************************
3032 dfi_reset assert
3033 ***********************************************************************/
3034 foreach_vch(ch)
3035 mmio_write_32(DBSC_DBPDCNT0(ch), 0x01);
3036 dsb_sev();
3037
3038 /***********************************************************************
3039 dbsc register set
3040 ***********************************************************************/
3041 dbsc_regset();
3042 MSG_LF("init_ddr:1\n");
3043
3044 /***********************************************************************
3045 dfi_reset negate
3046 ***********************************************************************/
3047 foreach_vch(ch)
3048 mmio_write_32(DBSC_DBPDCNT0(ch), 0x00);
3049 dsb_sev();
3050
3051 /***********************************************************************
3052 dfi_init_start (start ddrphy)
3053 ***********************************************************************/
3054 err = dfi_init_start();
3055 if (err) {
3056 return INITDRAM_ERR_I;
3057 }
3058 MSG_LF("init_ddr:2\n");
3059
3060 /***********************************************************************
3061 ddr backupmode end
3062 ***********************************************************************/
3063#ifdef DDR_BACKUPMODE
3064 if (ddrBackup) {
Marek Vasut56519892019-01-21 23:11:33 +01003065 NOTICE("BL2: [WARM_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003066 } else {
Marek Vasut56519892019-01-21 23:11:33 +01003067 NOTICE("BL2: [COLD_BOOT]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003068 }
3069 err = rcar_dram_update_boot_status(ddrBackup);
3070 if (err) {
Marek Vasut56519892019-01-21 23:11:33 +01003071 NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003072 return INITDRAM_ERR_I;
3073 }
3074#endif
3075 MSG_LF("init_ddr:3\n");
3076
3077 /***********************************************************************
3078 override term code after dfi_init_complete
3079 ***********************************************************************/
3080 err = set_term_code();
3081 if (err) {
3082 return INITDRAM_ERR_I;
3083 }
3084 MSG_LF("init_ddr:4\n");
3085
3086 /***********************************************************************
3087 rx offset calibration
3088 ***********************************************************************/
3089 if ((Prr_Cut > PRR_PRODUCT_11) || (Prr_Product == PRR_PRODUCT_M3N)
3090 || (Prr_Product == PRR_PRODUCT_V3H)) {
3091 err = rx_offset_cal_hw();
3092 } else {
3093 err = rx_offset_cal();
3094 }
3095 if (err)
3096 return (INITDRAM_ERR_O);
3097 MSG_LF("init_ddr:5\n");
3098
Marek Vasut6c245a52018-12-12 18:06:39 +01003099 /* PDX */
3100 send_dbcmd(0x08840001);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003101
3102 /***********************************************************************
3103 check register i/f is alive
3104 ***********************************************************************/
3105 err = ddrphy_regif_chk();
3106 if (err) {
3107 return (INITDRAM_ERR_O);
3108 }
3109 MSG_LF("init_ddr:6\n");
3110
3111 /***********************************************************************
3112 phy initialize end
3113 ***********************************************************************/
3114
3115 /***********************************************************************
3116 setup DDR mode registers
3117 ***********************************************************************/
3118 /* CMOS MODE */
3119 change_lpddr4_en(0);
3120
Marek Vasut6c245a52018-12-12 18:06:39 +01003121 /* MRS */
3122 ddr_register_set();
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003123
3124 /* ZQCAL start */
Marek Vasut6c245a52018-12-12 18:06:39 +01003125 send_dbcmd(0x0d84004F);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003126
3127 /* ZQLAT */
Marek Vasut6c245a52018-12-12 18:06:39 +01003128 send_dbcmd(0x0d840051);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003129
3130 /***********************************************************************
3131 Thermal sensor setting
3132 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003133 /* THCTR Bit6: PONM=0 , Bit0: THSST=1 */
3134 dataL = (mmio_read_32(THS1_THCTR) & 0xFFFFFFBF) | 0x00000001;
3135 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003136
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003137 /* LPDDR4 MODE */
3138 change_lpddr4_en(1);
3139
3140 MSG_LF("init_ddr:7\n");
3141
3142 /***********************************************************************
3143 mask CS_MAP if RANKx is not found
3144 ***********************************************************************/
3145 foreach_vch(ch) {
3146 dataL = ddr_getval(ch, _reg_PI_CS_MAP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003147 if (!(ch_have_this_cs[1] & (1U << ch)))
3148 dataL = dataL & 0x05;
3149 ddr_setval(ch, _reg_PI_CS_MAP, dataL);
3150 }
3151
3152 /***********************************************************************
3153 exec pi_training
3154 ***********************************************************************/
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003155 reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_FREQ_SEL_MULTICAST_EN),
3156 BIT(ddr_regdef_lsb(_reg_PHY_FREQ_SEL_MULTICAST_EN)));
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003157 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00);
Marek Vasut6c245a52018-12-12 18:06:39 +01003158
3159 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003160 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003161 } else {
3162 foreach_vch(ch) {
3163 for (slice = 0; slice < SLICE_CNT; slice++) {
3164 ddr_setval_s(ch, slice,
3165 _reg_PHY_PER_CS_TRAINING_EN,
3166 ((ch_have_this_cs[1]) >> ch)
3167 & 0x01);
3168 }
3169 }
3170 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003171
3172 phytrainingok = pi_training_go();
3173
3174 if (ddr_phyvalid != (phytrainingok & ddr_phyvalid)) {
3175 return (INITDRAM_ERR_T | phytrainingok);
3176 }
3177
3178 MSG_LF("init_ddr:8\n");
3179
3180 /***********************************************************************
3181 CACS DLY ADJUST
3182 ***********************************************************************/
3183 dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
3184 foreach_vch(ch) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003185 for (i = 0; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
3186 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i]);
3187 ddr_setval(ch, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3188 dataL + adj);
3189 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003190
3191 if (ddr_phycaslice == 1) {
3192 for (i = 0; i < 6; i++) {
3193 adj = _f_scale_adj(Boardcnf->ch[ch].cacs_adj[i + _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM]);
3194 ddr_setval_s(ch, 2, _reg_PHY_CLK_CACS_SLAVE_DELAY_X[i],
3195 dataL + adj
3196 );
3197 }
3198 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003199 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003200
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003201 update_dly();
3202 MSG_LF("init_ddr:9\n");
3203
3204 /***********************************************************************
3205 H3 fix rd latency to avoid bug in elasitic buffe
3206 ***********************************************************************/
3207 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3208 adjust_rddqs_latency();
3209 }
3210
3211 /***********************************************************************
3212 Adjust Write path latency
3213 ***********************************************************************/
3214 if (ddrtbl_getval
3215 (_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_WRITE_PATH_LAT_ADD))
3216 adjust_wpath_latency();
3217
3218 /***********************************************************************
3219 RDQLVL Training
3220 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003221 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003222 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x01);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003223 }
3224
3225 err = rdqdm_man();
Marek Vasut6c245a52018-12-12 18:06:39 +01003226
3227 if (ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET, _reg_PHY_IE_MODE) == 0x00) {
3228 ddr_setval_ach_as(_reg_PHY_IE_MODE, 0x00);
3229 }
3230
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003231 if (err) {
3232 return (INITDRAM_ERR_T);
3233 }
3234 update_dly();
3235 MSG_LF("init_ddr:10\n");
3236
3237 /***********************************************************************
3238 WDQLVL Training
3239 ***********************************************************************/
3240 err = wdqdm_man();
3241 if (err) {
3242 return (INITDRAM_ERR_T);
3243 }
3244 update_dly();
3245 MSG_LF("init_ddr:11\n");
3246
3247 /***********************************************************************
3248 training complete, setup dbsc
3249 ***********************************************************************/
3250 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3251 || (Prr_Product == PRR_PRODUCT_M3N)
3252 || (Prr_Product == PRR_PRODUCT_V3H)) {
3253 ddr_setval_ach_as(_reg_PHY_DFI40_POLARITY, 0x00);
3254 ddr_setval_ach(_reg_PI_DFI40_POLARITY, 0x00);
3255 }
3256
3257 dbsc_regset_post();
3258 MSG_LF("init_ddr:12\n");
3259
3260 return phytrainingok;
3261}
3262
3263/*******************************************************************************
3264 * SW LEVELING COMMON
3265 ******************************************************************************/
3266static uint32_t swlvl1(uint32_t ddr_csn, uint32_t reg_cs, uint32_t reg_kick)
3267{
3268 uint32_t ch;
3269 uint32_t dataL;
3270 uint32_t retry;
3271 uint32_t waiting;
3272 uint32_t err;
3273
3274 const uint32_t RETRY_MAX = 0x1000;
3275
3276 err = 0;
3277 /* set EXIT -> OP_DONE is cleared */
3278 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3279
3280 /* kick */
3281 foreach_vch(ch) {
3282 if (ch_have_this_cs[ddr_csn % 2] & (1U << ch)) {
3283 ddr_setval(ch, reg_cs, ddr_csn);
3284 ddr_setval(ch, reg_kick, 0x01);
3285 }
3286 }
3287 foreach_vch(ch) {
3288 /*PREPARE ADDR REGISTER (for SWLVL_OP_DONE) */
3289 ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3290 }
3291 waiting = ch_have_this_cs[ddr_csn % 2];
3292 dsb_sev();
3293 retry = RETRY_MAX;
3294 do {
3295 foreach_vch(ch) {
3296 if (!(waiting & (1U << ch)))
3297 continue;
3298 dataL = ddr_getval(ch, _reg_PI_SWLVL_OP_DONE);
3299 if (dataL & 0x01)
3300 waiting &= ~(1U << ch);
3301 }
3302 retry--;
3303 } while (waiting && (retry > 0));
3304 if (retry == 0) {
3305 err = 1;
3306 }
3307
3308 dsb_sev();
3309 /* set EXIT -> OP_DONE is cleared */
3310 ddr_setval_ach(_reg_PI_SWLVL_EXIT, 0x01);
3311 dsb_sev();
3312
3313 return err;
3314}
3315
3316/*******************************************************************************
3317 * WDQ TRAINING
3318 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003319#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003320static void wdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3321{
3322 int32_t i, k;
3323 uint32_t cs, slice;
3324 uint32_t dataL;
3325
3326 /***********************************************************************
3327 clr of training results buffer
3328 ***********************************************************************/
3329 cs = ddr_csn % 2;
3330 dataL = Boardcnf->dqdm_dly_w;
3331 for (slice = 0; slice < SLICE_CNT; slice++) {
3332 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3333 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3334 continue;
3335
3336 for (i = 0; i <= 8; i++) {
3337 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch))
3338 wdqdm_dly[ch][cs][slice][i] =
3339 wdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3340 else
3341 wdqdm_dly[ch][cs][slice][i] = dataL;
3342 wdqdm_le[ch][cs][slice][i] = 0;
3343 wdqdm_te[ch][cs][slice][i] = 0;
3344 }
3345 wdqdm_st[ch][cs][slice] = 0;
3346 wdqdm_win[ch][cs][slice] = 0;
3347 }
3348}
3349
3350static uint32_t wdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3351{
3352 int32_t i, k;
3353 uint32_t cs, slice;
3354 uint32_t dataL;
3355 uint32_t err;
3356 const uint32_t _par_WDQLVL_RETRY_THRES = 0x7c0;
3357
3358 int32_t min_win;
3359 int32_t win;
3360 int8_t _adj;
3361 int16_t adj;
3362 uint32_t dq;
3363
3364 /***********************************************************************
3365 analysis of training results
3366 ***********************************************************************/
3367 err = 0;
3368 for (slice = 0; slice < SLICE_CNT; slice += 1) {
3369 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3370 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3371 continue;
3372
3373 cs = ddr_csn % 2;
3374 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003375 for (i = 0; i < 9; i++) {
3376 dq = slice * 8 + i;
3377 if (i == 8)
3378 _adj = Boardcnf->ch[ch].dm_adj_w[slice];
3379 else
3380 _adj = Boardcnf->ch[ch].dq_adj_w[dq];
3381 adj = _f_scale_adj(_adj);
3382
3383 dataL =
3384 ddr_getval_s(ch, slice,
3385 _reg_PHY_CLK_WRX_SLAVE_DELAY[i]) + adj;
3386 ddr_setval_s(ch, slice, _reg_PHY_CLK_WRX_SLAVE_DELAY[i],
3387 dataL);
3388 wdqdm_dly[ch][cs][slice][i] = dataL;
3389 }
3390 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x00);
3391 dataL = ddr_getval_s(ch, slice, _reg_PHY_WDQLVL_STATUS_OBS);
3392 wdqdm_st[ch][cs][slice] = dataL;
3393 min_win = INT_LEAST32_MAX;
3394 for (i = 0; i <= 8; i++) {
3395 ddr_setval_s(ch, slice, _reg_PHY_WDQLVL_DQDM_OBS_SELECT,
3396 i);
3397
3398 dataL =
3399 ddr_getval_s(ch, slice,
3400 _reg_PHY_WDQLVL_DQDM_TE_DLY_OBS);
3401 wdqdm_te[ch][cs][slice][i] = dataL;
3402 dataL =
3403 ddr_getval_s(ch, slice,
3404 _reg_PHY_WDQLVL_DQDM_LE_DLY_OBS);
3405 wdqdm_le[ch][cs][slice][i] = dataL;
3406 win =
3407 (int32_t) wdqdm_te[ch][cs][slice][i] -
3408 wdqdm_le[ch][cs][slice][i];
3409 if (min_win > win)
3410 min_win = win;
3411 if (dataL >= _par_WDQLVL_RETRY_THRES)
3412 err = 2;
3413 }
3414 wdqdm_win[ch][cs][slice] = min_win;
Marek Vasut6c245a52018-12-12 18:06:39 +01003415 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003416 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN, 0x01);
Marek Vasut6c245a52018-12-12 18:06:39 +01003417 } else {
3418 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_EN,
3419 ((ch_have_this_cs[1]) >> ch) & 0x01);
3420 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003421 }
3422 return err;
3423}
Marek Vasut6c245a52018-12-12 18:06:39 +01003424#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003425
3426static void wdqdm_cp(uint32_t ddr_csn, uint32_t restore)
3427{
3428 uint32_t i;
3429 uint32_t ch, slice;
3430 uint32_t tgt_cs, src_cs;
3431 uint32_t tmp_r;
3432
3433 /***********************************************************************
3434 copy of training results
3435 ***********************************************************************/
3436 foreach_vch(ch) {
3437 for (tgt_cs = 0; tgt_cs < CS_CNT; tgt_cs++) {
3438 for (slice = 0; slice < SLICE_CNT; slice++) {
3439 ddr_setval_s(ch, slice,
3440 _reg_PHY_PER_CS_TRAINING_INDEX,
3441 tgt_cs);
3442 src_cs = ddr_csn % 2;
3443 if (!(ch_have_this_cs[1] & (1U << ch)))
3444 src_cs = 0;
3445 for (i = 0; i <= 4; i += 4) {
3446 if (restore)
3447 tmp_r =
3448 rdqdm_dly[ch][tgt_cs][slice]
3449 [i];
3450 else
3451 tmp_r =
3452 rdqdm_dly[ch][src_cs][slice]
3453 [i];
3454
3455 ddr_setval_s(ch, slice,
3456 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY
3457 [i], tmp_r);
3458 }
3459 }
3460 }
3461 }
3462}
3463
3464static uint32_t wdqdm_man1(void)
3465{
3466 int32_t k;
3467 uint32_t ch, cs, slice;
3468 uint32_t ddr_csn;
3469 uint32_t dataL;
3470 uint32_t err;
Marek Vasut6c245a52018-12-12 18:06:39 +01003471 uint32_t high_dq[DRAM_CH_CNT];
3472 uint32_t mr14_csab0_bak[DRAM_CH_CNT];
3473#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003474 uint32_t err_flg;
Marek Vasut6c245a52018-12-12 18:06:39 +01003475#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003476
3477 /***********************************************************************
3478 manual execution of training
3479 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003480 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3481 foreach_vch(ch) {
3482 high_dq[ch] = 0;
3483 for (slice = 0; slice < SLICE_CNT; slice++) {
3484 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3485 if (k >= 2)
3486 high_dq[ch] |= (1U << slice);
3487 }
3488 ddr_setval(ch, _reg_PI_16BIT_DRAM_CONNECT, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003489 }
3490 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003491 err = 0;
3492 /* CLEAR PREV RESULT */
3493 for (cs = 0; cs < CS_CNT; cs++) {
3494 ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_INDEX, cs);
3495 if (((Prr_Product == PRR_PRODUCT_H3)
3496 && (Prr_Cut > PRR_PRODUCT_11))
3497 || (Prr_Product == PRR_PRODUCT_M3N)
3498 || (Prr_Product == PRR_PRODUCT_V3H)) {
3499 ddr_setval_ach_as(_reg_SC_PHY_WDQLVL_CLR_PREV_RESULTS,
3500 0x01);
3501 } else {
3502 ddr_setval_ach_as(_reg_PHY_WDQLVL_CLR_PREV_RESULTS,
3503 0x01);
3504 }
3505 }
3506 ddrphy_regif_idle();
3507
Marek Vasut6c245a52018-12-12 18:06:39 +01003508#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003509 err_flg = 0;
Marek Vasut6c245a52018-12-12 18:06:39 +01003510#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003511 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3512 if ((Prr_Product == PRR_PRODUCT_H3)
3513 && (Prr_Cut <= PRR_PRODUCT_11)) {
3514 foreach_vch(ch) {
3515 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3516 dataL &= ~(0x00ffU << 16);
3517
3518 if (ddr_csn >= 2)
3519 k = (high_dq[ch] ^ 0x0f);
3520 else
3521 k = high_dq[ch];
3522 dataL |= (k << 16);
3523 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3524 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, k);
3525 }
3526 }
3527 if (((Prr_Product == PRR_PRODUCT_H3)
3528 && (Prr_Cut <= PRR_PRODUCT_11))
3529 || ((Prr_Product == PRR_PRODUCT_M3)
3530 && (Prr_Cut == PRR_PRODUCT_10))) {
3531 wdqdm_cp(ddr_csn, 0);
3532 }
3533
3534 foreach_vch(ch) {
3535 dataL =
3536 ddr_getval(ch,
3537 _reg_PI_MR14_DATA_Fx_CSx[1][ddr_csn]);
3538 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0], dataL);
3539 }
3540
3541 /* KICK WDQLVL */
3542 err = swlvl1(ddr_csn, _reg_PI_WDQLVL_CS, _reg_PI_WDQLVL_REQ);
3543 if (err)
3544 goto err_exit;
3545
3546 if (ddr_csn == 0)
3547 foreach_vch(ch) {
3548 mr14_csab0_bak[ch] =
3549 ddr_getval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0]);
3550 } else
3551 foreach_vch(ch) {
3552 ddr_setval(ch, _reg_PI_MR14_DATA_Fx_CSx[1][0],
3553 mr14_csab0_bak[ch]);
3554 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003555#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003556 foreach_vch(ch) {
3557 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3558 wdqdm_clr1(ch, ddr_csn);
3559 continue;
3560 }
3561 err = wdqdm_ana1(ch, ddr_csn);
3562 if (err)
3563 err_flg |= (1U << (ddr_csn * 4 + ch));
3564 ddrphy_regif_idle();
3565 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003566#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003567 }
3568err_exit:
Marek Vasut6c245a52018-12-12 18:06:39 +01003569#ifndef DDR_FAST_INIT
3570 err |= err_flg;
3571#endif/* DDR_FAST_INIT */
3572 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3573 ddr_setval_ach(_reg_PI_16BIT_DRAM_CONNECT, 0x01);
3574 foreach_vch(ch) {
3575 dataL = mmio_read_32(DBSC_DBDFICNT(ch));
3576 dataL &= ~(0x00ffU << 16);
3577 mmio_write_32(DBSC_DBDFICNT(ch), dataL);
3578 ddr_setval(ch, _reg_PI_WDQLVL_RESP_MASK, 0x00);
3579 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003580 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003581 return (err);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003582}
3583
3584static uint32_t wdqdm_man(void)
3585{
3586 uint32_t err, retry_cnt;
3587 const uint32_t retry_max = 0x10;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003588 uint32_t ch, ddr_csn, mr14_bkup[4][4];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003589
3590 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_RW, (DBSC_DBTR(11) & 0xFF) + 12);
3591 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut > PRR_PRODUCT_11))
3592 || (Prr_Product == PRR_PRODUCT_M3N)
3593 || (Prr_Product == PRR_PRODUCT_V3H)) {
3594 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR_F1,
3595 (DBSC_DBTR(12) & 0xFF) + 1);
3596 } else {
3597 ddr_setval_ach(_reg_PI_TDFI_WDQLVL_WR,
3598 (DBSC_DBTR(12) & 0xFF) + 1);
3599 }
3600 ddr_setval_ach(_reg_PI_TRFC_F1, (DBSC_DBTR(13) & 0x1FF));
3601
3602 retry_cnt = 0;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003603 err = 0;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003604 do {
3605 if ((Prr_Product == PRR_PRODUCT_H3)
3606 && (Prr_Cut <= PRR_PRODUCT_11)) {
3607 err = wdqdm_man1();
3608 } else {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003609 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x01);
3610 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3611 0x01);
3612 if ((Prr_Product == PRR_PRODUCT_M3N)
3613 || (Prr_Product == PRR_PRODUCT_V3H)) {
3614 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3615 0x0C);
3616 } else {
3617 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x0C);
3618 }
3619 dsb_sev();
3620 err = wdqdm_man1();
3621 foreach_vch(ch) {
3622 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3623 mr14_bkup[ch][ddr_csn] =
3624 ddr_getval(ch,
3625 _reg_PI_MR14_DATA_Fx_CSx
3626 [1][ddr_csn]);
3627 dsb_sev();
3628 }
3629 }
3630
3631 if ((Prr_Product == PRR_PRODUCT_M3N)
3632 || (Prr_Product == PRR_PRODUCT_V3H)) {
3633 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3634 0x04);
3635 } else {
3636 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x04);
3637 }
3638 pvtcode_update();
3639 err = wdqdm_man1();
3640 foreach_vch(ch) {
3641 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
3642 mr14_bkup[ch][ddr_csn] =
3643 (mr14_bkup[ch][ddr_csn] +
3644 ddr_getval(ch,
3645 _reg_PI_MR14_DATA_Fx_CSx
3646 [1][ddr_csn])) / 2;
3647 ddr_setval(ch,
3648 _reg_PI_MR14_DATA_Fx_CSx[1]
3649 [ddr_csn],
3650 mr14_bkup[ch][ddr_csn]);
3651 }
3652 }
3653
3654 ddr_setval_ach(_reg_PI_WDQLVL_VREF_NORMAL_STEPSIZE,
3655 0x00);
3656 if ((Prr_Product == PRR_PRODUCT_M3N)
3657 || (Prr_Product == PRR_PRODUCT_V3H)) {
3658 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA_F1,
3659 0x00);
3660 ddr_setval_ach
3661 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT_F1,
3662 0x00);
3663 ddr_setval_ach
3664 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1,
3665 0x00);
3666 } else {
3667 ddr_setval_ach(_reg_PI_WDQLVL_VREF_DELTA, 0x00);
3668 ddr_setval_ach
3669 (_reg_PI_WDQLVL_VREF_INITIAL_START_POINT,
3670 0x00);
3671 ddr_setval_ach
3672 (_reg_PI_WDQLVL_VREF_INITIAL_STOP_POINT,
3673 0x00);
3674 }
3675 ddr_setval_ach(_reg_PI_WDQLVL_VREF_INITIAL_STEPSIZE,
3676 0x00);
3677
3678 pvtcode_update2();
3679 err = wdqdm_man1();
3680 ddr_setval_ach(_reg_PI_WDQLVL_VREF_EN, 0x00);
3681 }
3682 } while (err && (++retry_cnt < retry_max));
3683
3684 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
3685 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_10))) {
3686 wdqdm_cp(0, 1);
3687 }
3688
3689 return (retry_cnt >= retry_max);
3690}
3691
3692/*******************************************************************************
3693 * RDQ TRAINING
3694 ******************************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01003695#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003696static void rdqdm_clr1(uint32_t ch, uint32_t ddr_csn)
3697{
3698 int32_t i, k;
3699 uint32_t cs, slice;
3700 uint32_t dataL;
3701
3702 /***********************************************************************
3703 clr of training results buffer
3704 ***********************************************************************/
3705 cs = ddr_csn % 2;
3706 dataL = Boardcnf->dqdm_dly_r;
3707 for (slice = 0; slice < SLICE_CNT; slice++) {
3708 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3709 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3710 continue;
3711
3712 for (i = 0; i <= 8; i++) {
3713 if (ch_have_this_cs[CS_CNT - 1 - cs] & (1U << ch)) {
3714 rdqdm_dly[ch][cs][slice][i] =
3715 rdqdm_dly[ch][CS_CNT - 1 - cs][slice][i];
3716 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] =
3717 rdqdm_dly[ch][CS_CNT - 1 - cs][slice +
3718 SLICE_CNT]
3719 [i];
3720 } else {
3721 rdqdm_dly[ch][cs][slice][i] = dataL;
3722 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3723 }
3724 rdqdm_le[ch][cs][slice][i] = 0;
3725 rdqdm_le[ch][cs][slice + SLICE_CNT][i] = 0;
3726 rdqdm_te[ch][cs][slice][i] = 0;
3727 rdqdm_te[ch][cs][slice + SLICE_CNT][i] = 0;
3728 rdqdm_nw[ch][cs][slice][i] = 0;
3729 rdqdm_nw[ch][cs][slice + SLICE_CNT][i] = 0;
3730 }
3731 rdqdm_st[ch][cs][slice] = 0;
3732 rdqdm_win[ch][cs][slice] = 0;
3733 }
3734}
3735
3736static uint32_t rdqdm_ana1(uint32_t ch, uint32_t ddr_csn)
3737{
3738 int32_t i, k;
3739 uint32_t cs, slice;
3740 uint32_t dataL;
3741 uint32_t err;
3742 int8_t _adj;
3743 int16_t adj;
3744 uint32_t dq;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003745 int32_t min_win;
3746 int32_t win;
3747 uint32_t rdq_status_obs_select;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003748
3749 /***********************************************************************
3750 analysis of training results
3751 ***********************************************************************/
3752 err = 0;
3753 for (slice = 0; slice < SLICE_CNT; slice++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003754 k = (Boardcnf->ch[ch].dqs_swap >> (4 * slice)) & 0x0f;
3755 if (((k >= 2) && (ddr_csn < 2)) || ((k < 2) && (ddr_csn >= 2)))
3756 continue;
3757
3758 cs = ddr_csn % 2;
3759 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, cs);
3760 ddrphy_regif_idle();
3761
3762 ddr_getval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX);
3763 ddrphy_regif_idle();
3764
3765 for (i = 0; i <= 8; i++) {
3766 dq = slice * 8 + i;
3767 if (i == 8)
3768 _adj = Boardcnf->ch[ch].dm_adj_r[slice];
3769 else
3770 _adj = Boardcnf->ch[ch].dq_adj_r[dq];
3771
3772 adj = _f_scale_adj(_adj);
3773
3774 dataL =
3775 ddr_getval_s(ch, slice,
3776 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) +
3777 adj;
3778 ddr_setval_s(ch, slice,
3779 _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i],
3780 dataL);
3781 rdqdm_dly[ch][cs][slice][i] = dataL;
3782
3783 dataL =
3784 ddr_getval_s(ch, slice,
3785 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) +
3786 adj;
3787 ddr_setval_s(ch, slice,
3788 _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i],
3789 dataL);
3790 rdqdm_dly[ch][cs][slice + SLICE_CNT][i] = dataL;
3791 }
3792 min_win = INT_LEAST32_MAX;
3793 for (i = 0; i <= 8; i++) {
3794 dataL =
3795 ddr_getval_s(ch, slice, _reg_PHY_RDLVL_STATUS_OBS);
3796 rdqdm_st[ch][cs][slice] = dataL;
3797 rdqdm_st[ch][cs][slice + SLICE_CNT] = dataL;
3798 /* k : rise/fall */
3799 for (k = 0; k < 2; k++) {
3800 if (i == 8) {
3801 rdq_status_obs_select = 16 + 8 * k;
3802 } else {
3803 rdq_status_obs_select = i + k * 8;
3804 }
3805 ddr_setval_s(ch, slice,
3806 _reg_PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3807 rdq_status_obs_select);
3808
3809 dataL =
3810 ddr_getval_s(ch, slice,
3811 _reg_PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3812 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i] =
3813 dataL;
3814
3815 dataL =
3816 ddr_getval_s(ch, slice,
3817 _reg_PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3818 rdqdm_te[ch][cs][slice + SLICE_CNT * k][i] =
3819 dataL;
3820
3821 dataL =
3822 ddr_getval_s(ch, slice,
3823 _reg_PHY_RDLVL_RDDQS_DQ_NUM_WINDOWS_OBS);
3824 rdqdm_nw[ch][cs][slice + SLICE_CNT * k][i] =
3825 dataL;
3826
3827 win =
3828 (int32_t) rdqdm_te[ch][cs][slice +
3829 SLICE_CNT *
3830 k][i] -
3831 rdqdm_le[ch][cs][slice + SLICE_CNT * k][i];
3832 if (i != 8) {
3833 if (min_win > win)
3834 min_win = win;
3835 }
3836 }
3837 }
3838 rdqdm_win[ch][cs][slice] = min_win;
3839 if (min_win <= 0) {
3840 err = 2;
3841 }
3842 }
3843 return (err);
3844}
Marek Vasut6c245a52018-12-12 18:06:39 +01003845#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003846
3847static uint32_t rdqdm_man1(void)
3848{
3849 uint32_t ch;
3850 uint32_t ddr_csn;
Marek Vasut6c245a52018-12-12 18:06:39 +01003851#ifdef DDR_FAST_INIT
3852 uint32_t slice;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003853 uint32_t i, adj, dataL;
Marek Vasut6c245a52018-12-12 18:06:39 +01003854#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003855 uint32_t err;
3856
3857 /***********************************************************************
3858 manual execution of training
3859 ***********************************************************************/
3860 err = 0;
3861
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003862 for (ddr_csn = 0; ddr_csn < CSAB_CNT; ddr_csn++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003863 /* KICK RDQLVL */
3864 err = swlvl1(ddr_csn, _reg_PI_RDLVL_CS, _reg_PI_RDLVL_REQ);
3865 if (err)
3866 goto err_exit;
Marek Vasut6c245a52018-12-12 18:06:39 +01003867#ifndef DDR_FAST_INIT
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003868 foreach_vch(ch) {
3869 if (!(ch_have_this_cs[ddr_csn % 2] & (1U << ch))) {
3870 rdqdm_clr1(ch, ddr_csn);
3871 ddrphy_regif_idle();
3872 continue;
3873 }
3874 err = rdqdm_ana1(ch, ddr_csn);
3875 ddrphy_regif_idle();
3876 if (err)
3877 goto err_exit;
3878 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003879#else/* DDR_FAST_INIT */
3880 foreach_vch(ch) {
3881 if (ch_have_this_cs[ddr_csn] & (1U << ch)) {
3882 for (slice = 0; slice < SLICE_CNT; slice++) {
3883 if (ddr_getval_s(ch, slice,
3884 _reg_PHY_RDLVL_STATUS_OBS) !=
3885 0x0D00FFFF) {
3886 err = (1U << ch) |
3887 (0x10U << slice);
3888 goto err_exit;
3889 }
3890 }
3891 }
3892 if (((Prr_Product == PRR_PRODUCT_H3)
3893 && (Prr_Cut <= PRR_PRODUCT_11))
3894 || ((Prr_Product == PRR_PRODUCT_M3)
3895 && (Prr_Cut <= PRR_PRODUCT_10))) {
Marek Vasut6c245a52018-12-12 18:06:39 +01003896 for (slice = 0; slice < SLICE_CNT; slice++) {
3897 for (i = 0; i <= 8; i++) {
3898 if (i == 8)
3899 adj = _f_scale_adj(Boardcnf->ch[ch].dm_adj_r[slice]);
3900 else
3901 adj = _f_scale_adj(Boardcnf->ch[ch].dq_adj_r[slice * 8 + i]);
3902 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX, ddr_csn);
3903 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i]) + adj;
3904 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_RISE_SLAVE_DELAY[i], dataL);
3905 rdqdm_dly[ch][ddr_csn][slice][i] = dataL;
3906 rdqdm_dly[ch][ddr_csn | 1][slice][i] = dataL;
3907
3908 dataL = ddr_getval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i]) + adj;
3909 ddr_setval_s(ch, slice, _reg_PHY_RDDQS_X_FALL_SLAVE_DELAY[i], dataL);
3910 rdqdm_dly[ch][ddr_csn][slice + SLICE_CNT][i] = dataL;
3911 rdqdm_dly[ch][ddr_csn | 1][slice + SLICE_CNT][i] = dataL;
3912 }
3913 }
3914 }
3915 }
3916 ddrphy_regif_idle();
3917
3918#endif/* DDR_FAST_INIT */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003919 }
Marek Vasut6c245a52018-12-12 18:06:39 +01003920
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003921err_exit:
3922 return (err);
3923}
3924
3925static uint32_t rdqdm_man(void)
3926{
3927 uint32_t err, retry_cnt;
3928 const uint32_t retry_max = 0x01;
3929
3930 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3931 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3932 _reg_PHY_DQ_TSEL_ENABLE));
3933 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3934 0x00000004 | ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3935 _reg_PHY_DQS_TSEL_ENABLE));
3936 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3937 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3938 _reg_PHY_DQ_TSEL_SELECT));
3939 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3940 0xFF0FFFFF & ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3941 _reg_PHY_DQS_TSEL_SELECT));
3942
3943 retry_cnt = 0;
3944 do {
3945 err = rdqdm_man1();
3946 ddrphy_regif_idle();
3947 } while (err && (++retry_cnt < retry_max));
3948 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_ENABLE,
3949 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3950 _reg_PHY_DQ_TSEL_ENABLE));
3951 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_ENABLE,
3952 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3953 _reg_PHY_DQS_TSEL_ENABLE));
3954 ddr_setval_ach_as(_reg_PHY_DQ_TSEL_SELECT,
3955 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3956 _reg_PHY_DQ_TSEL_SELECT));
3957 ddr_setval_ach_as(_reg_PHY_DQS_TSEL_SELECT,
3958 ddrtbl_getval(_cnf_DDR_PHY_SLICE_REGSET,
3959 _reg_PHY_DQS_TSEL_SELECT));
3960
3961 return (retry_cnt >= retry_max);
3962}
3963
3964/*******************************************************************************
3965 * rx offset calibration
3966 ******************************************************************************/
3967static int32_t _find_change(uint64_t val, uint32_t dir)
3968{
3969 int32_t i;
3970 uint32_t startval;
3971 uint32_t curval;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09003972 const int32_t VAL_END = 0x3f;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02003973
3974 if (dir == 0) {
3975 startval = (val & 0x01);
3976 for (i = 1; i <= VAL_END; i++) {
3977 curval = (val >> i) & 0x01;
3978 if (curval != startval)
3979 return (i);
3980 }
3981 return (VAL_END);
3982 } else {
3983 startval = (val >> dir) & 0x01;
3984 for (i = dir - 1; i >= 0; i--) {
3985 curval = (val >> i) & 0x01;
3986 if (curval != startval)
3987 return (i);
3988 }
3989 return (0);
3990 }
3991}
3992
3993static uint32_t _rx_offset_cal_updn(uint32_t code)
3994{
3995 const uint32_t CODE_MAX = 0x40;
3996 uint32_t tmp;
3997
3998 if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
3999 if (code == 0)
4000 tmp = (1U << 6) | (CODE_MAX - 1);
4001 else if (code <= 0x20)
4002 tmp =
4003 ((CODE_MAX - 1 -
4004 (0x20 - code) * 2) << 6) | (CODE_MAX - 1);
4005 else
4006 tmp =
4007 ((CODE_MAX - 1) << 6) | (CODE_MAX - 1 -
4008 (code - 0x20) * 2);
4009 } else {
4010 if (code == 0)
4011 tmp = (1U << 6) | (CODE_MAX - 1);
4012 else
4013 tmp = (code << 6) | (CODE_MAX - code);
4014 }
4015 return tmp;
4016}
4017
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004018static uint32_t rx_offset_cal(void)
4019{
4020 uint32_t index;
4021 uint32_t code;
4022 const uint32_t CODE_MAX = 0x40;
4023 const uint32_t CODE_STEP = 2;
4024 uint32_t ch, slice;
4025 uint32_t tmp;
4026 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
4027 uint64_t val[DRAM_CH_CNT][SLICE_CNT][_reg_PHY_RX_CAL_X_NUM];
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004028 uint64_t tmpval;
4029 int32_t lsb, msb;
Marek Vasut6c245a52018-12-12 18:06:39 +01004030
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004031 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x01);
4032 foreach_vch(ch) {
4033 for (slice = 0; slice < SLICE_CNT; slice++) {
4034 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
4035 val[ch][slice][index] = 0;
4036 }
4037 }
4038 }
4039
4040 for (code = 0; code < CODE_MAX / CODE_STEP; code++) {
4041 tmp = _rx_offset_cal_updn(code * CODE_STEP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004042 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
4043 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[index], tmp);
4044 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004045 dsb_sev();
4046 ddr_getval_ach_as(_reg_PHY_RX_CAL_OBS, (uint32_t *) tmp_ach_as);
4047
4048 foreach_vch(ch) {
4049 for (slice = 0; slice < SLICE_CNT; slice++) {
4050 tmp = tmp_ach_as[ch][slice];
4051 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM;
4052 index++) {
4053 if (tmp & (1U << index)) {
4054 val[ch][slice][index] |=
4055 (1ULL << code);
4056 } else {
4057 val[ch][slice][index] &=
4058 ~(1ULL << code);
4059 }
4060 }
4061 }
4062 }
4063 }
4064 foreach_vch(ch) {
4065 for (slice = 0; slice < SLICE_CNT; slice++) {
4066 for (index = 0; index < _reg_PHY_RX_CAL_X_NUM; index++) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004067 tmpval = val[ch][slice][index];
4068 lsb = _find_change(tmpval, 0);
4069 msb =
4070 _find_change(tmpval,
4071 (CODE_MAX / CODE_STEP) - 1);
4072 tmp = (lsb + msb) >> 1;
4073
4074 tmp = _rx_offset_cal_updn(tmp * CODE_STEP);
4075 ddr_setval_s(ch, slice,
4076 _reg_PHY_RX_CAL_X[index], tmp);
4077 }
4078 }
4079 }
4080 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004081
4082 return 0;
4083}
4084
4085static uint32_t rx_offset_cal_hw(void)
4086{
4087 uint32_t ch, slice;
4088 uint32_t retry;
4089 uint32_t complete;
4090 uint32_t tmp;
4091 uint32_t tmp_ach_as[DRAM_CH_CNT][SLICE_CNT];
4092
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004093 ddr_setval_ach_as(_reg_PHY_RX_CAL_X[9], 0x00);
4094 ddr_setval_ach_as(_reg_PHY_RX_CAL_OVERRIDE, 0x00);
4095 ddr_setval_ach_as(_reg_PHY_RX_CAL_SAMPLE_WAIT, 0x0f);
4096
4097 retry = 0;
4098 while (retry < 4096) {
4099 if ((retry & 0xff) == 0) {
4100 ddr_setval_ach_as(_reg_SC_PHY_RX_CAL_START, 0x01);
4101 }
4102 foreach_vch(ch)
4103 for (slice = 0; slice < SLICE_CNT; slice++)
4104 tmp_ach_as[ch][slice] =
4105 ddr_getval_s(ch, slice, _reg_PHY_RX_CAL_X[9]);
4106
4107 complete = 1;
4108 foreach_vch(ch) {
4109 for (slice = 0; slice < SLICE_CNT; slice++) {
4110 tmp = tmp_ach_as[ch][slice];
4111 tmp = (tmp & 0x3f) + ((tmp >> 6) & 0x3f);
4112 if (((Prr_Product == PRR_PRODUCT_H3)
4113 && (Prr_Cut > PRR_PRODUCT_11))
4114 || (Prr_Product == PRR_PRODUCT_M3N)
4115 || (Prr_Product == PRR_PRODUCT_V3H)) {
4116 if (tmp != 0x3E)
4117 complete = 0;
4118 } else {
4119 if (tmp != 0x40)
4120 complete = 0;
4121 }
4122 }
4123 }
4124 if (complete)
4125 break;
4126
4127 retry++;
4128 }
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004129
4130 return (complete == 0);
4131}
4132
4133/*******************************************************************************
4134 * adjust rddqs latency
4135 ******************************************************************************/
4136static void adjust_rddqs_latency(void)
4137{
4138 uint32_t ch, slice;
4139 uint32_t dly;
4140 uint32_t maxlatx2;
4141 uint32_t tmp;
4142 uint32_t rdlat_adjx2[SLICE_CNT];
4143 foreach_vch(ch) {
4144 maxlatx2 = 0;
4145 for (slice = 0; slice < SLICE_CNT; slice++) {
4146 ddr_setval_s(ch, slice, _reg_PHY_PER_CS_TRAINING_INDEX,
4147 0x00);
4148
4149 dly =
4150 ddr_getval_s(ch, slice,
4151 _reg_PHY_RDDQS_GATE_SLAVE_DELAY);
4152 tmp =
4153 ddr_getval_s(ch, slice,
4154 _reg_PHY_RDDQS_LATENCY_ADJUST);
4155 /* note gate_slave_delay[9] is always 0 */
4156 tmp = (tmp << 1) + (dly >> 8);
4157 rdlat_adjx2[slice] = tmp;
4158 if (maxlatx2 < tmp)
4159 maxlatx2 = tmp;
4160 }
4161 maxlatx2 = ((maxlatx2 + 1) >> 1) << 1;
4162 for (slice = 0; slice < SLICE_CNT; slice++) {
4163 tmp = maxlatx2 - rdlat_adjx2[slice];
4164 tmp = (tmp >> 1);
4165 if (tmp) {
4166 ddr_setval_s(ch, slice, _reg_PHY_RPTR_UPDATE,
4167 ddr_getval_s(ch, slice,
4168 _reg_PHY_RPTR_UPDATE)
4169 + 1);
4170 }
4171 }
4172 }
4173}
4174
4175/*******************************************************************************
4176 * adjust wpath latency
4177 ******************************************************************************/
4178static void adjust_wpath_latency(void)
4179{
4180 uint32_t ch, cs, slice;
4181 uint32_t dly;
4182 uint32_t wpath_add;
4183 const uint32_t _par_EARLY_THRESHOLD_VAL = 0x180;
4184
4185 foreach_vch(ch) {
4186 for (slice = 0; slice < SLICE_CNT; slice += 1) {
4187 for (cs = 0; cs < CS_CNT; cs++) {
4188 ddr_setval_s(ch, slice,
4189 _reg_PHY_PER_CS_TRAINING_INDEX,
4190 cs);
4191 ddr_getval_s(ch, slice,
4192 _reg_PHY_PER_CS_TRAINING_INDEX);
4193 dly =
4194 ddr_getval_s(ch, slice,
4195 _reg_PHY_CLK_WRDQS_SLAVE_DELAY);
4196 if (dly <= _par_EARLY_THRESHOLD_VAL)
4197 continue;
4198
4199 wpath_add =
4200 ddr_getval_s(ch, slice,
4201 _reg_PHY_WRITE_PATH_LAT_ADD);
4202 ddr_setval_s(ch, slice,
4203 _reg_PHY_WRITE_PATH_LAT_ADD,
4204 wpath_add - 1);
4205 }
4206 }
4207 }
4208}
4209
4210/*******************************************************************************
4211 * DDR Initialize entry
4212 ******************************************************************************/
4213int32_t rcar_dram_init(void)
4214{
4215 uint32_t ch, cs;
4216 uint32_t dataL;
4217 uint32_t bus_mbps, bus_mbpsdiv;
4218 uint32_t tmp_tccd;
4219 uint32_t failcount;
4220
4221 /***********************************************************************
4222 Thermal sensor setting
4223 ***********************************************************************/
Marek Vasut6c245a52018-12-12 18:06:39 +01004224 dataL = mmio_read_32(CPG_MSTPSR5);
Marek Vasuta75f8262019-07-14 08:55:27 +02004225 if (dataL & BIT(22)) { /* case THS/TSC Standby */
4226 dataL &= ~(BIT(22));
Marek Vasut6c245a52018-12-12 18:06:39 +01004227 cpg_write_32(CPG_SMSTPCR5, dataL);
Marek Vasuta75f8262019-07-14 08:55:27 +02004228 while ((BIT(22)) & mmio_read_32(CPG_MSTPSR5)); /* wait bit=0 */
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004229 }
4230
4231 /* THCTR Bit6: PONM=0 , Bit0: THSST=0 */
Marek Vasut6c245a52018-12-12 18:06:39 +01004232 dataL = mmio_read_32(THS1_THCTR) & 0xFFFFFFBE;
4233 mmio_write_32(THS1_THCTR, dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004234
4235 /***********************************************************************
4236 Judge product and cut
4237 ***********************************************************************/
4238#ifdef RCAR_DDR_FIXED_LSI_TYPE
4239#if(RCAR_LSI==RCAR_AUTO)
4240 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4241 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4242#else /* RCAR_LSI */
4243#ifndef RCAR_LSI_CUT
4244 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4245#endif /* RCAR_LSI_CUT */
4246#endif /* RCAR_LSI */
4247#else /* RCAR_DDR_FIXED_LSI_TYPE */
4248 Prr_Product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
4249 Prr_Cut = mmio_read_32(PRR) & PRR_CUT_MASK;
4250#endif /* RCAR_DDR_FIXED_LSI_TYPE */
4251
4252 if (Prr_Product == PRR_PRODUCT_H3) {
4253 if (Prr_Cut <= PRR_PRODUCT_11) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004254 pDDR_REGDEF_TBL = (const uint32_t *)&DDR_REGDEF_TBL[0][0];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004255 } else {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004256 pDDR_REGDEF_TBL = (const uint32_t *)&DDR_REGDEF_TBL[2][0];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004257 }
4258 } else if (Prr_Product == PRR_PRODUCT_M3) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004259 pDDR_REGDEF_TBL = (const uint32_t *)&DDR_REGDEF_TBL[1][0];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004260 } else if ((Prr_Product == PRR_PRODUCT_M3N)
4261 || (Prr_Product == PRR_PRODUCT_V3H)) {
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004262 pDDR_REGDEF_TBL = (const uint32_t *)&DDR_REGDEF_TBL[3][0];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004263 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004264 FATAL_MSG("BL2: DDR:Unknown Product\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004265 return 0xff;
4266 }
4267
4268 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01004269 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004270 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4271 } else {
4272 mmio_write_32(DBSC_DBSYSCNT0, 0x00001234);
4273 }
4274
4275 /***********************************************************************
4276 Judge board type
4277 ***********************************************************************/
4278 _cnf_BOARDTYPE = boardcnf_get_brd_type();
4279 if (_cnf_BOARDTYPE >= BOARDNUM) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004280 FATAL_MSG("BL2: DDR:Unknown Board\n");
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004281 return 0xff;
4282 }
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004283 Boardcnf = (const struct _boardcnf *)&boardcnfs[_cnf_BOARDTYPE];
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004284
4285/* RCAR_DRAM_SPLIT_2CH (2U) */
4286#if RCAR_DRAM_SPLIT == 2
4287 /***********************************************************************
4288 H3(Test for future H3-N): Swap ch2 and ch1 for 2ch-split
4289 ***********************************************************************/
4290 if ((Prr_Product == PRR_PRODUCT_H3) && (Boardcnf->phyvalid == 0x05)) {
4291 mmio_write_32(DBSC_DBMEMSWAPCONF0, 0x00000006);
4292 ddr_phyvalid = 0x03;
4293 } else {
4294 ddr_phyvalid = Boardcnf->phyvalid;
4295 }
4296#else /* RCAR_DRAM_SPLIT_2CH */
4297 ddr_phyvalid = Boardcnf->phyvalid;
4298#endif /* RCAR_DRAM_SPLIT_2CH */
4299
4300 max_density = 0;
4301
4302 for (cs = 0; cs < CS_CNT; cs++) {
4303 ch_have_this_cs[cs] = 0;
4304 }
4305
4306 foreach_ech(ch)
4307 for (cs = 0; cs < CS_CNT; cs++)
4308 ddr_density[ch][cs] = 0xff;
4309
4310 foreach_vch(ch) {
4311 for (cs = 0; cs < CS_CNT; cs++) {
4312 dataL = Boardcnf->ch[ch].ddr_density[cs];
4313 ddr_density[ch][cs] = dataL;
4314
4315 if (dataL == 0xff)
4316 continue;
4317 if (dataL > max_density)
4318 max_density = dataL;
4319 if ((cs == 1) && (Prr_Product == PRR_PRODUCT_H3)
4320 && (Prr_Cut <= PRR_PRODUCT_11))
4321 continue;
4322 ch_have_this_cs[cs] |= (1U << ch);
4323 }
4324 }
4325
4326 /***********************************************************************
4327 Judge board clock frequency (in MHz)
4328 ***********************************************************************/
4329 boardcnf_get_brd_clk(_cnf_BOARDTYPE, &brd_clk, &brd_clkdiv);
4330 if ((brd_clk / brd_clkdiv) > 25) {
4331 brd_clkdiva = 1;
4332 } else {
4333 brd_clkdiva = 0;
4334 }
4335
4336 /***********************************************************************
4337 Judge ddr operating frequency clock(in Mbps)
4338 ***********************************************************************/
4339 boardcnf_get_ddr_mbps(_cnf_BOARDTYPE, &ddr_mbps, &ddr_mbpsdiv);
4340
4341 ddr0800_mul = CLK_DIV(800, 2, brd_clk, brd_clkdiv * (brd_clkdiva + 1));
4342
4343 ddr_mul =
4344 CLK_DIV(ddr_mbps, ddr_mbpsdiv * 2, brd_clk,
4345 brd_clkdiv * (brd_clkdiva + 1));
4346
4347 /***********************************************************************
4348 Adjust tccd
4349 ***********************************************************************/
4350 dataL = (0x00006000 & mmio_read_32(RST_MODEMR)) >> 13;
Chiaki Fujii59263ee2019-05-17 10:45:02 +09004351 bus_mbps = 0;
4352 bus_mbpsdiv = 0;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004353 switch (dataL) {
4354 case 0:
4355 bus_mbps = brd_clk * 0x60 * 2;
4356 bus_mbpsdiv = brd_clkdiv * 1;
4357 break;
4358 case 1:
4359 bus_mbps = brd_clk * 0x50 * 2;
4360 bus_mbpsdiv = brd_clkdiv * 1;
4361 break;
4362 case 2:
4363 bus_mbps = brd_clk * 0x40 * 2;
4364 bus_mbpsdiv = brd_clkdiv * 1;
4365 break;
4366 case 3:
4367 bus_mbps = brd_clk * 0x60 * 2;
4368 bus_mbpsdiv = brd_clkdiv * 2;
4369 break;
4370 default:
4371 bus_mbps = brd_clk * 0x60 * 2;
4372 bus_mbpsdiv = brd_clkdiv * 2;
4373 break;
4374 }
4375 tmp_tccd = CLK_DIV(ddr_mbps * 8, ddr_mbpsdiv, bus_mbps, bus_mbpsdiv);
4376 if (8 * ddr_mbps * bus_mbpsdiv != tmp_tccd * bus_mbps * ddr_mbpsdiv)
4377 tmp_tccd = tmp_tccd + 1;
4378
4379 if (tmp_tccd < 8)
4380 ddr_tccd = 8;
4381 else
4382 ddr_tccd = tmp_tccd;
4383
Marek Vasut6c245a52018-12-12 18:06:39 +01004384 NOTICE("BL2: DDR%d(%s)\n", ddr_mbps / ddr_mbpsdiv, RCAR_DDR_VERSION);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004385
4386 MSG_LF("Start\n");
4387
4388 /***********************************************************************
4389 PLL Setting
4390 ***********************************************************************/
4391 pll3_control(1);
4392
4393 /***********************************************************************
4394 initialize DDR
4395 ***********************************************************************/
4396 dataL = init_ddr();
4397 if (dataL == ddr_phyvalid) {
4398 failcount = 0;
4399 } else {
4400 failcount = 1;
4401 }
4402
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004403 foreach_vch(ch)
4404 mmio_write_32(DBSC_DBPDLK(ch), 0x00000000);
4405 if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
Marek Vasut3af20052019-02-25 14:57:08 +01004406 || ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30))) {
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004407 /* non : H3 Ver.1.x/M3-W Ver.1.x not support */
4408 } else {
4409 mmio_write_32(DBSC_DBSYSCNT0, 0x00000000);
4410 }
4411
4412 if (failcount == 0) {
4413 return INITDRAM_OK;
4414 } else {
4415 return INITDRAM_NG;
4416 }
4417}
4418
4419void pvtcode_update(void)
4420{
4421 uint32_t ch;
Marek Vasut6c245a52018-12-12 18:06:39 +01004422 uint32_t dataL;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004423 uint32_t pvtp[4], pvtn[4], pvtp_init, pvtn_init;
4424 int32_t pvtp_tmp, pvtn_tmp;
4425
4426 foreach_vch(ch) {
4427 pvtn_init = (tcal.tcomp_cal[ch] & 0xFC0) >> 6;
4428 pvtp_init = (tcal.tcomp_cal[ch] & 0x03F) >> 0;
4429
4430 if (8912 * pvtp_init > 44230) {
4431 pvtp_tmp = (5000 + 8912 * pvtp_init - 44230) / 10000;
4432 } else {
4433 pvtp_tmp =
4434 -((-(5000 + 8912 * pvtp_init - 44230)) / 10000);
4435 }
4436 pvtn_tmp = (5000 + 5776 * pvtn_init + 30280) / 10000;
4437
4438 pvtn[ch] = pvtn_tmp + pvtn_init;
4439 pvtp[ch] = pvtp_tmp + pvtp_init;
4440
4441 if (pvtn[ch] > 63) {
4442 pvtn[ch] = 63;
4443 pvtp[ch] =
4444 (pvtp_tmp) * (63 - 6 * pvtn_tmp -
4445 pvtn_init) / (pvtn_tmp) +
4446 6 * pvtp_tmp + pvtp_init;
4447 }
4448 if ((Prr_Product == PRR_PRODUCT_H3)
4449 && (Prr_Cut <= PRR_PRODUCT_11)) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004450 dataL = pvtp[ch] | (pvtn[ch] << 6) | (tcal.tcomp_cal[ch] & 0xfffff000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004451 reg_ddrphy_write(ch,
4452 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004453 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004454 reg_ddrphy_write(ch,
4455 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004456 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004457 reg_ddrphy_write(ch,
4458 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004459 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004460 reg_ddrphy_write(ch,
4461 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004462 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004463 reg_ddrphy_write(ch,
4464 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004465 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004466 } else {
Marek Vasut6c245a52018-12-12 18:06:39 +01004467 dataL = pvtp[ch] | (pvtn[ch] << 6) | 0x00015000;
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004468 reg_ddrphy_write(ch,
4469 ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004470 dataL | 0x00020000);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004471 reg_ddrphy_write(ch,
4472 ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004473 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004474 reg_ddrphy_write(ch,
4475 ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004476 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004477 reg_ddrphy_write(ch,
4478 ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004479 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004480 reg_ddrphy_write(ch,
4481 ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
Marek Vasut6c245a52018-12-12 18:06:39 +01004482 dataL);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004483 }
4484 }
4485}
4486
4487void pvtcode_update2(void)
4488{
4489 uint32_t ch;
4490 foreach_vch(ch) {
4491 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_FDBK_TERM),
4492 tcal.init_cal[ch] | 0x00020000);
4493 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DATA_TERM),
4494 tcal.init_cal[ch]);
4495 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_DQS_TERM),
4496 tcal.init_cal[ch]);
4497 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_ADDR_TERM),
4498 tcal.init_cal[ch]);
4499 reg_ddrphy_write(ch, ddr_regdef_adr(_reg_PHY_PAD_CS_TERM),
4500 tcal.init_cal[ch]);
4501 }
4502}
4503
4504void ddr_padcal_tcompensate_getinit(uint32_t override)
4505{
4506 uint32_t ch;
4507 uint32_t dataL;
4508 uint32_t pvtp, pvtn;
4509
4510 tcal.init_temp = 0;
4511 for (ch = 0; ch < 4; ch++) {
4512 tcal.init_cal[ch] = 0;
4513 tcal.tcomp_cal[ch] = 0;
4514 }
4515
4516 foreach_vch(ch) {
4517 tcal.init_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4518 tcal.tcomp_cal[ch] = ddr_getval(ch, _reg_PHY_PAD_TERM_X[1]);
4519 }
4520
4521 if (!override) {
Marek Vasut6c245a52018-12-12 18:06:39 +01004522 dataL = mmio_read_32(THS1_TEMP);
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004523 if (dataL < 2800) {
4524 tcal.init_temp =
4525 (143 * (int32_t) dataL - 359000) / 1000;
4526 } else {
4527 tcal.init_temp =
4528 (121 * (int32_t) dataL - 296300) / 1000;
4529 }
4530
4531 foreach_vch(ch) {
4532 pvtp = (tcal.init_cal[ch] >> 0) & 0x000003F;
4533 pvtn = (tcal.init_cal[ch] >> 6) & 0x000003F;
4534 if ((int32_t) pvtp >
4535 ((tcal.init_temp * 29 - 3625) / 1000))
4536 pvtp =
4537 (int32_t) pvtp +
4538 ((3625 - tcal.init_temp * 29) / 1000);
4539 else
4540 pvtp = 0;
4541
4542 if ((int32_t) pvtn >
4543 ((tcal.init_temp * 54 - 6750) / 1000))
4544 pvtn =
4545 (int32_t) pvtn +
4546 ((6750 - tcal.init_temp * 54) / 1000);
4547 else
4548 pvtn = 0;
4549
4550 if ((Prr_Product == PRR_PRODUCT_H3)
4551 && (Prr_Cut <= PRR_PRODUCT_11)) {
4552 tcal.init_cal[ch] =
4553 (tcal.
4554 init_cal[ch] & 0xfffff000) | (pvtn << 6) |
4555 (pvtp);
4556 } else {
4557 tcal.init_cal[ch] =
4558 0x00015000 | (pvtn << 6) | (pvtp);
4559 }
4560 }
4561 tcal.init_temp = 125;
4562 }
4563}
4564
4565#ifndef ddr_qos_init_setting
4566/* for QoS init */
4567uint8_t get_boardcnf_phyvalid(void)
4568{
Jorge Ramirez-Ortiz47503d22018-09-23 09:36:52 +02004569 return ddr_phyvalid;
4570}
4571#endif /* ddr_qos_init_setting */
4572
4573/*******************************************************************************
4574 * END
4575 ******************************************************************************/