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