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