xref: /OK3568_Linux_fs/u-boot/drivers/ram/rockchip/sdram_rv1126.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * (C) Copyright 2020 Rockchip Electronics Co., Ltd.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun #include <debug_uart.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <ram.h>
10*4882a593Smuzhiyun #include <syscon.h>
11*4882a593Smuzhiyun #include <asm/io.h>
12*4882a593Smuzhiyun #include <asm/arch/clock.h>
13*4882a593Smuzhiyun #include <asm/arch/hardware.h>
14*4882a593Smuzhiyun #include <asm/arch/rk_atags.h>
15*4882a593Smuzhiyun #include <asm/arch/cru_rv1126.h>
16*4882a593Smuzhiyun #include <asm/arch/grf_rv1126.h>
17*4882a593Smuzhiyun #include <asm/arch/sdram_common.h>
18*4882a593Smuzhiyun #include <asm/arch/sdram_rv1126.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* define training flag */
21*4882a593Smuzhiyun #define CA_TRAINING			(0x1 << 0)
22*4882a593Smuzhiyun #define READ_GATE_TRAINING		(0x1 << 1)
23*4882a593Smuzhiyun #define WRITE_LEVELING			(0x1 << 2)
24*4882a593Smuzhiyun #define WRITE_TRAINING			(0x1 << 3)
25*4882a593Smuzhiyun #define READ_TRAINING			(0x1 << 4)
26*4882a593Smuzhiyun #define FULL_TRAINING			(0xff)
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define SKEW_RX_SIGNAL			(0)
29*4882a593Smuzhiyun #define SKEW_TX_SIGNAL			(1)
30*4882a593Smuzhiyun #define SKEW_CA_SIGNAL			(2)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define DESKEW_MDF_ABS_VAL		(0)
33*4882a593Smuzhiyun #define DESKEW_MDF_DIFF_VAL		(1)
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef CONFIG_TPL_BUILD
36*4882a593Smuzhiyun #ifndef CONFIG_TPL_TINY_FRAMEWORK
37*4882a593Smuzhiyun #error please defined CONFIG_TPL_TINY_FRAMEWORK for RV1126 !!!
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #ifdef CONFIG_TPL_BUILD
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun struct dram_info {
44*4882a593Smuzhiyun 	void __iomem *pctl;
45*4882a593Smuzhiyun 	void __iomem *phy;
46*4882a593Smuzhiyun 	struct rv1126_cru *cru;
47*4882a593Smuzhiyun 	struct msch_regs *msch;
48*4882a593Smuzhiyun 	struct rv1126_ddrgrf *ddrgrf;
49*4882a593Smuzhiyun 	struct rv1126_grf *grf;
50*4882a593Smuzhiyun 	struct ram_info info;
51*4882a593Smuzhiyun 	struct rv1126_pmugrf *pmugrf;
52*4882a593Smuzhiyun 	u32 sr_idle;
53*4882a593Smuzhiyun 	u32 pd_idle;
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define GRF_BASE_ADDR			0xfe000000
57*4882a593Smuzhiyun #define PMU_GRF_BASE_ADDR		0xfe020000
58*4882a593Smuzhiyun #define DDR_GRF_BASE_ADDR		0xfe030000
59*4882a593Smuzhiyun #define BUS_SGRF_BASE_ADDR		0xfe0a0000
60*4882a593Smuzhiyun #define SERVER_MSCH_BASE_ADDR		0xfe800000
61*4882a593Smuzhiyun #define CRU_BASE_ADDR			0xff490000
62*4882a593Smuzhiyun #define DDR_PHY_BASE_ADDR		0xff4a0000
63*4882a593Smuzhiyun #define UPCTL2_BASE_ADDR		0xffa50000
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define SGRF_SOC_CON2			0x8
66*4882a593Smuzhiyun #define SGRF_SOC_CON12			0x30
67*4882a593Smuzhiyun #define SGRF_SOC_CON13			0x34
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun struct dram_info dram_info;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #if (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 3)
72*4882a593Smuzhiyun struct rv1126_sdram_params sdram_configs[] = {
73*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-328.inc"
74*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-396.inc"
75*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-528.inc"
76*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-664.inc"
77*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-784.inc"
78*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-924.inc"
79*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr3-detect-1056.inc"
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun #elif (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 0)
82*4882a593Smuzhiyun struct rv1126_sdram_params sdram_configs[] = {
83*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-328.inc"
84*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-396.inc"
85*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-528.inc"
86*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-664.inc"
87*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-784.inc"
88*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-924.inc"
89*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-ddr4-detect-1056.inc"
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun #elif (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 6)
92*4882a593Smuzhiyun struct rv1126_sdram_params sdram_configs[] = {
93*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-328.inc"
94*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-396.inc"
95*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-528.inc"
96*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-664.inc"
97*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-784.inc"
98*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-924.inc"
99*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr3-detect-1056.inc"
100*4882a593Smuzhiyun };
101*4882a593Smuzhiyun #elif (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 7) || (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 8)
102*4882a593Smuzhiyun struct rv1126_sdram_params sdram_configs[] = {
103*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-328.inc"
104*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-396.inc"
105*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-528.inc"
106*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-664.inc"
107*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-784.inc"
108*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-924.inc"
109*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-lpddr4-detect-1056.inc"
110*4882a593Smuzhiyun };
111*4882a593Smuzhiyun #endif
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun u32 common_info[] = {
114*4882a593Smuzhiyun 	#include "sdram_inc/rv1126/sdram-rv1126-loader_params.inc"
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
118*4882a593Smuzhiyun static struct rw_trn_result rw_trn_result;
119*4882a593Smuzhiyun #endif
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun static struct rv1126_fsp_param fsp_param[MAX_IDX];
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun static u8 lp3_odt_value;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun static s8 wrlvl_result[2][4];
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* DDR configuration 0-9 */
128*4882a593Smuzhiyun u16 ddr_cfg_2_rbc[] = {
129*4882a593Smuzhiyun 	((0 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 3), /* 0 */
130*4882a593Smuzhiyun 	((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 2), /* 1 */
131*4882a593Smuzhiyun 	((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 3), /* 2 */
132*4882a593Smuzhiyun 	((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 1), /* 3 */
133*4882a593Smuzhiyun 	((0 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 4), /* 4 */
134*4882a593Smuzhiyun 	((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 1), /* 5 */
135*4882a593Smuzhiyun 	((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 2), /* 6 */
136*4882a593Smuzhiyun 	((0 << 8) | (2 << 5) | (1 << 4) | (1 << 3) | 3), /* 7 */
137*4882a593Smuzhiyun 	((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 2), /* 8 */
138*4882a593Smuzhiyun 	((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 2) /* 9 */
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /* DDR configuration 10-21 */
142*4882a593Smuzhiyun u8 ddr4_cfg_2_rbc[] = {
143*4882a593Smuzhiyun 	((0 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 0), /* 10 */
144*4882a593Smuzhiyun 	((1 << 7) | (2 << 4) | (0 << 3) | (2 << 1) | 0), /* 11 */
145*4882a593Smuzhiyun 	((0 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 0), /* 12 */
146*4882a593Smuzhiyun 	((1 << 7) | (3 << 4) | (0 << 3) | (1 << 1) | 0), /* 13 */
147*4882a593Smuzhiyun 	((0 << 7) | (4 << 4) | (0 << 3) | (2 << 1) | 1), /* 14 */
148*4882a593Smuzhiyun 	((1 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 1), /* 15 */
149*4882a593Smuzhiyun 	((1 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 1), /* 16 */
150*4882a593Smuzhiyun 	((0 << 7) | (2 << 4) | (1 << 3) | (2 << 1) | 0), /* 17 */
151*4882a593Smuzhiyun 	((0 << 7) | (3 << 4) | (1 << 3) | (1 << 1) | 0), /* 18 */
152*4882a593Smuzhiyun 	((0 << 7) | (3 << 4) | (1 << 3) | (2 << 1) | 1), /* 19 */
153*4882a593Smuzhiyun 	((0 << 7) | (4 << 4) | (1 << 3) | (1 << 1) | 1), /* 20 */
154*4882a593Smuzhiyun 	((1 << 7) | (4 << 4) | (0 << 3) | (0 << 1) | 0) /* 21 */
155*4882a593Smuzhiyun };
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /* DDR configuration 22-28 */
158*4882a593Smuzhiyun u16 ddr_cfg_2_rbc_p2[] = {
159*4882a593Smuzhiyun 	((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 0), /* 22 */
160*4882a593Smuzhiyun 	((0 << 8) | (4 << 5) | (0 << 4) | (1 << 3) | 2), /* 23 */
161*4882a593Smuzhiyun 	((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 3), /* 24 */
162*4882a593Smuzhiyun 	((0 << 8) | (3 << 5) | (1 << 4) | (0 << 3) | 3), /* 25 */
163*4882a593Smuzhiyun 	((0 << 8) | (4 << 5) | (1 << 4) | (0 << 3) | 2), /* 26 */
164*4882a593Smuzhiyun 	((1 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 2), /* 27 */
165*4882a593Smuzhiyun 	((0 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 3) /* 28 */
166*4882a593Smuzhiyun };
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun u8 d4_rbc_2_d3_rbc[][2] = {
169*4882a593Smuzhiyun 	{10, 0},
170*4882a593Smuzhiyun 	{11, 2},
171*4882a593Smuzhiyun 	{12, 23},
172*4882a593Smuzhiyun 	{13, 1},
173*4882a593Smuzhiyun 	{14, 28},
174*4882a593Smuzhiyun 	{15, 24},
175*4882a593Smuzhiyun 	{16, 27},
176*4882a593Smuzhiyun 	{17, 7},
177*4882a593Smuzhiyun 	{18, 6},
178*4882a593Smuzhiyun 	{19, 25},
179*4882a593Smuzhiyun 	{20, 26},
180*4882a593Smuzhiyun 	{21, 3}
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun u32 addrmap[29][9] = {
184*4882a593Smuzhiyun 	{24, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
185*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x3f3f}, /* 0 */
186*4882a593Smuzhiyun 	{23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
187*4882a593Smuzhiyun 		0x07070707, 0x00000f0f, 0x3f3f}, /* 1 */
188*4882a593Smuzhiyun 	{23, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
189*4882a593Smuzhiyun 		0x0f080808, 0x00000f0f, 0x3f3f}, /* 2 */
190*4882a593Smuzhiyun 	{22, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
191*4882a593Smuzhiyun 		0x06060606, 0x00000f0f, 0x3f3f}, /* 3 */
192*4882a593Smuzhiyun 	{24, 0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
193*4882a593Smuzhiyun 		0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
194*4882a593Smuzhiyun 	{6, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x07070707,
195*4882a593Smuzhiyun 		0x07070707, 0x00000f0f, 0x3f3f}, /* 5 */
196*4882a593Smuzhiyun 	{7, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x08080808,
197*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x3f3f}, /* 6 */
198*4882a593Smuzhiyun 	{8, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x09090909,
199*4882a593Smuzhiyun 		0x0f090909, 0x00000f0f, 0x3f3f}, /* 7 */
200*4882a593Smuzhiyun 	{22, 0x001f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
201*4882a593Smuzhiyun 		0x06060606, 0x00000f0f, 0x3f3f}, /* 8 */
202*4882a593Smuzhiyun 	{23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
203*4882a593Smuzhiyun 		0x0f070707, 0x00000f0f, 0x3f3f}, /* 9 */
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	{24, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
206*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x0801}, /* 10 */
207*4882a593Smuzhiyun 	{23, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
208*4882a593Smuzhiyun 		0x0f080808, 0x00000f0f, 0x0801}, /* 11 */
209*4882a593Smuzhiyun 	{24, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
210*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x0700}, /* 12 */
211*4882a593Smuzhiyun 	{23, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
212*4882a593Smuzhiyun 		0x07070707, 0x00000f0f, 0x0700}, /* 13 */
213*4882a593Smuzhiyun 	{24, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
214*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x3f01}, /* 14 */
215*4882a593Smuzhiyun 	{23, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
216*4882a593Smuzhiyun 		0x07070707, 0x00000f0f, 0x3f01}, /* 15 */
217*4882a593Smuzhiyun 	{23, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
218*4882a593Smuzhiyun 		0x06060606, 0x00000f06, 0x3f00}, /* 16 */
219*4882a593Smuzhiyun 	{8, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x09090909,
220*4882a593Smuzhiyun 		0x0f090909, 0x00000f0f, 0x0801}, /* 17 */
221*4882a593Smuzhiyun 	{7, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x08080808,
222*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x0700}, /* 18 */
223*4882a593Smuzhiyun 	{7, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
224*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x3f01}, /* 19 */
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	{6, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
227*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x3f00}, /* 20 */
228*4882a593Smuzhiyun 	{23, 0x003f0909, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
229*4882a593Smuzhiyun 		0x06060606, 0x00000f06, 0x0600}, /* 21 */
230*4882a593Smuzhiyun 	{21, 0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
231*4882a593Smuzhiyun 		0x05050505, 0x00000f0f, 0x3f3f}, /* 22 */
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	{24, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
234*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x3f3f}, /* 23 */
235*4882a593Smuzhiyun 	{23, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707,
236*4882a593Smuzhiyun 		0x07070707, 0x00000f0f, 0x3f3f}, /* 24 */
237*4882a593Smuzhiyun 	{7, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
238*4882a593Smuzhiyun 		0x08080808, 0x00000f0f, 0x3f3f}, /* 25 */
239*4882a593Smuzhiyun 	{6, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
240*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x3f3f}, /* 26 */
241*4882a593Smuzhiyun 	{23, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
242*4882a593Smuzhiyun 		0x06060606, 0x00000f06, 0x3f3f}, /* 27 */
243*4882a593Smuzhiyun 	{24, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707,
244*4882a593Smuzhiyun 		0x07070707, 0x00000f07, 0x3f3f} /* 28 */
245*4882a593Smuzhiyun };
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun static u8 dq_sel[22][3] = {
248*4882a593Smuzhiyun 	{0x0, 0x17, 0x22},
249*4882a593Smuzhiyun 	{0x1, 0x18, 0x23},
250*4882a593Smuzhiyun 	{0x2, 0x19, 0x24},
251*4882a593Smuzhiyun 	{0x3, 0x1a, 0x25},
252*4882a593Smuzhiyun 	{0x4, 0x1b, 0x26},
253*4882a593Smuzhiyun 	{0x5, 0x1c, 0x27},
254*4882a593Smuzhiyun 	{0x6, 0x1d, 0x28},
255*4882a593Smuzhiyun 	{0x7, 0x1e, 0x29},
256*4882a593Smuzhiyun 	{0x8, 0x16, 0x21},
257*4882a593Smuzhiyun 	{0x9, 0x1f, 0x2a},
258*4882a593Smuzhiyun 	{0xa, 0x20, 0x2b},
259*4882a593Smuzhiyun 	{0x10, 0x1, 0xc},
260*4882a593Smuzhiyun 	{0x11, 0x2, 0xd},
261*4882a593Smuzhiyun 	{0x12, 0x3, 0xe},
262*4882a593Smuzhiyun 	{0x13, 0x4, 0xf},
263*4882a593Smuzhiyun 	{0x14, 0x5, 0x10},
264*4882a593Smuzhiyun 	{0x15, 0x6, 0x11},
265*4882a593Smuzhiyun 	{0x16, 0x7, 0x12},
266*4882a593Smuzhiyun 	{0x17, 0x8, 0x13},
267*4882a593Smuzhiyun 	{0x18, 0x0, 0xb},
268*4882a593Smuzhiyun 	{0x19, 0x9, 0x14},
269*4882a593Smuzhiyun 	{0x1a, 0xa, 0x15}
270*4882a593Smuzhiyun };
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun static u16 grp_addr[4] = {
273*4882a593Smuzhiyun 	ADD_GROUP_CS0_A,
274*4882a593Smuzhiyun 	ADD_GROUP_CS0_B,
275*4882a593Smuzhiyun 	ADD_GROUP_CS1_A,
276*4882a593Smuzhiyun 	ADD_GROUP_CS1_B
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun static u8 wrlvl_result_offset[2][4] = {
280*4882a593Smuzhiyun 	{0xa0 + 0x26, 0xa0 + 0x27, 0xd0 + 0x26, 0xd0 + 0x27},
281*4882a593Smuzhiyun 	{0xa0 + 0x28, 0xa0 + 0x29, 0xd0 + 0x28, 0xd0 + 0x29},
282*4882a593Smuzhiyun };
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun static u16 dqs_dq_skew_adr[16] = {
285*4882a593Smuzhiyun 	0x170 + 0,	/* SKEW_UPDATE_RX_CS0_DQS0 */
286*4882a593Smuzhiyun 	0x170 + 0xb,	/* SKEW_UPDATE_RX_CS0_DQS1 */
287*4882a593Smuzhiyun 	0x1d0 + 0,	/* SKEW_UPDATE_RX_CS0_DQS2 */
288*4882a593Smuzhiyun 	0x1d0 + 0xb,	/* SKEW_UPDATE_RX_CS0_DQS3 */
289*4882a593Smuzhiyun 	0x1a0 + 0,	/* SKEW_UPDATE_RX_CS1_DQS0 */
290*4882a593Smuzhiyun 	0x1a0 + 0xb,	/* SKEW_UPDATE_RX_CS1_DQS1 */
291*4882a593Smuzhiyun 	0x200 + 0,	/* SKEW_UPDATE_RX_CS1_DQS2 */
292*4882a593Smuzhiyun 	0x200 + 0xb,	/* SKEW_UPDATE_RX_CS1_DQS3 */
293*4882a593Smuzhiyun 	0x170 + 0x16,	/* SKEW_UPDATE_TX_CS0_DQS0 */
294*4882a593Smuzhiyun 	0x170 + 0x21,	/* SKEW_UPDATE_TX_CS0_DQS1 */
295*4882a593Smuzhiyun 	0x1d0 + 0x16,	/* SKEW_UPDATE_TX_CS0_DQS2 */
296*4882a593Smuzhiyun 	0x1d0 + 0x21,	/* SKEW_UPDATE_TX_CS0_DQS3 */
297*4882a593Smuzhiyun 	0x1a0 + 0x16,	/* SKEW_UPDATE_TX_CS1_DQS0 */
298*4882a593Smuzhiyun 	0x1a0 + 0x21,	/* SKEW_UPDATE_TX_CS1_DQS1 */
299*4882a593Smuzhiyun 	0x200 + 0x16,	/* SKEW_UPDATE_TX_CS1_DQS2 */
300*4882a593Smuzhiyun 	0x200 + 0x21,	/* SKEW_UPDATE_TX_CS1_DQS3 */
301*4882a593Smuzhiyun };
302*4882a593Smuzhiyun 
rkclk_ddr_reset(struct dram_info * dram,u32 ctl_srstn,u32 ctl_psrstn,u32 phy_srstn,u32 phy_psrstn)303*4882a593Smuzhiyun static void rkclk_ddr_reset(struct dram_info *dram,
304*4882a593Smuzhiyun 			    u32 ctl_srstn, u32 ctl_psrstn,
305*4882a593Smuzhiyun 			    u32 phy_srstn, u32 phy_psrstn)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	writel(UPCTL2_SRSTN_REQ(ctl_srstn) | UPCTL2_PSRSTN_REQ(ctl_psrstn) |
308*4882a593Smuzhiyun 	       UPCTL2_ASRSTN_REQ(ctl_srstn),
309*4882a593Smuzhiyun 	       BUS_SGRF_BASE_ADDR + SGRF_SOC_CON13);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	writel(DDRPHY_SRSTN_REQ(phy_srstn) | DDRPHY_PSRSTN_REQ(phy_psrstn),
312*4882a593Smuzhiyun 	       &dram->cru->softrst_con[12]);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
rkclk_set_dpll(struct dram_info * dram,unsigned int hz)315*4882a593Smuzhiyun static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
318*4882a593Smuzhiyun 	int delay = 1000;
319*4882a593Smuzhiyun 	u32 mhz = hz / MHz;
320*4882a593Smuzhiyun 	struct global_info *gbl_info;
321*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
322*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
323*4882a593Smuzhiyun 	u32 ssmod_info;
324*4882a593Smuzhiyun 	u32 dsmpd = 1;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	gbl_info = (struct global_info *)((void *)common_info +
327*4882a593Smuzhiyun 		    index->global_index.offset * 4);
328*4882a593Smuzhiyun 	ssmod_info = gbl_info->info_2t;
329*4882a593Smuzhiyun 	refdiv = 1;
330*4882a593Smuzhiyun 	if (mhz <= 100) {
331*4882a593Smuzhiyun 		postdiv1 = 6;
332*4882a593Smuzhiyun 		postdiv2 = 4;
333*4882a593Smuzhiyun 	} else if (mhz <= 150) {
334*4882a593Smuzhiyun 		postdiv1 = 4;
335*4882a593Smuzhiyun 		postdiv2 = 4;
336*4882a593Smuzhiyun 	} else if (mhz <= 200) {
337*4882a593Smuzhiyun 		postdiv1 = 6;
338*4882a593Smuzhiyun 		postdiv2 = 2;
339*4882a593Smuzhiyun 	} else if (mhz <= 300) {
340*4882a593Smuzhiyun 		postdiv1 = 4;
341*4882a593Smuzhiyun 		postdiv2 = 2;
342*4882a593Smuzhiyun 	} else if (mhz <= 400) {
343*4882a593Smuzhiyun 		postdiv1 = 6;
344*4882a593Smuzhiyun 		postdiv2 = 1;
345*4882a593Smuzhiyun 	} else {
346*4882a593Smuzhiyun 		postdiv1 = 4;
347*4882a593Smuzhiyun 		postdiv2 = 1;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 	fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	writel(0x1f000000, &dram->cru->clksel_con[64]);
354*4882a593Smuzhiyun 	writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
355*4882a593Smuzhiyun 	/* enable ssmod */
356*4882a593Smuzhiyun 	if (PLL_SSMOD_SPREAD(ssmod_info)) {
357*4882a593Smuzhiyun 		dsmpd = 0;
358*4882a593Smuzhiyun 		clrsetbits_le32(&dram->cru->pll[1].con2,
359*4882a593Smuzhiyun 				0xffffff << 0, 0x0 << 0);
360*4882a593Smuzhiyun 		writel(SSMOD_SPREAD(PLL_SSMOD_SPREAD(ssmod_info)) |
361*4882a593Smuzhiyun 		       SSMOD_DIVVAL(PLL_SSMOD_DIV(ssmod_info)) |
362*4882a593Smuzhiyun 		       SSMOD_DOWNSPREAD(PLL_SSMOD_DOWNSPREAD(ssmod_info)) |
363*4882a593Smuzhiyun 		       SSMOD_RESET(0) |
364*4882a593Smuzhiyun 		       SSMOD_DIS_SSCG(0) |
365*4882a593Smuzhiyun 		       SSMOD_BP(0),
366*4882a593Smuzhiyun 		       &dram->cru->pll[1].con3);
367*4882a593Smuzhiyun 	}
368*4882a593Smuzhiyun 	writel(DSMPD(dsmpd) | POSTDIV2(postdiv2) | REFDIV(refdiv),
369*4882a593Smuzhiyun 	       &dram->cru->pll[1].con1);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	while (delay > 0) {
372*4882a593Smuzhiyun 		udelay(1);
373*4882a593Smuzhiyun 		if (LOCK(readl(&dram->cru->pll[1].con1)))
374*4882a593Smuzhiyun 			break;
375*4882a593Smuzhiyun 		delay--;
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 	if (delay <= 0)
378*4882a593Smuzhiyun 		printascii("ERROR: DPLL lock timeout!\n");
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
rkclk_configure_ddr(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)383*4882a593Smuzhiyun static void rkclk_configure_ddr(struct dram_info *dram,
384*4882a593Smuzhiyun 				struct rv1126_sdram_params *sdram_params)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	/* for inno ddr phy need freq / 2 */
387*4882a593Smuzhiyun 	rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ / 2);
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun static unsigned int
calculate_ddrconfig(struct rv1126_sdram_params * sdram_params)391*4882a593Smuzhiyun 	calculate_ddrconfig(struct rv1126_sdram_params *sdram_params)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
394*4882a593Smuzhiyun 	u32 cs, bw, die_bw, col, row, bank;
395*4882a593Smuzhiyun 	u32 cs1_row;
396*4882a593Smuzhiyun 	u32 i, tmp;
397*4882a593Smuzhiyun 	u32 ddrconf = -1;
398*4882a593Smuzhiyun 	u32 row_3_4;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	cs = cap_info->rank;
401*4882a593Smuzhiyun 	bw = cap_info->bw;
402*4882a593Smuzhiyun 	die_bw = cap_info->dbw;
403*4882a593Smuzhiyun 	col = cap_info->col;
404*4882a593Smuzhiyun 	row = cap_info->cs0_row;
405*4882a593Smuzhiyun 	cs1_row = cap_info->cs1_row;
406*4882a593Smuzhiyun 	bank = cap_info->bk;
407*4882a593Smuzhiyun 	row_3_4 = cap_info->row_3_4;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4) {
410*4882a593Smuzhiyun 		if (cs == 2 && row == cs1_row && !row_3_4) {
411*4882a593Smuzhiyun 			tmp = ((row - 13) << 4) | (1 << 3) | (bw << 1) |
412*4882a593Smuzhiyun 			      die_bw;
413*4882a593Smuzhiyun 			for (i = 17; i < 21; i++) {
414*4882a593Smuzhiyun 				if (((tmp & 0xf) ==
415*4882a593Smuzhiyun 				     (ddr4_cfg_2_rbc[i - 10] & 0xf)) &&
416*4882a593Smuzhiyun 				    ((tmp & 0x70) <=
417*4882a593Smuzhiyun 				     (ddr4_cfg_2_rbc[i - 10] & 0x70))) {
418*4882a593Smuzhiyun 					ddrconf = i;
419*4882a593Smuzhiyun 					goto out;
420*4882a593Smuzhiyun 				}
421*4882a593Smuzhiyun 			}
422*4882a593Smuzhiyun 		}
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 		tmp = ((cs - 1) << 7) | ((row - 13) << 4) | (bw << 1) | die_bw;
425*4882a593Smuzhiyun 		for (i = 10; i < 21; i++) {
426*4882a593Smuzhiyun 			if (((tmp & 0xf) == (ddr4_cfg_2_rbc[i - 10] & 0xf)) &&
427*4882a593Smuzhiyun 			    ((tmp & 0x70) <= (ddr4_cfg_2_rbc[i - 10] & 0x70)) &&
428*4882a593Smuzhiyun 			    ((tmp & 0x80) <= (ddr4_cfg_2_rbc[i - 10] & 0x80))) {
429*4882a593Smuzhiyun 				ddrconf = i;
430*4882a593Smuzhiyun 				goto out;
431*4882a593Smuzhiyun 			}
432*4882a593Smuzhiyun 		}
433*4882a593Smuzhiyun 	} else {
434*4882a593Smuzhiyun 		if (cs == 2 && row == cs1_row && bank == 3) {
435*4882a593Smuzhiyun 			for (i = 5; i < 8; i++) {
436*4882a593Smuzhiyun 				if (((bw + col - 10) == (ddr_cfg_2_rbc[i] &
437*4882a593Smuzhiyun 							 0x7)) &&
438*4882a593Smuzhiyun 				    ((row - 13) << 5) <= (ddr_cfg_2_rbc[i] &
439*4882a593Smuzhiyun 							  (0x7 << 5))) {
440*4882a593Smuzhiyun 					ddrconf = i;
441*4882a593Smuzhiyun 					goto out;
442*4882a593Smuzhiyun 				}
443*4882a593Smuzhiyun 			}
444*4882a593Smuzhiyun 		}
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 		tmp = ((cs - 1) << 8) | ((row - 13) << 5) |
447*4882a593Smuzhiyun 		      ((bw + col - 10) << 0);
448*4882a593Smuzhiyun 		if (bank == 3)
449*4882a593Smuzhiyun 			tmp |= (1 << 3);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 		for (i = 0; i < 9; i++)
452*4882a593Smuzhiyun 			if (((tmp & 0x1f) == (ddr_cfg_2_rbc[i] & 0x1f)) &&
453*4882a593Smuzhiyun 			    ((tmp & (7 << 5)) <=
454*4882a593Smuzhiyun 			     (ddr_cfg_2_rbc[i] & (7 << 5))) &&
455*4882a593Smuzhiyun 			    ((tmp & (1 << 8)) <=
456*4882a593Smuzhiyun 			     (ddr_cfg_2_rbc[i] & (1 << 8)))) {
457*4882a593Smuzhiyun 				ddrconf = i;
458*4882a593Smuzhiyun 				goto out;
459*4882a593Smuzhiyun 			}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 		for (i = 0; i < 7; i++)
462*4882a593Smuzhiyun 			if (((tmp & 0x1f) == (ddr_cfg_2_rbc_p2[i] & 0x1f)) &&
463*4882a593Smuzhiyun 			    ((tmp & (7 << 5)) <=
464*4882a593Smuzhiyun 			     (ddr_cfg_2_rbc_p2[i] & (7 << 5))) &&
465*4882a593Smuzhiyun 			    ((tmp & (1 << 8)) <=
466*4882a593Smuzhiyun 			     (ddr_cfg_2_rbc_p2[i] & (1 << 8)))) {
467*4882a593Smuzhiyun 				ddrconf = i + 22;
468*4882a593Smuzhiyun 				goto out;
469*4882a593Smuzhiyun 			}
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 		if (cs == 1 && bank == 3 && row <= 17 &&
472*4882a593Smuzhiyun 		    (col + bw) == 12)
473*4882a593Smuzhiyun 			ddrconf = 23;
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun out:
477*4882a593Smuzhiyun 	if (ddrconf > 28)
478*4882a593Smuzhiyun 		printascii("calculate ddrconfig error\n");
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4) {
481*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) {
482*4882a593Smuzhiyun 			if (ddrconf == d4_rbc_2_d3_rbc[i][0]) {
483*4882a593Smuzhiyun 				if (ddrconf == 21 && row > 16)
484*4882a593Smuzhiyun 					printascii("warn:ddrconf21 row > 16\n");
485*4882a593Smuzhiyun 				else
486*4882a593Smuzhiyun 					ddrconf = d4_rbc_2_d3_rbc[i][1];
487*4882a593Smuzhiyun 				break;
488*4882a593Smuzhiyun 			}
489*4882a593Smuzhiyun 		}
490*4882a593Smuzhiyun 	}
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	return ddrconf;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun 
sw_set_req(struct dram_info * dram)495*4882a593Smuzhiyun static void sw_set_req(struct dram_info *dram)
496*4882a593Smuzhiyun {
497*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	/* clear sw_done=0 */
500*4882a593Smuzhiyun 	writel(PCTL2_SW_DONE_CLEAR, pctl_base + DDR_PCTL2_SWCTL);
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
sw_set_ack(struct dram_info * dram)503*4882a593Smuzhiyun static void sw_set_ack(struct dram_info *dram)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	/* set sw_done=1 */
508*4882a593Smuzhiyun 	writel(PCTL2_SW_DONE, pctl_base + DDR_PCTL2_SWCTL);
509*4882a593Smuzhiyun 	while (1) {
510*4882a593Smuzhiyun 		/* wait programming done */
511*4882a593Smuzhiyun 		if (readl(pctl_base + DDR_PCTL2_SWSTAT) &
512*4882a593Smuzhiyun 				PCTL2_SW_DONE_ACK)
513*4882a593Smuzhiyun 			break;
514*4882a593Smuzhiyun 	}
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun 
set_ctl_address_map(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)517*4882a593Smuzhiyun static void set_ctl_address_map(struct dram_info *dram,
518*4882a593Smuzhiyun 				struct rv1126_sdram_params *sdram_params)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
521*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
522*4882a593Smuzhiyun 	u32 ddrconf = cap_info->ddrconfig;
523*4882a593Smuzhiyun 	u32 i, row;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	row = cap_info->cs0_row;
526*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4) {
527*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) {
528*4882a593Smuzhiyun 			if (ddrconf == d4_rbc_2_d3_rbc[i][1]) {
529*4882a593Smuzhiyun 				ddrconf = d4_rbc_2_d3_rbc[i][0];
530*4882a593Smuzhiyun 				break;
531*4882a593Smuzhiyun 			}
532*4882a593Smuzhiyun 		}
533*4882a593Smuzhiyun 	}
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	if (ddrconf >= ARRAY_SIZE(addrmap)) {
536*4882a593Smuzhiyun 		printascii("set ctl address map fail\n");
537*4882a593Smuzhiyun 		return;
538*4882a593Smuzhiyun 	}
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
541*4882a593Smuzhiyun 			  &addrmap[ddrconf][0], ARRAY_SIZE(addrmap[ddrconf]) * 4);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	/* unused row set to 0xf */
544*4882a593Smuzhiyun 	for (i = 17; i >= row; i--)
545*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
546*4882a593Smuzhiyun 			((i - 12) * 8 / 32) * 4,
547*4882a593Smuzhiyun 			0xf << ((i - 12) * 8 % 32));
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
550*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
551*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
552*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	if (cap_info->rank == 1)
555*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun 
phy_pll_set(struct dram_info * dram,u32 freq,u32 wait)558*4882a593Smuzhiyun static void phy_pll_set(struct dram_info *dram, u32 freq, u32 wait)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
561*4882a593Smuzhiyun 	u32 fbdiv, prediv, postdiv, postdiv_en;
562*4882a593Smuzhiyun 	int delay = 1000;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	if (wait) {
565*4882a593Smuzhiyun 		clrbits_le32(PHY_REG(phy_base, 0x53), PHY_PD_DISB);
566*4882a593Smuzhiyun 		while (!(readl(PHY_REG(phy_base, 0x90)) & PHY_PLL_LOCK)) {
567*4882a593Smuzhiyun 			udelay(1);
568*4882a593Smuzhiyun 			if (delay-- <= 0) {
569*4882a593Smuzhiyun 				printascii("ERROR: phy pll lock timeout!\n");
570*4882a593Smuzhiyun 				while (1)
571*4882a593Smuzhiyun 					;
572*4882a593Smuzhiyun 			}
573*4882a593Smuzhiyun 		}
574*4882a593Smuzhiyun 	} else {
575*4882a593Smuzhiyun 		freq /= MHz;
576*4882a593Smuzhiyun 		prediv = 1;
577*4882a593Smuzhiyun 		if (freq <= 200) {
578*4882a593Smuzhiyun 			fbdiv = 16;
579*4882a593Smuzhiyun 			postdiv = 2;
580*4882a593Smuzhiyun 			postdiv_en = 1;
581*4882a593Smuzhiyun 		} else if (freq <= 456) {
582*4882a593Smuzhiyun 			fbdiv = 8;
583*4882a593Smuzhiyun 			postdiv = 1;
584*4882a593Smuzhiyun 			postdiv_en = 1;
585*4882a593Smuzhiyun 		} else {
586*4882a593Smuzhiyun 			fbdiv = 4;
587*4882a593Smuzhiyun 			postdiv = 0;
588*4882a593Smuzhiyun 			postdiv_en = 0;
589*4882a593Smuzhiyun 		}
590*4882a593Smuzhiyun 		writel(fbdiv & 0xff, PHY_REG(phy_base, 0x50));
591*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_PBDIV_BIT9_MASK,
592*4882a593Smuzhiyun 				(fbdiv >> 8) & 1);
593*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_POSTDIV_EN_MASK,
594*4882a593Smuzhiyun 				postdiv_en << PHY_POSTDIV_EN_SHIFT);
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x52),
597*4882a593Smuzhiyun 				PHY_PREDIV_MASK << PHY_PREDIV_SHIFT, prediv);
598*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x53),
599*4882a593Smuzhiyun 				PHY_POSTDIV_MASK << PHY_POSTDIV_SHIFT,
600*4882a593Smuzhiyun 				postdiv << PHY_POSTDIV_SHIFT);
601*4882a593Smuzhiyun 	}
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun static const u16 d3_phy_drv_2_ohm[][2] = {
605*4882a593Smuzhiyun 	{PHY_DDR3_RON_455ohm, 455},
606*4882a593Smuzhiyun 	{PHY_DDR3_RON_230ohm, 230},
607*4882a593Smuzhiyun 	{PHY_DDR3_RON_153ohm, 153},
608*4882a593Smuzhiyun 	{PHY_DDR3_RON_115ohm, 115},
609*4882a593Smuzhiyun 	{PHY_DDR3_RON_91ohm, 91},
610*4882a593Smuzhiyun 	{PHY_DDR3_RON_76ohm, 76},
611*4882a593Smuzhiyun 	{PHY_DDR3_RON_65ohm, 65},
612*4882a593Smuzhiyun 	{PHY_DDR3_RON_57ohm, 57},
613*4882a593Smuzhiyun 	{PHY_DDR3_RON_51ohm, 51},
614*4882a593Smuzhiyun 	{PHY_DDR3_RON_46ohm, 46},
615*4882a593Smuzhiyun 	{PHY_DDR3_RON_41ohm, 41},
616*4882a593Smuzhiyun 	{PHY_DDR3_RON_38ohm, 38},
617*4882a593Smuzhiyun 	{PHY_DDR3_RON_35ohm, 35},
618*4882a593Smuzhiyun 	{PHY_DDR3_RON_32ohm, 32},
619*4882a593Smuzhiyun 	{PHY_DDR3_RON_30ohm, 30},
620*4882a593Smuzhiyun 	{PHY_DDR3_RON_28ohm, 28},
621*4882a593Smuzhiyun 	{PHY_DDR3_RON_27ohm, 27},
622*4882a593Smuzhiyun 	{PHY_DDR3_RON_25ohm, 25},
623*4882a593Smuzhiyun 	{PHY_DDR3_RON_24ohm, 24},
624*4882a593Smuzhiyun 	{PHY_DDR3_RON_23ohm, 23},
625*4882a593Smuzhiyun 	{PHY_DDR3_RON_22ohm, 22},
626*4882a593Smuzhiyun 	{PHY_DDR3_RON_21ohm, 21},
627*4882a593Smuzhiyun 	{PHY_DDR3_RON_20ohm, 20}
628*4882a593Smuzhiyun };
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun static u16 d3_phy_odt_2_ohm[][2] = {
631*4882a593Smuzhiyun 	{PHY_DDR3_RTT_DISABLE, 0},
632*4882a593Smuzhiyun 	{PHY_DDR3_RTT_561ohm, 561},
633*4882a593Smuzhiyun 	{PHY_DDR3_RTT_282ohm, 282},
634*4882a593Smuzhiyun 	{PHY_DDR3_RTT_188ohm, 188},
635*4882a593Smuzhiyun 	{PHY_DDR3_RTT_141ohm, 141},
636*4882a593Smuzhiyun 	{PHY_DDR3_RTT_113ohm, 113},
637*4882a593Smuzhiyun 	{PHY_DDR3_RTT_94ohm, 94},
638*4882a593Smuzhiyun 	{PHY_DDR3_RTT_81ohm, 81},
639*4882a593Smuzhiyun 	{PHY_DDR3_RTT_72ohm, 72},
640*4882a593Smuzhiyun 	{PHY_DDR3_RTT_64ohm, 64},
641*4882a593Smuzhiyun 	{PHY_DDR3_RTT_58ohm, 58},
642*4882a593Smuzhiyun 	{PHY_DDR3_RTT_52ohm, 52},
643*4882a593Smuzhiyun 	{PHY_DDR3_RTT_48ohm, 48},
644*4882a593Smuzhiyun 	{PHY_DDR3_RTT_44ohm, 44},
645*4882a593Smuzhiyun 	{PHY_DDR3_RTT_41ohm, 41},
646*4882a593Smuzhiyun 	{PHY_DDR3_RTT_38ohm, 38},
647*4882a593Smuzhiyun 	{PHY_DDR3_RTT_37ohm, 37},
648*4882a593Smuzhiyun 	{PHY_DDR3_RTT_34ohm, 34},
649*4882a593Smuzhiyun 	{PHY_DDR3_RTT_32ohm, 32},
650*4882a593Smuzhiyun 	{PHY_DDR3_RTT_31ohm, 31},
651*4882a593Smuzhiyun 	{PHY_DDR3_RTT_29ohm, 29},
652*4882a593Smuzhiyun 	{PHY_DDR3_RTT_28ohm, 28},
653*4882a593Smuzhiyun 	{PHY_DDR3_RTT_27ohm, 27},
654*4882a593Smuzhiyun 	{PHY_DDR3_RTT_25ohm, 25}
655*4882a593Smuzhiyun };
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun static u16 d4lp3_phy_drv_2_ohm[][2] = {
658*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_482ohm, 482},
659*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_244ohm, 244},
660*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_162ohm, 162},
661*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_122ohm, 122},
662*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_97ohm, 97},
663*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_81ohm, 81},
664*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_69ohm, 69},
665*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_61ohm, 61},
666*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_54ohm, 54},
667*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_48ohm, 48},
668*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_44ohm, 44},
669*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_40ohm, 40},
670*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_37ohm, 37},
671*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_34ohm, 34},
672*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_32ohm, 32},
673*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_30ohm, 30},
674*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_28ohm, 28},
675*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_27ohm, 27},
676*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_25ohm, 25},
677*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_24ohm, 24},
678*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_23ohm, 23},
679*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_22ohm, 22},
680*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RON_21ohm, 21}
681*4882a593Smuzhiyun };
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun static u16 d4lp3_phy_odt_2_ohm[][2] = {
684*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_DISABLE, 0},
685*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_586ohm, 586},
686*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_294ohm, 294},
687*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_196ohm, 196},
688*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_148ohm, 148},
689*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_118ohm, 118},
690*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_99ohm, 99},
691*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_85ohm, 58},
692*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_76ohm, 76},
693*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_67ohm, 67},
694*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_60ohm, 60},
695*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_55ohm, 55},
696*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_50ohm, 50},
697*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_46ohm, 46},
698*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_43ohm, 43},
699*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_40ohm, 40},
700*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_38ohm, 38},
701*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_36ohm, 36},
702*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_34ohm, 34},
703*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_32ohm, 32},
704*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_31ohm, 31},
705*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_29ohm, 29},
706*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_28ohm, 28},
707*4882a593Smuzhiyun 	{PHY_DDR4_LPDDR3_RTT_27ohm, 27}
708*4882a593Smuzhiyun };
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun static u16 lp4_phy_drv_2_ohm[][2] = {
711*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_501ohm, 501},
712*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_253ohm, 253},
713*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_168ohm, 168},
714*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_126ohm, 126},
715*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_101ohm, 101},
716*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_84ohm, 84},
717*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_72ohm, 72},
718*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_63ohm, 63},
719*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_56ohm, 56},
720*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_50ohm, 50},
721*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_46ohm, 46},
722*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_42ohm, 42},
723*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_38ohm, 38},
724*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_36ohm, 36},
725*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_33ohm, 33},
726*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_31ohm, 31},
727*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_29ohm, 29},
728*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_28ohm, 28},
729*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_26ohm, 26},
730*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_25ohm, 25},
731*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_24ohm, 24},
732*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_23ohm, 23},
733*4882a593Smuzhiyun 	{PHY_LPDDR4_RON_22ohm, 22}
734*4882a593Smuzhiyun };
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun static u16 lp4_phy_odt_2_ohm[][2] = {
737*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_DISABLE, 0},
738*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_604ohm, 604},
739*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_303ohm, 303},
740*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_202ohm, 202},
741*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_152ohm, 152},
742*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_122ohm, 122},
743*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_101ohm, 101},
744*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_87ohm,	87},
745*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_78ohm, 78},
746*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_69ohm, 69},
747*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_62ohm, 62},
748*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_56ohm, 56},
749*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_52ohm, 52},
750*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_48ohm, 48},
751*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_44ohm, 44},
752*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_41ohm, 41},
753*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_39ohm, 39},
754*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_37ohm, 37},
755*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_35ohm, 35},
756*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_33ohm, 33},
757*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_32ohm, 32},
758*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_30ohm, 30},
759*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_29ohm, 29},
760*4882a593Smuzhiyun 	{PHY_LPDDR4_RTT_27ohm, 27}
761*4882a593Smuzhiyun };
762*4882a593Smuzhiyun 
lp4_odt_calc(u32 odt_ohm)763*4882a593Smuzhiyun static u32 lp4_odt_calc(u32 odt_ohm)
764*4882a593Smuzhiyun {
765*4882a593Smuzhiyun 	u32 odt;
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	if (odt_ohm == 0)
768*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_DIS;
769*4882a593Smuzhiyun 	else if (odt_ohm <= 40)
770*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_40;
771*4882a593Smuzhiyun 	else if (odt_ohm <= 48)
772*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_48;
773*4882a593Smuzhiyun 	else if (odt_ohm <= 60)
774*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_60;
775*4882a593Smuzhiyun 	else if (odt_ohm <= 80)
776*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_80;
777*4882a593Smuzhiyun 	else if (odt_ohm <= 120)
778*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_120;
779*4882a593Smuzhiyun 	else
780*4882a593Smuzhiyun 		odt = LPDDR4_DQODT_240;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	return odt;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun 
get_ddr_drv_odt_info(u32 dramtype)785*4882a593Smuzhiyun static void *get_ddr_drv_odt_info(u32 dramtype)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
788*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
789*4882a593Smuzhiyun 	void *ddr_info = 0;
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 	if (dramtype == DDR4)
792*4882a593Smuzhiyun 		ddr_info = (void *)common_info + index->ddr4_index.offset * 4;
793*4882a593Smuzhiyun 	else if (dramtype == DDR3)
794*4882a593Smuzhiyun 		ddr_info = (void *)common_info + index->ddr3_index.offset * 4;
795*4882a593Smuzhiyun 	else if (dramtype == LPDDR3)
796*4882a593Smuzhiyun 		ddr_info = (void *)common_info + index->lp3_index.offset * 4;
797*4882a593Smuzhiyun 	else if (dramtype == LPDDR4)
798*4882a593Smuzhiyun 		ddr_info = (void *)common_info + index->lp4_index.offset * 4;
799*4882a593Smuzhiyun 	else if (dramtype == LPDDR4X)
800*4882a593Smuzhiyun 		ddr_info = (void *)common_info + index->lp4x_index.offset * 4;
801*4882a593Smuzhiyun 	else
802*4882a593Smuzhiyun 		printascii("unsupported dram type\n");
803*4882a593Smuzhiyun 	return ddr_info;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun 
set_lp4_vref(struct dram_info * dram,struct lp4_info * lp4_info,u32 freq_mhz,u32 dst_fsp,u32 dramtype)806*4882a593Smuzhiyun static void set_lp4_vref(struct dram_info *dram, struct lp4_info *lp4_info,
807*4882a593Smuzhiyun 			 u32 freq_mhz, u32 dst_fsp, u32 dramtype)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
810*4882a593Smuzhiyun 	u32 ca_vref, dq_vref;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	if (freq_mhz <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq))
813*4882a593Smuzhiyun 		ca_vref = LP4_CA_VREF(lp4_info->vref_when_odtoff);
814*4882a593Smuzhiyun 	else
815*4882a593Smuzhiyun 		ca_vref = LP4_CA_VREF(lp4_info->vref_when_odten);
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	if (freq_mhz <= LP4_DQ_ODT_EN_FREQ(lp4_info->dq_odten_freq))
818*4882a593Smuzhiyun 		dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odtoff);
819*4882a593Smuzhiyun 	else
820*4882a593Smuzhiyun 		dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odten);
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 	if (dramtype == LPDDR4) {
823*4882a593Smuzhiyun 		if (ca_vref < 100)
824*4882a593Smuzhiyun 			ca_vref = 100;
825*4882a593Smuzhiyun 		if (ca_vref > 420)
826*4882a593Smuzhiyun 			ca_vref = 420;
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 		if (ca_vref <= 300)
829*4882a593Smuzhiyun 			ca_vref = (0 << 6) | (ca_vref - 100) / 4;
830*4882a593Smuzhiyun 		else
831*4882a593Smuzhiyun 			ca_vref = (1 << 6) | (ca_vref - 220) / 4;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 		if (dq_vref < 100)
834*4882a593Smuzhiyun 			dq_vref = 100;
835*4882a593Smuzhiyun 		if (dq_vref > 420)
836*4882a593Smuzhiyun 			dq_vref = 420;
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 		if (dq_vref <= 300)
839*4882a593Smuzhiyun 			dq_vref = (0 << 6) | (dq_vref - 100) / 4;
840*4882a593Smuzhiyun 		else
841*4882a593Smuzhiyun 			dq_vref = (1 << 6) | (dq_vref - 220) / 4;
842*4882a593Smuzhiyun 	} else {
843*4882a593Smuzhiyun 		ca_vref = ca_vref * 11 / 6;
844*4882a593Smuzhiyun 		if (ca_vref < 150)
845*4882a593Smuzhiyun 			ca_vref = 150;
846*4882a593Smuzhiyun 		if (ca_vref > 629)
847*4882a593Smuzhiyun 			ca_vref = 629;
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 		if (ca_vref <= 449)
850*4882a593Smuzhiyun 			ca_vref = (0 << 6) | (ca_vref - 150) / 4;
851*4882a593Smuzhiyun 		else
852*4882a593Smuzhiyun 			ca_vref = (1 << 6) | (ca_vref - 329) / 4;
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 		if (dq_vref < 150)
855*4882a593Smuzhiyun 			dq_vref = 150;
856*4882a593Smuzhiyun 		if (dq_vref > 629)
857*4882a593Smuzhiyun 			dq_vref = 629;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 		if (dq_vref <= 449)
860*4882a593Smuzhiyun 			dq_vref = (0 << 6) | (dq_vref - 150) / 6;
861*4882a593Smuzhiyun 		else
862*4882a593Smuzhiyun 			dq_vref = (1 << 6) | (dq_vref - 329) / 6;
863*4882a593Smuzhiyun 	}
864*4882a593Smuzhiyun 	sw_set_req(dram);
865*4882a593Smuzhiyun 	clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
866*4882a593Smuzhiyun 			DDR_PCTL2_INIT6,
867*4882a593Smuzhiyun 			PCTL2_MR_MASK << PCTL2_LPDDR4_MR12_SHIFT,
868*4882a593Smuzhiyun 			ca_vref << PCTL2_LPDDR4_MR12_SHIFT);
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
871*4882a593Smuzhiyun 			DDR_PCTL2_INIT7,
872*4882a593Smuzhiyun 			PCTL2_MR_MASK << PCTL2_LPDDR4_MR14_SHIFT,
873*4882a593Smuzhiyun 			dq_vref << PCTL2_LPDDR4_MR14_SHIFT);
874*4882a593Smuzhiyun 	sw_set_ack(dram);
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun 
set_ds_odt(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,u32 dst_fsp)877*4882a593Smuzhiyun static void set_ds_odt(struct dram_info *dram,
878*4882a593Smuzhiyun 		       struct rv1126_sdram_params *sdram_params, u32 dst_fsp)
879*4882a593Smuzhiyun {
880*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
881*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
882*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
883*4882a593Smuzhiyun 	struct ddr2_3_4_lp2_3_info *ddr_info;
884*4882a593Smuzhiyun 	struct lp4_info *lp4_info;
885*4882a593Smuzhiyun 	u32 i, j, tmp;
886*4882a593Smuzhiyun 	const u16 (*p_drv)[2];
887*4882a593Smuzhiyun 	const u16 (*p_odt)[2];
888*4882a593Smuzhiyun 	u32 drv_info, sr_info;
889*4882a593Smuzhiyun 	u32 phy_dq_drv_ohm, phy_clk_drv_ohm, phy_ca_drv_ohm, dram_drv_ohm;
890*4882a593Smuzhiyun 	u32 phy_odt_ohm, dram_odt_ohm;
891*4882a593Smuzhiyun 	u32 lp4_pu_cal, phy_lp4_drv_pd_en;
892*4882a593Smuzhiyun 	u32 phy_odt_up_en, phy_odt_dn_en;
893*4882a593Smuzhiyun 	u32 sr_dq, sr_clk;
894*4882a593Smuzhiyun 	u32 freq = sdram_params->base.ddr_freq;
895*4882a593Smuzhiyun 	u32 mr1_mr3, mr11, mr22, vref_out, vref_inner;
896*4882a593Smuzhiyun 	u32 phy_clk_drv = 0, phy_odt = 0, phy_ca_drv = 0, dram_caodt_ohm = 0;
897*4882a593Smuzhiyun 	u32 phy_dq_drv = 0;
898*4882a593Smuzhiyun 	u32 phy_odt_up = 0, phy_odt_dn = 0;
899*4882a593Smuzhiyun 
900*4882a593Smuzhiyun 	ddr_info = get_ddr_drv_odt_info(dramtype);
901*4882a593Smuzhiyun 	lp4_info = (void *)ddr_info;
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	if (!ddr_info)
904*4882a593Smuzhiyun 		return;
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	/* dram odt en freq control phy drv, dram odt and phy sr */
907*4882a593Smuzhiyun 	if (freq <= DRAMODT_EN_FREQ(ddr_info->odten_freq)) {
908*4882a593Smuzhiyun 		drv_info = ddr_info->drv_when_odtoff;
909*4882a593Smuzhiyun 		dram_odt_ohm = 0;
910*4882a593Smuzhiyun 		sr_info = ddr_info->sr_when_odtoff;
911*4882a593Smuzhiyun 		phy_lp4_drv_pd_en =
912*4882a593Smuzhiyun 			PHY_LP4_DRV_PULLDOWN_EN_ODTOFF(lp4_info->odt_info);
913*4882a593Smuzhiyun 	} else {
914*4882a593Smuzhiyun 		drv_info = ddr_info->drv_when_odten;
915*4882a593Smuzhiyun 		dram_odt_ohm = ODT_INFO_DRAM_ODT(ddr_info->odt_info);
916*4882a593Smuzhiyun 		sr_info = ddr_info->sr_when_odten;
917*4882a593Smuzhiyun 		phy_lp4_drv_pd_en =
918*4882a593Smuzhiyun 			PHY_LP4_DRV_PULLDOWN_EN_ODTEN(lp4_info->odt_info);
919*4882a593Smuzhiyun 	}
920*4882a593Smuzhiyun 	phy_dq_drv_ohm =
921*4882a593Smuzhiyun 		DRV_INFO_PHY_DQ_DRV(drv_info);
922*4882a593Smuzhiyun 	phy_clk_drv_ohm =
923*4882a593Smuzhiyun 		DRV_INFO_PHY_CLK_DRV(drv_info);
924*4882a593Smuzhiyun 	phy_ca_drv_ohm =
925*4882a593Smuzhiyun 		DRV_INFO_PHY_CA_DRV(drv_info);
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 	sr_dq = DQ_SR_INFO(sr_info);
928*4882a593Smuzhiyun 	sr_clk = CLK_SR_INFO(sr_info);
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	/* phy odt en freq control dram drv and phy odt */
931*4882a593Smuzhiyun 	if (freq <= PHYODT_EN_FREQ(ddr_info->odten_freq)) {
932*4882a593Smuzhiyun 		dram_drv_ohm = DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odtoff);
933*4882a593Smuzhiyun 		lp4_pu_cal = LP4_DRV_PU_CAL_ODTOFF(lp4_info->odt_info);
934*4882a593Smuzhiyun 		phy_odt_ohm = 0;
935*4882a593Smuzhiyun 		phy_odt_up_en = 0;
936*4882a593Smuzhiyun 		phy_odt_dn_en = 0;
937*4882a593Smuzhiyun 	} else {
938*4882a593Smuzhiyun 		dram_drv_ohm =
939*4882a593Smuzhiyun 			DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odten);
940*4882a593Smuzhiyun 		phy_odt_ohm = ODT_INFO_PHY_ODT(ddr_info->odt_info);
941*4882a593Smuzhiyun 		phy_odt_up_en =
942*4882a593Smuzhiyun 			ODT_INFO_PULLUP_EN(ddr_info->odt_info);
943*4882a593Smuzhiyun 		phy_odt_dn_en =
944*4882a593Smuzhiyun 			ODT_INFO_PULLDOWN_EN(ddr_info->odt_info);
945*4882a593Smuzhiyun 		lp4_pu_cal = LP4_DRV_PU_CAL_ODTEN(lp4_info->odt_info);
946*4882a593Smuzhiyun 	}
947*4882a593Smuzhiyun 
948*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
949*4882a593Smuzhiyun 		if (phy_odt_ohm) {
950*4882a593Smuzhiyun 			phy_odt_up_en = 0;
951*4882a593Smuzhiyun 			phy_odt_dn_en = 1;
952*4882a593Smuzhiyun 		}
953*4882a593Smuzhiyun 		if (freq <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq))
954*4882a593Smuzhiyun 			dram_caodt_ohm = 0;
955*4882a593Smuzhiyun 		else
956*4882a593Smuzhiyun 			dram_caodt_ohm =
957*4882a593Smuzhiyun 				ODT_INFO_LP4_CA_ODT(lp4_info->odt_info);
958*4882a593Smuzhiyun 	}
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	if (dramtype == DDR3) {
961*4882a593Smuzhiyun 		p_drv = d3_phy_drv_2_ohm;
962*4882a593Smuzhiyun 		p_odt = d3_phy_odt_2_ohm;
963*4882a593Smuzhiyun 	} else if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
964*4882a593Smuzhiyun 		p_drv = lp4_phy_drv_2_ohm;
965*4882a593Smuzhiyun 		p_odt = lp4_phy_odt_2_ohm;
966*4882a593Smuzhiyun 	} else {
967*4882a593Smuzhiyun 		p_drv = d4lp3_phy_drv_2_ohm;
968*4882a593Smuzhiyun 		p_odt = d4lp3_phy_odt_2_ohm;
969*4882a593Smuzhiyun 	}
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 	for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
972*4882a593Smuzhiyun 		if (phy_dq_drv_ohm <= *(*(p_drv + i) + 1)) {
973*4882a593Smuzhiyun 			phy_dq_drv = **(p_drv + i);
974*4882a593Smuzhiyun 			break;
975*4882a593Smuzhiyun 		}
976*4882a593Smuzhiyun 		if (i == 0)
977*4882a593Smuzhiyun 			break;
978*4882a593Smuzhiyun 	}
979*4882a593Smuzhiyun 	for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
980*4882a593Smuzhiyun 		if (phy_clk_drv_ohm <= *(*(p_drv + i) + 1)) {
981*4882a593Smuzhiyun 			phy_clk_drv = **(p_drv + i);
982*4882a593Smuzhiyun 			break;
983*4882a593Smuzhiyun 		}
984*4882a593Smuzhiyun 		if (i == 0)
985*4882a593Smuzhiyun 			break;
986*4882a593Smuzhiyun 	}
987*4882a593Smuzhiyun 	for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
988*4882a593Smuzhiyun 		if (phy_ca_drv_ohm <= *(*(p_drv + i) + 1)) {
989*4882a593Smuzhiyun 			phy_ca_drv = **(p_drv + i);
990*4882a593Smuzhiyun 			break;
991*4882a593Smuzhiyun 		}
992*4882a593Smuzhiyun 		if (i == 0)
993*4882a593Smuzhiyun 			break;
994*4882a593Smuzhiyun 	}
995*4882a593Smuzhiyun 	if (!phy_odt_ohm)
996*4882a593Smuzhiyun 		phy_odt = 0;
997*4882a593Smuzhiyun 	else
998*4882a593Smuzhiyun 		for (i = ARRAY_SIZE(d4lp3_phy_odt_2_ohm) - 1; ; i--) {
999*4882a593Smuzhiyun 			if (phy_odt_ohm <= *(*(p_odt + i) + 1)) {
1000*4882a593Smuzhiyun 				phy_odt = **(p_odt + i);
1001*4882a593Smuzhiyun 				break;
1002*4882a593Smuzhiyun 			}
1003*4882a593Smuzhiyun 			if (i == 0)
1004*4882a593Smuzhiyun 				break;
1005*4882a593Smuzhiyun 		}
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 	if (dramtype != LPDDR4 && dramtype != LPDDR4X) {
1008*4882a593Smuzhiyun 		if (!phy_odt_ohm || (phy_odt_up_en && phy_odt_dn_en))
1009*4882a593Smuzhiyun 			vref_inner = 0x80;
1010*4882a593Smuzhiyun 		else if (phy_odt_up_en)
1011*4882a593Smuzhiyun 			vref_inner = (2 * dram_drv_ohm + phy_odt_ohm) * 128 /
1012*4882a593Smuzhiyun 				     (dram_drv_ohm + phy_odt_ohm);
1013*4882a593Smuzhiyun 		else
1014*4882a593Smuzhiyun 			vref_inner = phy_odt_ohm * 128 /
1015*4882a593Smuzhiyun 				(phy_odt_ohm + dram_drv_ohm);
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun 		if (dramtype != DDR3 && dram_odt_ohm)
1018*4882a593Smuzhiyun 			vref_out = (2 * phy_dq_drv_ohm + dram_odt_ohm) * 128 /
1019*4882a593Smuzhiyun 				   (phy_dq_drv_ohm + dram_odt_ohm);
1020*4882a593Smuzhiyun 		else
1021*4882a593Smuzhiyun 			vref_out = 0x80;
1022*4882a593Smuzhiyun 	} else {
1023*4882a593Smuzhiyun 		/* for lp4 and lp4x*/
1024*4882a593Smuzhiyun 		if (phy_odt_ohm)
1025*4882a593Smuzhiyun 			vref_inner =
1026*4882a593Smuzhiyun 				(PHY_LP4_DQ_VREF(lp4_info->vref_when_odten) *
1027*4882a593Smuzhiyun 				 256) / 1000;
1028*4882a593Smuzhiyun 		else
1029*4882a593Smuzhiyun 			vref_inner =
1030*4882a593Smuzhiyun 				(PHY_LP4_DQ_VREF(lp4_info->vref_when_odtoff) *
1031*4882a593Smuzhiyun 				 256) / 1000;
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 		vref_out = 0x80;
1034*4882a593Smuzhiyun 	}
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	/* default ZQCALIB bypass mode */
1037*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x100), 0x1f, phy_ca_drv);
1038*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x101), 0x1f, phy_ca_drv);
1039*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x102), 0x1f, phy_clk_drv);
1040*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x103), 0x1f, phy_clk_drv);
1041*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
1042*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_clk_drv);
1043*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_clk_drv);
1044*4882a593Smuzhiyun 	} else {
1045*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_ca_drv);
1046*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_ca_drv);
1047*4882a593Smuzhiyun 	}
1048*4882a593Smuzhiyun 	/* clk / cmd slew rate */
1049*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x106), 0x1f, sr_clk);
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	phy_lp4_drv_pd_en = (~phy_lp4_drv_pd_en) & 1;
1052*4882a593Smuzhiyun 	if (phy_odt_up_en)
1053*4882a593Smuzhiyun 		phy_odt_up = phy_odt;
1054*4882a593Smuzhiyun 	if (phy_odt_dn_en)
1055*4882a593Smuzhiyun 		phy_odt_dn = phy_odt;
1056*4882a593Smuzhiyun 
1057*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
1058*4882a593Smuzhiyun 		j = 0x110 + i * 0x10;
1059*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, j + 1), 0x1f, phy_odt_up);
1060*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, j), 0x1f, phy_odt_dn);
1061*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, j + 2), 0x1f, phy_dq_drv);
1062*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, j + 3), 0x1f, phy_dq_drv);
1063*4882a593Smuzhiyun 		writel(vref_inner, PHY_REG(phy_base, 0x118 + i * 0x10));
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10),
1066*4882a593Smuzhiyun 				1 << 3, phy_lp4_drv_pd_en << 3);
1067*4882a593Smuzhiyun 		if (dramtype == LPDDR4 || dramtype == LPDDR4X)
1068*4882a593Smuzhiyun 			clrbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10), BIT(5));
1069*4882a593Smuzhiyun 		/* dq slew rate */
1070*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x117 + i * 0x10),
1071*4882a593Smuzhiyun 				0x1f, sr_dq);
1072*4882a593Smuzhiyun 	}
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 	/* reg_rx_vref_value_update */
1075*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1076*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun 	/* RAM VREF */
1079*4882a593Smuzhiyun 	writel(vref_out, PHY_REG(phy_base, 0x105));
1080*4882a593Smuzhiyun 	if (dramtype == LPDDR3)
1081*4882a593Smuzhiyun 		udelay(100);
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X)
1084*4882a593Smuzhiyun 		set_lp4_vref(dram, lp4_info, freq, dst_fsp, dramtype);
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun 	if (dramtype == DDR3 || dramtype == DDR4) {
1087*4882a593Smuzhiyun 		mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1088*4882a593Smuzhiyun 				DDR_PCTL2_INIT3);
1089*4882a593Smuzhiyun 		mr1_mr3 = mr1_mr3 >> PCTL2_DDR34_MR1_SHIFT & PCTL2_MR_MASK;
1090*4882a593Smuzhiyun 	} else {
1091*4882a593Smuzhiyun 		mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1092*4882a593Smuzhiyun 				DDR_PCTL2_INIT4);
1093*4882a593Smuzhiyun 		mr1_mr3 = mr1_mr3 >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK;
1094*4882a593Smuzhiyun 	}
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	if (dramtype == DDR3) {
1097*4882a593Smuzhiyun 		mr1_mr3 &= ~(DDR3_DS_MASK | DDR3_RTT_NOM_MASK);
1098*4882a593Smuzhiyun 		if (dram_drv_ohm == 34)
1099*4882a593Smuzhiyun 			mr1_mr3 |= DDR3_DS_34;
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun 		if (dram_odt_ohm == 0)
1102*4882a593Smuzhiyun 			mr1_mr3 |= DDR3_RTT_NOM_DIS;
1103*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 40)
1104*4882a593Smuzhiyun 			mr1_mr3 |= DDR3_RTT_NOM_40;
1105*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 60)
1106*4882a593Smuzhiyun 			mr1_mr3 |= DDR3_RTT_NOM_60;
1107*4882a593Smuzhiyun 		else
1108*4882a593Smuzhiyun 			mr1_mr3 |= DDR3_RTT_NOM_120;
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	} else if (dramtype == DDR4) {
1111*4882a593Smuzhiyun 		mr1_mr3 &= ~(DDR4_DS_MASK | DDR4_RTT_NOM_MASK);
1112*4882a593Smuzhiyun 		if (dram_drv_ohm == 48)
1113*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_DS_48;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 		if (dram_odt_ohm == 0)
1116*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_DIS;
1117*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 34)
1118*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_34;
1119*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 40)
1120*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_40;
1121*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 48)
1122*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_48;
1123*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 60)
1124*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_60;
1125*4882a593Smuzhiyun 		else
1126*4882a593Smuzhiyun 			mr1_mr3 |= DDR4_RTT_NOM_120;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun 	} else if (dramtype == LPDDR3) {
1129*4882a593Smuzhiyun 		if (dram_drv_ohm <= 34)
1130*4882a593Smuzhiyun 			mr1_mr3 |= LPDDR3_DS_34;
1131*4882a593Smuzhiyun 		else if (dram_drv_ohm <= 40)
1132*4882a593Smuzhiyun 			mr1_mr3 |= LPDDR3_DS_40;
1133*4882a593Smuzhiyun 		else if (dram_drv_ohm <= 48)
1134*4882a593Smuzhiyun 			mr1_mr3 |= LPDDR3_DS_48;
1135*4882a593Smuzhiyun 		else if (dram_drv_ohm <= 60)
1136*4882a593Smuzhiyun 			mr1_mr3 |= LPDDR3_DS_60;
1137*4882a593Smuzhiyun 		else if (dram_drv_ohm <= 80)
1138*4882a593Smuzhiyun 			mr1_mr3 |= LPDDR3_DS_80;
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 		if (dram_odt_ohm == 0)
1141*4882a593Smuzhiyun 			lp3_odt_value = LPDDR3_ODT_DIS;
1142*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 60)
1143*4882a593Smuzhiyun 			lp3_odt_value = LPDDR3_ODT_60;
1144*4882a593Smuzhiyun 		else if (dram_odt_ohm <= 120)
1145*4882a593Smuzhiyun 			lp3_odt_value = LPDDR3_ODT_120;
1146*4882a593Smuzhiyun 		else
1147*4882a593Smuzhiyun 			lp3_odt_value = LPDDR3_ODT_240;
1148*4882a593Smuzhiyun 	} else {/* for lpddr4 and lpddr4x */
1149*4882a593Smuzhiyun 		/* MR3 for lp4 PU-CAL and PDDS */
1150*4882a593Smuzhiyun 		mr1_mr3 &= ~(LPDDR4_PDDS_MASK | LPDDR4_PU_CAL_MASK);
1151*4882a593Smuzhiyun 		mr1_mr3 |= lp4_pu_cal;
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun 		tmp = lp4_odt_calc(dram_drv_ohm);
1154*4882a593Smuzhiyun 		if (!tmp)
1155*4882a593Smuzhiyun 			tmp = LPDDR4_PDDS_240;
1156*4882a593Smuzhiyun 		mr1_mr3 |= (tmp << LPDDR4_PDDS_SHIFT);
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun 		/* MR11 for lp4 ca odt, dq odt set */
1159*4882a593Smuzhiyun 		mr11 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1160*4882a593Smuzhiyun 			     DDR_PCTL2_INIT6);
1161*4882a593Smuzhiyun 		mr11 = mr11 >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK;
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 		mr11 &= ~(LPDDR4_DQODT_MASK | LPDDR4_CAODT_MASK);
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 		tmp = lp4_odt_calc(dram_odt_ohm);
1166*4882a593Smuzhiyun 		mr11 |= (tmp << LPDDR4_DQODT_SHIFT);
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 		tmp = lp4_odt_calc(dram_caodt_ohm);
1169*4882a593Smuzhiyun 		mr11 |= (tmp << LPDDR4_CAODT_SHIFT);
1170*4882a593Smuzhiyun 		sw_set_req(dram);
1171*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1172*4882a593Smuzhiyun 				DDR_PCTL2_INIT6,
1173*4882a593Smuzhiyun 				PCTL2_MR_MASK << PCTL2_LPDDR4_MR11_SHIFT,
1174*4882a593Smuzhiyun 				mr11 << PCTL2_LPDDR4_MR11_SHIFT);
1175*4882a593Smuzhiyun 		sw_set_ack(dram);
1176*4882a593Smuzhiyun 
1177*4882a593Smuzhiyun 		/* MR22 for soc odt/odt-ck/odt-cs/odt-ca */
1178*4882a593Smuzhiyun 		mr22 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1179*4882a593Smuzhiyun 			     DDR_PCTL2_INIT7);
1180*4882a593Smuzhiyun 		mr22 = mr22 >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK;
1181*4882a593Smuzhiyun 		mr22 &= ~LPDDR4_SOC_ODT_MASK;
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun 		tmp = lp4_odt_calc(phy_odt_ohm);
1184*4882a593Smuzhiyun 		mr22 |= tmp;
1185*4882a593Smuzhiyun 		mr22 = mr22 |
1186*4882a593Smuzhiyun 		       (LP4_ODTE_CK_EN(lp4_info->cs_drv_ca_odt_info) <<
1187*4882a593Smuzhiyun 			LPDDR4_ODTE_CK_SHIFT) |
1188*4882a593Smuzhiyun 		       (LP4_ODTE_CS_EN(lp4_info->cs_drv_ca_odt_info) <<
1189*4882a593Smuzhiyun 			LPDDR4_ODTE_CS_SHIFT) |
1190*4882a593Smuzhiyun 		       (LP4_ODTD_CA_EN(lp4_info->cs_drv_ca_odt_info) <<
1191*4882a593Smuzhiyun 			LPDDR4_ODTD_CA_SHIFT);
1192*4882a593Smuzhiyun 
1193*4882a593Smuzhiyun 		sw_set_req(dram);
1194*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1195*4882a593Smuzhiyun 				DDR_PCTL2_INIT7,
1196*4882a593Smuzhiyun 				PCTL2_MR_MASK << PCTL2_LPDDR4_MR22_SHIFT,
1197*4882a593Smuzhiyun 				mr22 << PCTL2_LPDDR4_MR22_SHIFT);
1198*4882a593Smuzhiyun 		sw_set_ack(dram);
1199*4882a593Smuzhiyun 	}
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 	if (dramtype == DDR4 || dramtype == DDR3) {
1202*4882a593Smuzhiyun 		sw_set_req(dram);
1203*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1204*4882a593Smuzhiyun 				DDR_PCTL2_INIT3,
1205*4882a593Smuzhiyun 				PCTL2_MR_MASK << PCTL2_DDR34_MR1_SHIFT,
1206*4882a593Smuzhiyun 				mr1_mr3 << PCTL2_DDR34_MR1_SHIFT);
1207*4882a593Smuzhiyun 		sw_set_ack(dram);
1208*4882a593Smuzhiyun 	} else {
1209*4882a593Smuzhiyun 		sw_set_req(dram);
1210*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
1211*4882a593Smuzhiyun 				DDR_PCTL2_INIT4,
1212*4882a593Smuzhiyun 				PCTL2_MR_MASK << PCTL2_LPDDR234_MR3_SHIFT,
1213*4882a593Smuzhiyun 				mr1_mr3 << PCTL2_LPDDR234_MR3_SHIFT);
1214*4882a593Smuzhiyun 		sw_set_ack(dram);
1215*4882a593Smuzhiyun 	}
1216*4882a593Smuzhiyun }
1217*4882a593Smuzhiyun 
sdram_cmd_dq_path_remap(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)1218*4882a593Smuzhiyun static int sdram_cmd_dq_path_remap(struct dram_info *dram,
1219*4882a593Smuzhiyun 				   struct rv1126_sdram_params *sdram_params)
1220*4882a593Smuzhiyun {
1221*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1222*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
1223*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
1224*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
1225*4882a593Smuzhiyun 	struct dq_map_info *map_info;
1226*4882a593Smuzhiyun 
1227*4882a593Smuzhiyun 	map_info = (struct dq_map_info *)((void *)common_info +
1228*4882a593Smuzhiyun 		index->dq_map_index.offset * 4);
1229*4882a593Smuzhiyun 
1230*4882a593Smuzhiyun 	if (dramtype == LPDDR4X)
1231*4882a593Smuzhiyun 		dramtype = LPDDR4;
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun 	if (dramtype <= LPDDR4)
1234*4882a593Smuzhiyun 		writel((map_info->byte_map[dramtype / 4] >>
1235*4882a593Smuzhiyun 			((dramtype % 4) * 8)) & 0xff,
1236*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x4f));
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	return 0;
1239*4882a593Smuzhiyun }
1240*4882a593Smuzhiyun 
phy_cfg(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)1241*4882a593Smuzhiyun static void phy_cfg(struct dram_info *dram,
1242*4882a593Smuzhiyun 		    struct rv1126_sdram_params *sdram_params)
1243*4882a593Smuzhiyun {
1244*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
1245*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1246*4882a593Smuzhiyun 	u32 i, dq_map, tmp;
1247*4882a593Smuzhiyun 	u32 byte1 = 0, byte0 = 0;
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun 	sdram_cmd_dq_path_remap(dram, sdram_params);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 0);
1252*4882a593Smuzhiyun 	for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
1253*4882a593Smuzhiyun 		writel(sdram_params->phy_regs.phy[i][1],
1254*4882a593Smuzhiyun 		       phy_base + sdram_params->phy_regs.phy[i][0]);
1255*4882a593Smuzhiyun 	}
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x62), BIT(5));
1258*4882a593Smuzhiyun 	dq_map = readl(PHY_REG(phy_base, 0x4f));
1259*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
1260*4882a593Smuzhiyun 		if (((dq_map >> (i * 2)) & 0x3) == 0) {
1261*4882a593Smuzhiyun 			byte0 = i;
1262*4882a593Smuzhiyun 			break;
1263*4882a593Smuzhiyun 		}
1264*4882a593Smuzhiyun 	}
1265*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
1266*4882a593Smuzhiyun 		if (((dq_map >> (i * 2)) & 0x3) == 1) {
1267*4882a593Smuzhiyun 			byte1 = i;
1268*4882a593Smuzhiyun 			break;
1269*4882a593Smuzhiyun 		}
1270*4882a593Smuzhiyun 	}
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	tmp = readl(PHY_REG(phy_base, 0xf)) & (~PHY_DQ_WIDTH_MASK);
1273*4882a593Smuzhiyun 	if (cap_info->bw == 2)
1274*4882a593Smuzhiyun 		tmp |= 0xf;
1275*4882a593Smuzhiyun 	else if (cap_info->bw == 1)
1276*4882a593Smuzhiyun 		tmp |= ((1 << byte0) | (1 << byte1));
1277*4882a593Smuzhiyun 	else
1278*4882a593Smuzhiyun 		tmp |= (1 << byte0);
1279*4882a593Smuzhiyun 
1280*4882a593Smuzhiyun 	writel(tmp, PHY_REG(phy_base, 0xf));
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	/* lpddr4 odt control by phy, enable cs0 odt */
1283*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR4 ||
1284*4882a593Smuzhiyun 	    sdram_params->base.dramtype == LPDDR4X)
1285*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, 0x20), 0x7 << 4,
1286*4882a593Smuzhiyun 				(1 << 6) | (1 << 4));
1287*4882a593Smuzhiyun 	/* for ca training ca vref choose range1 */
1288*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x1e), BIT(6));
1289*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x1f), BIT(6));
1290*4882a593Smuzhiyun 	/* for wr training PHY_0x7c[5], choose range0 */
1291*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x7c), BIT(5));
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun 
update_refresh_reg(struct dram_info * dram)1294*4882a593Smuzhiyun static int update_refresh_reg(struct dram_info *dram)
1295*4882a593Smuzhiyun {
1296*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1297*4882a593Smuzhiyun 	u32 ret;
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
1300*4882a593Smuzhiyun 	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
1301*4882a593Smuzhiyun 
1302*4882a593Smuzhiyun 	return 0;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun 
1305*4882a593Smuzhiyun /*
1306*4882a593Smuzhiyun  * rank = 1: cs0
1307*4882a593Smuzhiyun  * rank = 2: cs1
1308*4882a593Smuzhiyun  */
read_mr(struct dram_info * dram,u32 rank,u32 mr_num,u32 dramtype)1309*4882a593Smuzhiyun u32 read_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 dramtype)
1310*4882a593Smuzhiyun {
1311*4882a593Smuzhiyun 	u32 ret;
1312*4882a593Smuzhiyun 	u32 i, temp;
1313*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1314*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
1315*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
1316*4882a593Smuzhiyun 	struct dq_map_info *map_info;
1317*4882a593Smuzhiyun 
1318*4882a593Smuzhiyun 	map_info = (struct dq_map_info *)((void *)common_info +
1319*4882a593Smuzhiyun 		index->dq_map_index.offset * 4);
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun 	pctl_read_mr(pctl_base, rank, mr_num);
1322*4882a593Smuzhiyun 
1323*4882a593Smuzhiyun 	if (dramtype == LPDDR3) {
1324*4882a593Smuzhiyun 		temp = (readl(&dram->ddrgrf->ddr_grf_status[0]) & 0xff);
1325*4882a593Smuzhiyun 		ret = 0;
1326*4882a593Smuzhiyun 		for (i = 0; i < 8; i++)
1327*4882a593Smuzhiyun 			ret |= ((temp >> i) & 0x1) << ((map_info->lp3_dq0_7_map >> (i * 4)) & 0xf);
1328*4882a593Smuzhiyun 	} else {
1329*4882a593Smuzhiyun 		ret = readl(&dram->ddrgrf->ddr_grf_status[1]) & 0xff;
1330*4882a593Smuzhiyun 	}
1331*4882a593Smuzhiyun 
1332*4882a593Smuzhiyun 	return ret;
1333*4882a593Smuzhiyun }
1334*4882a593Smuzhiyun 
1335*4882a593Smuzhiyun /* before call this function autorefresh should be disabled */
send_a_refresh(struct dram_info * dram)1336*4882a593Smuzhiyun void send_a_refresh(struct dram_info *dram)
1337*4882a593Smuzhiyun {
1338*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1339*4882a593Smuzhiyun 
1340*4882a593Smuzhiyun 	while (readl(pctl_base + DDR_PCTL2_DBGSTAT) & 0x3)
1341*4882a593Smuzhiyun 		continue;
1342*4882a593Smuzhiyun 	writel(0x3, pctl_base + DDR_PCTL2_DBGCMD);
1343*4882a593Smuzhiyun }
1344*4882a593Smuzhiyun 
enter_sr(struct dram_info * dram,u32 en)1345*4882a593Smuzhiyun static void enter_sr(struct dram_info *dram, u32 en)
1346*4882a593Smuzhiyun {
1347*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun 	if (en) {
1350*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW);
1351*4882a593Smuzhiyun 		while (1) {
1352*4882a593Smuzhiyun 			if (((readl(pctl_base + DDR_PCTL2_STAT) &
1353*4882a593Smuzhiyun 			      PCTL2_SELFREF_TYPE_MASK) ==
1354*4882a593Smuzhiyun 			     PCTL2_SELFREF_TYPE_SR_NOT_AUTO) &&
1355*4882a593Smuzhiyun 			    ((readl(pctl_base + DDR_PCTL2_STAT) &
1356*4882a593Smuzhiyun 			      PCTL2_OPERATING_MODE_MASK) ==
1357*4882a593Smuzhiyun 			     PCTL2_OPERATING_MODE_SR))
1358*4882a593Smuzhiyun 				break;
1359*4882a593Smuzhiyun 		}
1360*4882a593Smuzhiyun 	} else {
1361*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW);
1362*4882a593Smuzhiyun 		while ((readl(pctl_base + DDR_PCTL2_STAT) &
1363*4882a593Smuzhiyun 		       PCTL2_OPERATING_MODE_MASK) == PCTL2_OPERATING_MODE_SR)
1364*4882a593Smuzhiyun 			continue;
1365*4882a593Smuzhiyun 	}
1366*4882a593Smuzhiyun }
1367*4882a593Smuzhiyun 
record_dq_prebit(struct dram_info * dram)1368*4882a593Smuzhiyun void record_dq_prebit(struct dram_info *dram)
1369*4882a593Smuzhiyun {
1370*4882a593Smuzhiyun 	u32 group, i, tmp;
1371*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1372*4882a593Smuzhiyun 
1373*4882a593Smuzhiyun 	for (group = 0; group < 4; group++) {
1374*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(dq_sel); i++) {
1375*4882a593Smuzhiyun 			/* l_loop_invdelaysel */
1376*4882a593Smuzhiyun 			writel(dq_sel[i][0], PHY_REG(phy_base,
1377*4882a593Smuzhiyun 						     grp_addr[group] + 0x2c));
1378*4882a593Smuzhiyun 			tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2e));
1379*4882a593Smuzhiyun 			writel(tmp, PHY_REG(phy_base,
1380*4882a593Smuzhiyun 					    grp_addr[group] + dq_sel[i][1]));
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun 			/* r_loop_invdelaysel */
1383*4882a593Smuzhiyun 			writel(dq_sel[i][0], PHY_REG(phy_base,
1384*4882a593Smuzhiyun 						     grp_addr[group] + 0x2d));
1385*4882a593Smuzhiyun 			tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2f));
1386*4882a593Smuzhiyun 			writel(tmp, PHY_REG(phy_base,
1387*4882a593Smuzhiyun 					    grp_addr[group] + dq_sel[i][2]));
1388*4882a593Smuzhiyun 		}
1389*4882a593Smuzhiyun 	}
1390*4882a593Smuzhiyun }
1391*4882a593Smuzhiyun 
update_dq_rx_prebit(struct dram_info * dram)1392*4882a593Smuzhiyun static void update_dq_rx_prebit(struct dram_info *dram)
1393*4882a593Smuzhiyun {
1394*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1395*4882a593Smuzhiyun 
1396*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x70), BIT(1) | BIT(6) | BIT(4),
1397*4882a593Smuzhiyun 			BIT(4));
1398*4882a593Smuzhiyun 	udelay(1);
1399*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x70), BIT(4));
1400*4882a593Smuzhiyun }
1401*4882a593Smuzhiyun 
update_dq_tx_prebit(struct dram_info * dram)1402*4882a593Smuzhiyun static void update_dq_tx_prebit(struct dram_info *dram)
1403*4882a593Smuzhiyun {
1404*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
1407*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x2), BIT(3));
1408*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0xc), BIT(6));
1409*4882a593Smuzhiyun 	udelay(1);
1410*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0xc), BIT(6));
1411*4882a593Smuzhiyun }
1412*4882a593Smuzhiyun 
update_ca_prebit(struct dram_info * dram)1413*4882a593Smuzhiyun static void update_ca_prebit(struct dram_info *dram)
1414*4882a593Smuzhiyun {
1415*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x25), BIT(2));
1418*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x22), BIT(6));
1419*4882a593Smuzhiyun 	udelay(1);
1420*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x22), BIT(6));
1421*4882a593Smuzhiyun }
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun /*
1424*4882a593Smuzhiyun  * dir: 0: de-skew = delta_*
1425*4882a593Smuzhiyun  *	1: de-skew = reg val - delta_*
1426*4882a593Smuzhiyun  * delta_dir: value for differential signal: clk/
1427*4882a593Smuzhiyun  * delta_sig: value for single signal: ca/cmd
1428*4882a593Smuzhiyun  */
modify_ca_deskew(struct dram_info * dram,u32 dir,int delta_dif,int delta_sig,u32 cs,u32 dramtype)1429*4882a593Smuzhiyun static void modify_ca_deskew(struct dram_info *dram, u32 dir, int delta_dif,
1430*4882a593Smuzhiyun 			     int delta_sig, u32 cs, u32 dramtype)
1431*4882a593Smuzhiyun {
1432*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1433*4882a593Smuzhiyun 	u32 i, cs_en, tmp;
1434*4882a593Smuzhiyun 	u32 dfi_lp_stat = 0;
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun 	if (cs == 0)
1437*4882a593Smuzhiyun 		cs_en = 1;
1438*4882a593Smuzhiyun 	else if (cs == 2)
1439*4882a593Smuzhiyun 		cs_en = 2;
1440*4882a593Smuzhiyun 	else
1441*4882a593Smuzhiyun 		cs_en = 3;
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun 	if ((dramtype == LPDDR4 || dramtype == LPDDR4X) &&
1444*4882a593Smuzhiyun 	    ((readl(PHY_REG(phy_base, 0x60)) & BIT(5)) == 0)) {
1445*4882a593Smuzhiyun 		dfi_lp_stat = 1;
1446*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0x60), BIT(5));
1447*4882a593Smuzhiyun 	}
1448*4882a593Smuzhiyun 	enter_sr(dram, 1);
1449*4882a593Smuzhiyun 
1450*4882a593Smuzhiyun 	for (i = 0; i < 0x20; i++) {
1451*4882a593Smuzhiyun 		if (dir == DESKEW_MDF_ABS_VAL)
1452*4882a593Smuzhiyun 			tmp = delta_sig;
1453*4882a593Smuzhiyun 		else
1454*4882a593Smuzhiyun 			tmp = readl(PHY_REG(phy_base, 0x150 + i)) +
1455*4882a593Smuzhiyun 			      delta_sig;
1456*4882a593Smuzhiyun 		writel(tmp, PHY_REG(phy_base, 0x150 + i));
1457*4882a593Smuzhiyun 	}
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun 	if (dir == DESKEW_MDF_ABS_VAL)
1460*4882a593Smuzhiyun 		tmp = delta_dif;
1461*4882a593Smuzhiyun 	else
1462*4882a593Smuzhiyun 		tmp = readl(PHY_REG(phy_base, 0x150 + 0x17)) -
1463*4882a593Smuzhiyun 		       delta_sig + delta_dif;
1464*4882a593Smuzhiyun 	writel(tmp, PHY_REG(phy_base, 0x150 + 0x17));
1465*4882a593Smuzhiyun 	writel(tmp, PHY_REG(phy_base, 0x150 + 0x18));
1466*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
1467*4882a593Smuzhiyun 		writel(tmp, PHY_REG(phy_base, 0x150 + 0x4));
1468*4882a593Smuzhiyun 		writel(tmp, PHY_REG(phy_base, 0x150 + 0xa));
1469*4882a593Smuzhiyun 
1470*4882a593Smuzhiyun 		clrbits_le32(PHY_REG(phy_base, 0x10), cs_en << 6);
1471*4882a593Smuzhiyun 		update_ca_prebit(dram);
1472*4882a593Smuzhiyun 	}
1473*4882a593Smuzhiyun 	enter_sr(dram, 0);
1474*4882a593Smuzhiyun 
1475*4882a593Smuzhiyun 	if (dfi_lp_stat)
1476*4882a593Smuzhiyun 		clrbits_le32(PHY_REG(phy_base, 0x60), BIT(5));
1477*4882a593Smuzhiyun 
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun 
get_min_value(struct dram_info * dram,u32 signal,u32 rank)1480*4882a593Smuzhiyun static u32 get_min_value(struct dram_info *dram, u32 signal, u32 rank)
1481*4882a593Smuzhiyun {
1482*4882a593Smuzhiyun 	u32 i, j, offset = 0;
1483*4882a593Smuzhiyun 	u32 min = 0x3f;
1484*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1485*4882a593Smuzhiyun 	u32 byte_en;
1486*4882a593Smuzhiyun 
1487*4882a593Smuzhiyun 	if (signal == SKEW_TX_SIGNAL)
1488*4882a593Smuzhiyun 		offset = 8;
1489*4882a593Smuzhiyun 
1490*4882a593Smuzhiyun 	if (signal == SKEW_CA_SIGNAL) {
1491*4882a593Smuzhiyun 		for (i = 0; i < 0x20; i++)
1492*4882a593Smuzhiyun 			min = MIN(min, readl(PHY_REG(phy_base, 0x150  + i)));
1493*4882a593Smuzhiyun 	} else {
1494*4882a593Smuzhiyun 		byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf;
1495*4882a593Smuzhiyun 		for (j = offset; j < offset + rank * 4; j++) {
1496*4882a593Smuzhiyun 			if (!((byte_en >> (j % 4)) & 1))
1497*4882a593Smuzhiyun 				continue;
1498*4882a593Smuzhiyun 			for (i = 0; i < 11; i++)
1499*4882a593Smuzhiyun 				min = MIN(min,
1500*4882a593Smuzhiyun 					  readl(PHY_REG(phy_base,
1501*4882a593Smuzhiyun 							dqs_dq_skew_adr[j] +
1502*4882a593Smuzhiyun 							i)));
1503*4882a593Smuzhiyun 		}
1504*4882a593Smuzhiyun 	}
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 	return min;
1507*4882a593Smuzhiyun }
1508*4882a593Smuzhiyun 
low_power_update(struct dram_info * dram,u32 en)1509*4882a593Smuzhiyun static u32 low_power_update(struct dram_info *dram, u32 en)
1510*4882a593Smuzhiyun {
1511*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1512*4882a593Smuzhiyun 	u32 lp_stat = 0;
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun 	if (en) {
1515*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, en & 0xf);
1516*4882a593Smuzhiyun 	} else {
1517*4882a593Smuzhiyun 		lp_stat = readl(pctl_base + DDR_PCTL2_PWRCTL) & 0xf;
1518*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 0xf);
1519*4882a593Smuzhiyun 	}
1520*4882a593Smuzhiyun 
1521*4882a593Smuzhiyun 	return lp_stat;
1522*4882a593Smuzhiyun }
1523*4882a593Smuzhiyun 
1524*4882a593Smuzhiyun /*
1525*4882a593Smuzhiyun  * signal:
1526*4882a593Smuzhiyun  * dir: 0: de-skew = delta_*
1527*4882a593Smuzhiyun  *	1: de-skew = reg val - delta_*
1528*4882a593Smuzhiyun  * delta_dir: value for differential signal: dqs
1529*4882a593Smuzhiyun  * delta_sig: value for single signal: dq/dm
1530*4882a593Smuzhiyun  */
modify_dq_deskew(struct dram_info * dram,u32 signal,u32 dir,int delta_dif,int delta_sig,u32 rank)1531*4882a593Smuzhiyun static void modify_dq_deskew(struct dram_info *dram, u32 signal, u32 dir,
1532*4882a593Smuzhiyun 			     int delta_dif, int delta_sig, u32 rank)
1533*4882a593Smuzhiyun {
1534*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1535*4882a593Smuzhiyun 	u32 i, j, tmp, offset;
1536*4882a593Smuzhiyun 	u32 byte_en;
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf;
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun 	if (signal == SKEW_RX_SIGNAL)
1541*4882a593Smuzhiyun 		offset = 0;
1542*4882a593Smuzhiyun 	else
1543*4882a593Smuzhiyun 		offset = 8;
1544*4882a593Smuzhiyun 
1545*4882a593Smuzhiyun 	for (j = offset; j < (offset + rank * 4); j++) {
1546*4882a593Smuzhiyun 		if (!((byte_en >> (j % 4)) & 1))
1547*4882a593Smuzhiyun 			continue;
1548*4882a593Smuzhiyun 		for (i = 0; i < 0x9; i++) {
1549*4882a593Smuzhiyun 			if (dir == DESKEW_MDF_ABS_VAL)
1550*4882a593Smuzhiyun 				tmp = delta_sig;
1551*4882a593Smuzhiyun 			else
1552*4882a593Smuzhiyun 				tmp = delta_sig + readl(PHY_REG(phy_base,
1553*4882a593Smuzhiyun 							dqs_dq_skew_adr[j] +
1554*4882a593Smuzhiyun 							i));
1555*4882a593Smuzhiyun 			writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + i));
1556*4882a593Smuzhiyun 		}
1557*4882a593Smuzhiyun 		if (dir == DESKEW_MDF_ABS_VAL)
1558*4882a593Smuzhiyun 			tmp = delta_dif;
1559*4882a593Smuzhiyun 		else
1560*4882a593Smuzhiyun 			tmp = delta_dif + readl(PHY_REG(phy_base,
1561*4882a593Smuzhiyun 						dqs_dq_skew_adr[j] + 9));
1562*4882a593Smuzhiyun 		writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 9));
1563*4882a593Smuzhiyun 		writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 0xa));
1564*4882a593Smuzhiyun 	}
1565*4882a593Smuzhiyun 	if (signal == SKEW_RX_SIGNAL)
1566*4882a593Smuzhiyun 		update_dq_rx_prebit(dram);
1567*4882a593Smuzhiyun 	else
1568*4882a593Smuzhiyun 		update_dq_tx_prebit(dram);
1569*4882a593Smuzhiyun }
1570*4882a593Smuzhiyun 
data_training_rg(struct dram_info * dram,u32 cs,u32 dramtype)1571*4882a593Smuzhiyun static int data_training_rg(struct dram_info *dram, u32 cs, u32 dramtype)
1572*4882a593Smuzhiyun {
1573*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1574*4882a593Smuzhiyun 	u32 ret;
1575*4882a593Smuzhiyun 	u32 dis_auto_zq = 0;
1576*4882a593Smuzhiyun 	u32 odt_val_up, odt_val_dn;
1577*4882a593Smuzhiyun 	u32 i, j;
1578*4882a593Smuzhiyun 
1579*4882a593Smuzhiyun 	odt_val_dn = readl(PHY_REG(phy_base, 0x110));
1580*4882a593Smuzhiyun 	odt_val_up = readl(PHY_REG(phy_base, 0x111));
1581*4882a593Smuzhiyun 
1582*4882a593Smuzhiyun 	if (dramtype != LPDDR4 || dramtype != LPDDR4X) {
1583*4882a593Smuzhiyun 		for (i = 0; i < 4; i++) {
1584*4882a593Smuzhiyun 			j = 0x110 + i * 0x10;
1585*4882a593Smuzhiyun 			writel(PHY_DDR4_LPDDR3_RTT_294ohm,
1586*4882a593Smuzhiyun 			       PHY_REG(phy_base, j));
1587*4882a593Smuzhiyun 			writel(PHY_DDR4_LPDDR3_RTT_DISABLE,
1588*4882a593Smuzhiyun 			       PHY_REG(phy_base, j + 0x1));
1589*4882a593Smuzhiyun 		}
1590*4882a593Smuzhiyun 	}
1591*4882a593Smuzhiyun 	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
1592*4882a593Smuzhiyun 	/* use normal read mode for data training */
1593*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0xc), BIT(1));
1594*4882a593Smuzhiyun 
1595*4882a593Smuzhiyun 	if (dramtype == DDR4)
1596*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0xc), BIT(1));
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun 	/* choose training cs */
1599*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
1600*4882a593Smuzhiyun 	/* enable gate training */
1601*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
1602*4882a593Smuzhiyun 	udelay(50);
1603*4882a593Smuzhiyun 	ret = readl(PHY_REG(phy_base, 0x91));
1604*4882a593Smuzhiyun 	/* disable gate training */
1605*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
1606*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 2), 0x30);
1607*4882a593Smuzhiyun 	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun 	ret = (ret & 0x2f) ^ (readl(PHY_REG(phy_base, 0xf)) & 0xf);
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	if (dramtype != LPDDR4 || dramtype != LPDDR4X) {
1612*4882a593Smuzhiyun 		for (i = 0; i < 4; i++) {
1613*4882a593Smuzhiyun 			j = 0x110 + i * 0x10;
1614*4882a593Smuzhiyun 			writel(odt_val_dn, PHY_REG(phy_base, j));
1615*4882a593Smuzhiyun 			writel(odt_val_up, PHY_REG(phy_base, j + 0x1));
1616*4882a593Smuzhiyun 		}
1617*4882a593Smuzhiyun 	}
1618*4882a593Smuzhiyun 	return ret;
1619*4882a593Smuzhiyun }
1620*4882a593Smuzhiyun 
data_training_wl(struct dram_info * dram,u32 cs,u32 dramtype,u32 rank)1621*4882a593Smuzhiyun static int data_training_wl(struct dram_info *dram, u32 cs, u32 dramtype,
1622*4882a593Smuzhiyun 			    u32 rank)
1623*4882a593Smuzhiyun {
1624*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1625*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1626*4882a593Smuzhiyun 	u32 dis_auto_zq = 0;
1627*4882a593Smuzhiyun 	u32 tmp;
1628*4882a593Smuzhiyun 	u32 cur_fsp;
1629*4882a593Smuzhiyun 	u32 timeout_us = 1000;
1630*4882a593Smuzhiyun 
1631*4882a593Smuzhiyun 	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
1632*4882a593Smuzhiyun 
1633*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x7a), 0x1);
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun 	cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
1636*4882a593Smuzhiyun 	tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_INIT3) &
1637*4882a593Smuzhiyun 	      0xffff;
1638*4882a593Smuzhiyun 	writel(tmp & 0xff, PHY_REG(phy_base, 0x3));
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun 	/* disable another cs's output */
1641*4882a593Smuzhiyun 	if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2)
1642*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp | (1 << 12),
1643*4882a593Smuzhiyun 			      dramtype);
1644*4882a593Smuzhiyun 	if (dramtype == DDR3 || dramtype == DDR4)
1645*4882a593Smuzhiyun 		writel(0x40 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4));
1646*4882a593Smuzhiyun 	else
1647*4882a593Smuzhiyun 		writel(0x80 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4));
1648*4882a593Smuzhiyun 
1649*4882a593Smuzhiyun 	/* choose cs */
1650*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
1651*4882a593Smuzhiyun 			((0x2 >> cs) << 6) | (0 << 2));
1652*4882a593Smuzhiyun 	/* enable write leveling */
1653*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
1654*4882a593Smuzhiyun 			((0x2 >> cs) << 6) | (1 << 2));
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 	while (1) {
1657*4882a593Smuzhiyun 		if ((readl(PHY_REG(phy_base, 0x92)) & 0xf) ==
1658*4882a593Smuzhiyun 		    (readl(PHY_REG(phy_base, 0xf)) & 0xf))
1659*4882a593Smuzhiyun 			break;
1660*4882a593Smuzhiyun 
1661*4882a593Smuzhiyun 		udelay(1);
1662*4882a593Smuzhiyun 		if (timeout_us-- == 0) {
1663*4882a593Smuzhiyun 			printascii("error: write leveling timeout\n");
1664*4882a593Smuzhiyun 			while (1)
1665*4882a593Smuzhiyun 				;
1666*4882a593Smuzhiyun 		}
1667*4882a593Smuzhiyun 	}
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 	/* disable write leveling */
1670*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
1671*4882a593Smuzhiyun 			((0x2 >> cs) << 6) | (0 << 2));
1672*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x3 << 6, 0 << 6);
1673*4882a593Smuzhiyun 
1674*4882a593Smuzhiyun 	/* enable another cs's output */
1675*4882a593Smuzhiyun 	if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2)
1676*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp & ~(1 << 12),
1677*4882a593Smuzhiyun 			      dramtype);
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
1680*4882a593Smuzhiyun 
1681*4882a593Smuzhiyun 	return 0;
1682*4882a593Smuzhiyun }
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun char pattern[32] = {
1685*4882a593Smuzhiyun 	0xaa, 0x55, 0xaa, 0x55, 0x55, 0xaa, 0x55, 0xaa,
1686*4882a593Smuzhiyun 	0x55, 0xaa, 0x55, 0xaa, 0xaa, 0x55, 0xaa, 0x55,
1687*4882a593Smuzhiyun 	0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
1688*4882a593Smuzhiyun 	0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa
1689*4882a593Smuzhiyun };
1690*4882a593Smuzhiyun 
data_training_rd(struct dram_info * dram,u32 cs,u32 dramtype,u32 mhz)1691*4882a593Smuzhiyun static int data_training_rd(struct dram_info *dram, u32 cs, u32 dramtype,
1692*4882a593Smuzhiyun 			    u32 mhz)
1693*4882a593Smuzhiyun {
1694*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1695*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1696*4882a593Smuzhiyun 	u32 trefi_1x, trfc_1x;
1697*4882a593Smuzhiyun 	u32 dis_auto_zq = 0;
1698*4882a593Smuzhiyun 	u32 timeout_us = 1000;
1699*4882a593Smuzhiyun 	u32 dqs_default;
1700*4882a593Smuzhiyun 	u32 cur_fsp;
1701*4882a593Smuzhiyun 	u32 vref_inner;
1702*4882a593Smuzhiyun 	u32 i;
1703*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
1704*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
1705*4882a593Smuzhiyun 	struct dq_map_info *map_info;
1706*4882a593Smuzhiyun 
1707*4882a593Smuzhiyun 	vref_inner = readl(PHY_REG(phy_base, 0x128)) & 0xff;
1708*4882a593Smuzhiyun 	if (dramtype == DDR3 && vref_inner == 0x80) {
1709*4882a593Smuzhiyun 		for (i = 0; i < 4; i++)
1710*4882a593Smuzhiyun 			writel(vref_inner - 0xa,
1711*4882a593Smuzhiyun 			       PHY_REG(phy_base, 0x118 + i * 0x10));
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun 		/* reg_rx_vref_value_update */
1714*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1715*4882a593Smuzhiyun 		clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1716*4882a593Smuzhiyun 	}
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun 	map_info = (struct dq_map_info *)((void *)common_info +
1719*4882a593Smuzhiyun 		index->dq_map_index.offset * 4);
1720*4882a593Smuzhiyun 	/* only 1cs a time, 0:cs0 1 cs1 */
1721*4882a593Smuzhiyun 	if (cs > 1)
1722*4882a593Smuzhiyun 		return -1;
1723*4882a593Smuzhiyun 
1724*4882a593Smuzhiyun 	dqs_default = 0xf;
1725*4882a593Smuzhiyun 	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun 	cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
1728*4882a593Smuzhiyun 	/* config refresh timing */
1729*4882a593Smuzhiyun 	trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
1730*4882a593Smuzhiyun 			   DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32;
1731*4882a593Smuzhiyun 	trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
1732*4882a593Smuzhiyun 			DDR_PCTL2_RFSHTMG) & 0x3ff;
1733*4882a593Smuzhiyun 	/* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */
1734*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff);
1735*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f);
1736*4882a593Smuzhiyun 	/* reg_phy_trfc */
1737*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x);
1738*4882a593Smuzhiyun 	/* reg_max_refi_cnt */
1739*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4);
1740*4882a593Smuzhiyun 
1741*4882a593Smuzhiyun 	/* choose training cs */
1742*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x71), 0x3 << 6, (0x2 >> cs) << 6);
1743*4882a593Smuzhiyun 
1744*4882a593Smuzhiyun 	/* set dq map for ddr4 */
1745*4882a593Smuzhiyun 	if (dramtype == DDR4) {
1746*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0x70), BIT(7));
1747*4882a593Smuzhiyun 		for (i = 0; i < 4; i++) {
1748*4882a593Smuzhiyun 			writel((map_info->ddr4_dq_map[cs * 2] >>
1749*4882a593Smuzhiyun 				((i % 4) * 8)) & 0xff,
1750*4882a593Smuzhiyun 				PHY_REG(phy_base, 0x238 + i));
1751*4882a593Smuzhiyun 			writel((map_info->ddr4_dq_map[cs * 2 + 1] >>
1752*4882a593Smuzhiyun 				((i % 4) * 8)) & 0xff,
1753*4882a593Smuzhiyun 				PHY_REG(phy_base, 0x2b8 + i));
1754*4882a593Smuzhiyun 		}
1755*4882a593Smuzhiyun 	}
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun 	/* cha_l reg_l_rd_train_dqs_default[5:0] */
1758*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x230), 0x3f, dqs_default);
1759*4882a593Smuzhiyun 	/* cha_h reg_h_rd_train_dqs_default[5:0] */
1760*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x234), 0x3f, dqs_default);
1761*4882a593Smuzhiyun 	/* chb_l reg_l_rd_train_dqs_default[5:0] */
1762*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x2b0), 0x3f, dqs_default);
1763*4882a593Smuzhiyun 	/* chb_h reg_h_rd_train_dqs_default[5:0] */
1764*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x2b4), 0x3f, dqs_default);
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun 	/* Choose the read train auto mode */
1767*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x1);
1768*4882a593Smuzhiyun 	/* Enable the auto train of the read train */
1769*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x3);
1770*4882a593Smuzhiyun 
1771*4882a593Smuzhiyun 	/* Wait the train done. */
1772*4882a593Smuzhiyun 	while (1) {
1773*4882a593Smuzhiyun 		if ((readl(PHY_REG(phy_base, 0x93)) >> 7) & 0x1)
1774*4882a593Smuzhiyun 			break;
1775*4882a593Smuzhiyun 
1776*4882a593Smuzhiyun 		udelay(1);
1777*4882a593Smuzhiyun 		if (timeout_us-- == 0) {
1778*4882a593Smuzhiyun 			printascii("error: read training timeout\n");
1779*4882a593Smuzhiyun 			return -1;
1780*4882a593Smuzhiyun 		}
1781*4882a593Smuzhiyun 	}
1782*4882a593Smuzhiyun 
1783*4882a593Smuzhiyun 	/* Check the read train state */
1784*4882a593Smuzhiyun 	if ((readl(PHY_REG(phy_base, 0x240)) & 0x3) ||
1785*4882a593Smuzhiyun 	    (readl(PHY_REG(phy_base, 0x2c0)) & 0x3)) {
1786*4882a593Smuzhiyun 		printascii("error: read training error\n");
1787*4882a593Smuzhiyun 		return -1;
1788*4882a593Smuzhiyun 	}
1789*4882a593Smuzhiyun 
1790*4882a593Smuzhiyun 	/* Exit the Read Training by setting */
1791*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x70), BIT(1));
1792*4882a593Smuzhiyun 
1793*4882a593Smuzhiyun 	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun 	if (dramtype == DDR3 && vref_inner == 0x80) {
1796*4882a593Smuzhiyun 		for (i = 0; i < 4; i++)
1797*4882a593Smuzhiyun 			writel(vref_inner,
1798*4882a593Smuzhiyun 			       PHY_REG(phy_base, 0x118 + i * 0x10));
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 		/* reg_rx_vref_value_update */
1801*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1802*4882a593Smuzhiyun 		clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
1803*4882a593Smuzhiyun 	}
1804*4882a593Smuzhiyun 
1805*4882a593Smuzhiyun 	return 0;
1806*4882a593Smuzhiyun }
1807*4882a593Smuzhiyun 
data_training_wr(struct dram_info * dram,u32 cs,u32 dramtype,u32 mhz,u32 dst_fsp)1808*4882a593Smuzhiyun static int data_training_wr(struct dram_info *dram, u32 cs, u32 dramtype,
1809*4882a593Smuzhiyun 			    u32 mhz, u32 dst_fsp)
1810*4882a593Smuzhiyun {
1811*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
1812*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1813*4882a593Smuzhiyun 	u32 trefi_1x, trfc_1x;
1814*4882a593Smuzhiyun 	u32 dis_auto_zq = 0;
1815*4882a593Smuzhiyun 	u32 timeout_us = 1000;
1816*4882a593Smuzhiyun 	u32 cur_fsp;
1817*4882a593Smuzhiyun 	u32 mr_tmp, cl, cwl, phy_fsp, offset = 0;
1818*4882a593Smuzhiyun 
1819*4882a593Smuzhiyun 	if (dramtype == LPDDR3 && mhz <= 400) {
1820*4882a593Smuzhiyun 		phy_fsp = (readl(PHY_REG(phy_base, 0xc)) >> 0x2) & 0x3;
1821*4882a593Smuzhiyun 		offset = (phy_fsp == 0) ? 0x5 : 0x387 + (phy_fsp - 1) * 3;
1822*4882a593Smuzhiyun 		cl = readl(PHY_REG(phy_base, offset));
1823*4882a593Smuzhiyun 		cwl = readl(PHY_REG(phy_base, offset + 2));
1824*4882a593Smuzhiyun 
1825*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, 0x8);
1826*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, 0x4);
1827*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 2, 0x6, dramtype);
1828*4882a593Smuzhiyun 	}
1829*4882a593Smuzhiyun 
1830*4882a593Smuzhiyun 	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
1831*4882a593Smuzhiyun 
1832*4882a593Smuzhiyun 	/* PHY_0x7b[7:0] reg_train_col_addr[7:0] */
1833*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7b), 0xff, 0x0);
1834*4882a593Smuzhiyun 	/* PHY_0x7c[4:2] reg_train_ba_addr[2:0] */
1835*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x7 << 2, 0x0 << 2);
1836*4882a593Smuzhiyun 	/* PHY_0x7c[1:0] reg_train_col_addr[9:8] */
1837*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3, 0x0);
1838*4882a593Smuzhiyun 	/* PHY_0x7d[7:0] reg_train_row_addr[7:0] */
1839*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7d), 0xff, 0x0);
1840*4882a593Smuzhiyun 	/* PHY_0x7e[7:0] reg_train_row_addr[15:8] */
1841*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7e), 0xff, 0x0);
1842*4882a593Smuzhiyun 
1843*4882a593Smuzhiyun 	/* PHY_0x71[3] wrtrain_check_data_value_random_gen */
1844*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x71), BIT(3));
1845*4882a593Smuzhiyun 
1846*4882a593Smuzhiyun 	/* config refresh timing */
1847*4882a593Smuzhiyun 	cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
1848*4882a593Smuzhiyun 	trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
1849*4882a593Smuzhiyun 			   DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32;
1850*4882a593Smuzhiyun 	trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
1851*4882a593Smuzhiyun 			DDR_PCTL2_RFSHTMG) & 0x3ff;
1852*4882a593Smuzhiyun 	/* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */
1853*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff);
1854*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f);
1855*4882a593Smuzhiyun 	/* reg_phy_trfc */
1856*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x);
1857*4882a593Smuzhiyun 	/* reg_max_refi_cnt */
1858*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4);
1859*4882a593Smuzhiyun 
1860*4882a593Smuzhiyun 	/* choose training cs */
1861*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3 << 6, (0x2 >> cs) << 6);
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	/* PHY_0x7a [4] reg_wr_train_dqs_default_bypass */
1864*4882a593Smuzhiyun 	/* 0: Use the write-leveling value. */
1865*4882a593Smuzhiyun 	/* 1: use reg0x233 0x237 0x2b3 0x2b7 */
1866*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x7a), BIT(4));
1867*4882a593Smuzhiyun 
1868*4882a593Smuzhiyun 	/* PHY_0x7a [0] reg_dq_wr_train_auto */
1869*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x7a), 0x1);
1870*4882a593Smuzhiyun 
1871*4882a593Smuzhiyun 	/* PHY_0x7a [1] reg_dq_wr_train_en */
1872*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
1873*4882a593Smuzhiyun 
1874*4882a593Smuzhiyun 	send_a_refresh(dram);
1875*4882a593Smuzhiyun 
1876*4882a593Smuzhiyun 	while (1) {
1877*4882a593Smuzhiyun 		if ((readl(PHY_REG(phy_base, 0x92)) >> 7) & 0x1)
1878*4882a593Smuzhiyun 			break;
1879*4882a593Smuzhiyun 
1880*4882a593Smuzhiyun 		udelay(1);
1881*4882a593Smuzhiyun 		if (timeout_us-- == 0) {
1882*4882a593Smuzhiyun 			printascii("error: write training timeout\n");
1883*4882a593Smuzhiyun 			while (1)
1884*4882a593Smuzhiyun 				;
1885*4882a593Smuzhiyun 		}
1886*4882a593Smuzhiyun 	}
1887*4882a593Smuzhiyun 
1888*4882a593Smuzhiyun 	/* Check the write train state */
1889*4882a593Smuzhiyun 	if ((readl(PHY_REG(phy_base, 0x90)) >> 5) & 0x7) {
1890*4882a593Smuzhiyun 		printascii("error: write training error\n");
1891*4882a593Smuzhiyun 		return -1;
1892*4882a593Smuzhiyun 	}
1893*4882a593Smuzhiyun 
1894*4882a593Smuzhiyun 	/* PHY_0x7a [1] reg_dq_wr_train_en */
1895*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
1898*4882a593Smuzhiyun 
1899*4882a593Smuzhiyun 	/* save LPDDR4/LPDDR4X write vref to fsp_param for dfs */
1900*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
1901*4882a593Smuzhiyun 		fsp_param[dst_fsp].vref_dq[cs] =
1902*4882a593Smuzhiyun 			((readl(PHY_REG(phy_base, 0x384)) & 0x3f) +
1903*4882a593Smuzhiyun 			 (readl(PHY_REG(phy_base, 0x385)) & 0x3f)) / 2;
1904*4882a593Smuzhiyun 		/* add range info */
1905*4882a593Smuzhiyun 		fsp_param[dst_fsp].vref_dq[cs] |=
1906*4882a593Smuzhiyun 			((readl(PHY_REG(phy_base, 0x7c)) & BIT(5)) << 1);
1907*4882a593Smuzhiyun 	}
1908*4882a593Smuzhiyun 
1909*4882a593Smuzhiyun 	if (dramtype == LPDDR3 && mhz <= 400) {
1910*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, cl);
1911*4882a593Smuzhiyun 		clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, cwl);
1912*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
1913*4882a593Smuzhiyun 			       DDR_PCTL2_INIT3);
1914*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK,
1915*4882a593Smuzhiyun 			      dramtype);
1916*4882a593Smuzhiyun 	}
1917*4882a593Smuzhiyun 
1918*4882a593Smuzhiyun 	return 0;
1919*4882a593Smuzhiyun }
1920*4882a593Smuzhiyun 
data_training(struct dram_info * dram,u32 cs,struct rv1126_sdram_params * sdram_params,u32 dst_fsp,u32 training_flag)1921*4882a593Smuzhiyun static int data_training(struct dram_info *dram, u32 cs,
1922*4882a593Smuzhiyun 			 struct rv1126_sdram_params *sdram_params, u32 dst_fsp,
1923*4882a593Smuzhiyun 			 u32 training_flag)
1924*4882a593Smuzhiyun {
1925*4882a593Smuzhiyun 	u32 ret = 0;
1926*4882a593Smuzhiyun 
1927*4882a593Smuzhiyun 	if (training_flag == FULL_TRAINING)
1928*4882a593Smuzhiyun 		training_flag = READ_GATE_TRAINING | WRITE_LEVELING |
1929*4882a593Smuzhiyun 				WRITE_TRAINING | READ_TRAINING;
1930*4882a593Smuzhiyun 
1931*4882a593Smuzhiyun 	if ((training_flag & WRITE_LEVELING) == WRITE_LEVELING) {
1932*4882a593Smuzhiyun 		ret = data_training_wl(dram, cs,
1933*4882a593Smuzhiyun 				       sdram_params->base.dramtype,
1934*4882a593Smuzhiyun 				       sdram_params->ch.cap_info.rank);
1935*4882a593Smuzhiyun 		if (ret != 0)
1936*4882a593Smuzhiyun 			goto out;
1937*4882a593Smuzhiyun 	}
1938*4882a593Smuzhiyun 
1939*4882a593Smuzhiyun 	if ((training_flag & READ_GATE_TRAINING) == READ_GATE_TRAINING) {
1940*4882a593Smuzhiyun 		ret = data_training_rg(dram, cs,
1941*4882a593Smuzhiyun 				       sdram_params->base.dramtype);
1942*4882a593Smuzhiyun 		if (ret != 0)
1943*4882a593Smuzhiyun 			goto out;
1944*4882a593Smuzhiyun 	}
1945*4882a593Smuzhiyun 
1946*4882a593Smuzhiyun 	if ((training_flag & READ_TRAINING) == READ_TRAINING) {
1947*4882a593Smuzhiyun 		ret = data_training_rd(dram, cs,
1948*4882a593Smuzhiyun 				       sdram_params->base.dramtype,
1949*4882a593Smuzhiyun 				       sdram_params->base.ddr_freq);
1950*4882a593Smuzhiyun 		if (ret != 0)
1951*4882a593Smuzhiyun 			goto out;
1952*4882a593Smuzhiyun 	}
1953*4882a593Smuzhiyun 
1954*4882a593Smuzhiyun 	if ((training_flag & WRITE_TRAINING) == WRITE_TRAINING) {
1955*4882a593Smuzhiyun 		ret = data_training_wr(dram, cs,
1956*4882a593Smuzhiyun 				       sdram_params->base.dramtype,
1957*4882a593Smuzhiyun 				       sdram_params->base.ddr_freq, dst_fsp);
1958*4882a593Smuzhiyun 		if (ret != 0)
1959*4882a593Smuzhiyun 			goto out;
1960*4882a593Smuzhiyun 	}
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun out:
1963*4882a593Smuzhiyun 	return ret;
1964*4882a593Smuzhiyun }
1965*4882a593Smuzhiyun 
get_wrlvl_val(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)1966*4882a593Smuzhiyun static int get_wrlvl_val(struct dram_info *dram,
1967*4882a593Smuzhiyun 			 struct rv1126_sdram_params *sdram_params)
1968*4882a593Smuzhiyun {
1969*4882a593Smuzhiyun 	int i, j, clk_skew;
1970*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
1971*4882a593Smuzhiyun 	u32 lp_stat;
1972*4882a593Smuzhiyun 	int ret;
1973*4882a593Smuzhiyun 
1974*4882a593Smuzhiyun 	lp_stat = low_power_update(dram, 0);
1975*4882a593Smuzhiyun 
1976*4882a593Smuzhiyun 	clk_skew = 0x1f;
1977*4882a593Smuzhiyun 	modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, clk_skew, 3,
1978*4882a593Smuzhiyun 			 sdram_params->base.dramtype);
1979*4882a593Smuzhiyun 
1980*4882a593Smuzhiyun 	ret = data_training(dram, 0, sdram_params, 0, WRITE_LEVELING);
1981*4882a593Smuzhiyun 	if (sdram_params->ch.cap_info.rank == 2)
1982*4882a593Smuzhiyun 		ret |= data_training(dram, 1, sdram_params, 0, WRITE_LEVELING);
1983*4882a593Smuzhiyun 
1984*4882a593Smuzhiyun 	for (j = 0; j < 2; j++)
1985*4882a593Smuzhiyun 		for (i = 0; i < 4; i++)
1986*4882a593Smuzhiyun 			wrlvl_result[j][i] =
1987*4882a593Smuzhiyun 				(readl(PHY_REG(phy_base, wrlvl_result_offset[j][i])) & 0x3f) -
1988*4882a593Smuzhiyun 				clk_skew;
1989*4882a593Smuzhiyun 
1990*4882a593Smuzhiyun 	low_power_update(dram, lp_stat);
1991*4882a593Smuzhiyun 
1992*4882a593Smuzhiyun 	return ret;
1993*4882a593Smuzhiyun }
1994*4882a593Smuzhiyun 
1995*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
init_rw_trn_result_struct(struct rw_trn_result * result,void __iomem * phy_base,u8 cs_num)1996*4882a593Smuzhiyun static void init_rw_trn_result_struct(struct rw_trn_result *result,
1997*4882a593Smuzhiyun 				      void __iomem *phy_base, u8 cs_num)
1998*4882a593Smuzhiyun {
1999*4882a593Smuzhiyun 	int i;
2000*4882a593Smuzhiyun 
2001*4882a593Smuzhiyun 	result->cs_num = cs_num;
2002*4882a593Smuzhiyun 	result->byte_en = readb(PHY_REG(dram_info.phy, 0xf)) &
2003*4882a593Smuzhiyun 			  PHY_DQ_WIDTH_MASK;
2004*4882a593Smuzhiyun 	for (i = 0; i < FSP_NUM; i++)
2005*4882a593Smuzhiyun 		result->fsp_mhz[i] = 0;
2006*4882a593Smuzhiyun }
2007*4882a593Smuzhiyun 
save_rw_trn_min_max(void __iomem * phy_base,struct cs_rw_trn_result * rd_result,struct cs_rw_trn_result * wr_result,u8 byte_en)2008*4882a593Smuzhiyun static void save_rw_trn_min_max(void __iomem *phy_base,
2009*4882a593Smuzhiyun 				struct cs_rw_trn_result *rd_result,
2010*4882a593Smuzhiyun 				struct cs_rw_trn_result *wr_result,
2011*4882a593Smuzhiyun 				u8 byte_en)
2012*4882a593Smuzhiyun {
2013*4882a593Smuzhiyun 	u16 phy_ofs;
2014*4882a593Smuzhiyun 	u8 dqs;
2015*4882a593Smuzhiyun 	u8 dq;
2016*4882a593Smuzhiyun 
2017*4882a593Smuzhiyun 	for (dqs = 0; dqs < BYTE_NUM; dqs++) {
2018*4882a593Smuzhiyun 		if ((byte_en & BIT(dqs)) == 0)
2019*4882a593Smuzhiyun 			continue;
2020*4882a593Smuzhiyun 
2021*4882a593Smuzhiyun 		/* Channel A or B (low or high 16 bit) */
2022*4882a593Smuzhiyun 		phy_ofs = dqs < 2 ? 0x230 : 0x2b0;
2023*4882a593Smuzhiyun 		/* low or high 8 bit */
2024*4882a593Smuzhiyun 		phy_ofs += (dqs & 0x1) == 0 ? 0 : 0x9;
2025*4882a593Smuzhiyun 		for (dq = 0; dq < 8; dq++) {
2026*4882a593Smuzhiyun 			rd_result->dqs[dqs].dq_min[dq] =
2027*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x15 + dq));
2028*4882a593Smuzhiyun 			rd_result->dqs[dqs].dq_max[dq] =
2029*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x27 + dq));
2030*4882a593Smuzhiyun 			wr_result->dqs[dqs].dq_min[dq] =
2031*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x3d + dq));
2032*4882a593Smuzhiyun 			wr_result->dqs[dqs].dq_max[dq] =
2033*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x4f + dq));
2034*4882a593Smuzhiyun 		}
2035*4882a593Smuzhiyun 	}
2036*4882a593Smuzhiyun }
2037*4882a593Smuzhiyun 
save_rw_trn_deskew(void __iomem * phy_base,struct fsp_rw_trn_result * result,u8 cs_num,int min_val,bool rw)2038*4882a593Smuzhiyun static void save_rw_trn_deskew(void __iomem *phy_base,
2039*4882a593Smuzhiyun 			       struct fsp_rw_trn_result *result, u8 cs_num,
2040*4882a593Smuzhiyun 			       int min_val, bool rw)
2041*4882a593Smuzhiyun {
2042*4882a593Smuzhiyun 	u16 phy_ofs;
2043*4882a593Smuzhiyun 	u8 cs;
2044*4882a593Smuzhiyun 	u8 dq;
2045*4882a593Smuzhiyun 
2046*4882a593Smuzhiyun 	result->min_val = min_val;
2047*4882a593Smuzhiyun 
2048*4882a593Smuzhiyun 	for (cs = 0; cs < cs_num; cs++) {
2049*4882a593Smuzhiyun 		phy_ofs = cs == 0 ? 0x170 : 0x1a0;
2050*4882a593Smuzhiyun 		phy_ofs += rw == SKEW_RX_SIGNAL ? 0x1 : 0x17;
2051*4882a593Smuzhiyun 		for (dq = 0; dq < 8; dq++) {
2052*4882a593Smuzhiyun 			result->cs[cs].dqs[0].dq_deskew[dq] =
2053*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + dq));
2054*4882a593Smuzhiyun 			result->cs[cs].dqs[1].dq_deskew[dq] =
2055*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0xb + dq));
2056*4882a593Smuzhiyun 			result->cs[cs].dqs[2].dq_deskew[dq] =
2057*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x60 + dq));
2058*4882a593Smuzhiyun 			result->cs[cs].dqs[3].dq_deskew[dq] =
2059*4882a593Smuzhiyun 				readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + dq));
2060*4882a593Smuzhiyun 		}
2061*4882a593Smuzhiyun 
2062*4882a593Smuzhiyun 		result->cs[cs].dqs[0].dqs_deskew =
2063*4882a593Smuzhiyun 			readb(PHY_REG(phy_base, phy_ofs + 0x8));
2064*4882a593Smuzhiyun 		result->cs[cs].dqs[1].dqs_deskew =
2065*4882a593Smuzhiyun 			readb(PHY_REG(phy_base, phy_ofs + 0xb + 0x8));
2066*4882a593Smuzhiyun 		result->cs[cs].dqs[2].dqs_deskew =
2067*4882a593Smuzhiyun 			readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0x8));
2068*4882a593Smuzhiyun 		result->cs[cs].dqs[3].dqs_deskew =
2069*4882a593Smuzhiyun 			readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + 0x8));
2070*4882a593Smuzhiyun 	}
2071*4882a593Smuzhiyun }
2072*4882a593Smuzhiyun 
save_rw_trn_result_to_ddr(struct rw_trn_result * result)2073*4882a593Smuzhiyun static void save_rw_trn_result_to_ddr(struct rw_trn_result *result)
2074*4882a593Smuzhiyun {
2075*4882a593Smuzhiyun 	result->flag = DDR_DQ_EYE_FLAG;
2076*4882a593Smuzhiyun 	memcpy((void *)(RW_TRN_RESULT_ADDR), result, sizeof(*result));
2077*4882a593Smuzhiyun }
2078*4882a593Smuzhiyun #endif
2079*4882a593Smuzhiyun 
high_freq_training(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,u32 fsp)2080*4882a593Smuzhiyun static int high_freq_training(struct dram_info *dram,
2081*4882a593Smuzhiyun 			      struct rv1126_sdram_params *sdram_params,
2082*4882a593Smuzhiyun 			      u32 fsp)
2083*4882a593Smuzhiyun {
2084*4882a593Smuzhiyun 	u32 i, j;
2085*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
2086*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
2087*4882a593Smuzhiyun 	int min_val;
2088*4882a593Smuzhiyun 	int dqs_skew, clk_skew, ca_skew;
2089*4882a593Smuzhiyun 	u8 byte_en;
2090*4882a593Smuzhiyun 	int ret;
2091*4882a593Smuzhiyun 
2092*4882a593Smuzhiyun 	byte_en = readl(PHY_REG(phy_base, 0xf)) & PHY_DQ_WIDTH_MASK;
2093*4882a593Smuzhiyun 	dqs_skew = 0;
2094*4882a593Smuzhiyun 	for (j = 0; j < sdram_params->ch.cap_info.rank; j++) {
2095*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(wrlvl_result[0]); i++) {
2096*4882a593Smuzhiyun 			if ((byte_en & BIT(i)) != 0)
2097*4882a593Smuzhiyun 				dqs_skew += wrlvl_result[j][i];
2098*4882a593Smuzhiyun 		}
2099*4882a593Smuzhiyun 	}
2100*4882a593Smuzhiyun 	dqs_skew = dqs_skew /
2101*4882a593Smuzhiyun 		   (int)(sdram_params->ch.cap_info.rank * (1 << sdram_params->ch.cap_info.bw));
2102*4882a593Smuzhiyun 
2103*4882a593Smuzhiyun 	clk_skew = 0x20 - dqs_skew;
2104*4882a593Smuzhiyun 	dqs_skew = 0x20;
2105*4882a593Smuzhiyun 
2106*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
2107*4882a593Smuzhiyun 		min_val = 0xff;
2108*4882a593Smuzhiyun 		for (j = 0; j < sdram_params->ch.cap_info.rank; j++)
2109*4882a593Smuzhiyun 			for (i = 0; i < ARRAY_SIZE(wrlvl_result[0]); i++) {
2110*4882a593Smuzhiyun 				if ((byte_en & BIT(i)) != 0)
2111*4882a593Smuzhiyun 					min_val = MIN(wrlvl_result[j][i], min_val);
2112*4882a593Smuzhiyun 			}
2113*4882a593Smuzhiyun 
2114*4882a593Smuzhiyun 		if (min_val < 0) {
2115*4882a593Smuzhiyun 			clk_skew = -min_val;
2116*4882a593Smuzhiyun 			ca_skew = -min_val;
2117*4882a593Smuzhiyun 		} else {
2118*4882a593Smuzhiyun 			clk_skew = 0;
2119*4882a593Smuzhiyun 			ca_skew = 0;
2120*4882a593Smuzhiyun 		}
2121*4882a593Smuzhiyun 	} else if (dramtype == LPDDR3) {
2122*4882a593Smuzhiyun 		ca_skew = clk_skew - 4;
2123*4882a593Smuzhiyun 	} else {
2124*4882a593Smuzhiyun 		ca_skew = clk_skew;
2125*4882a593Smuzhiyun 	}
2126*4882a593Smuzhiyun 	modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, ca_skew, 3,
2127*4882a593Smuzhiyun 			 dramtype);
2128*4882a593Smuzhiyun 
2129*4882a593Smuzhiyun 	writel(wrlvl_result[0][0] + clk_skew, PHY_REG(phy_base, 0x233));
2130*4882a593Smuzhiyun 	writel(wrlvl_result[0][1] + clk_skew, PHY_REG(phy_base, 0x237));
2131*4882a593Smuzhiyun 	writel(wrlvl_result[0][2] + clk_skew, PHY_REG(phy_base, 0x2b3));
2132*4882a593Smuzhiyun 	writel(wrlvl_result[0][3] + clk_skew, PHY_REG(phy_base, 0x2b7));
2133*4882a593Smuzhiyun 	ret = data_training(dram, 0, sdram_params, fsp, READ_GATE_TRAINING |
2134*4882a593Smuzhiyun 			    READ_TRAINING | WRITE_TRAINING);
2135*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
2136*4882a593Smuzhiyun 	rw_trn_result.fsp_mhz[fsp] = (u16)sdram_params->base.ddr_freq;
2137*4882a593Smuzhiyun 	save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[0],
2138*4882a593Smuzhiyun 			    &rw_trn_result.wr_fsp[fsp].cs[0],
2139*4882a593Smuzhiyun 			    rw_trn_result.byte_en);
2140*4882a593Smuzhiyun #endif
2141*4882a593Smuzhiyun 	if (sdram_params->ch.cap_info.rank == 2) {
2142*4882a593Smuzhiyun 		writel(wrlvl_result[1][0] + clk_skew, PHY_REG(phy_base, 0x233));
2143*4882a593Smuzhiyun 		writel(wrlvl_result[1][1] + clk_skew, PHY_REG(phy_base, 0x237));
2144*4882a593Smuzhiyun 		writel(wrlvl_result[1][2] + clk_skew, PHY_REG(phy_base, 0x2b3));
2145*4882a593Smuzhiyun 		writel(wrlvl_result[1][3] + clk_skew, PHY_REG(phy_base, 0x2b7));
2146*4882a593Smuzhiyun 		ret |= data_training(dram, 1, sdram_params, fsp,
2147*4882a593Smuzhiyun 				     READ_GATE_TRAINING | READ_TRAINING |
2148*4882a593Smuzhiyun 				     WRITE_TRAINING);
2149*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
2150*4882a593Smuzhiyun 		save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[1],
2151*4882a593Smuzhiyun 				    &rw_trn_result.wr_fsp[fsp].cs[1],
2152*4882a593Smuzhiyun 				    rw_trn_result.byte_en);
2153*4882a593Smuzhiyun #endif
2154*4882a593Smuzhiyun 	}
2155*4882a593Smuzhiyun 	if (ret)
2156*4882a593Smuzhiyun 		goto out;
2157*4882a593Smuzhiyun 
2158*4882a593Smuzhiyun 	record_dq_prebit(dram);
2159*4882a593Smuzhiyun 
2160*4882a593Smuzhiyun 	min_val = get_min_value(dram, SKEW_RX_SIGNAL,
2161*4882a593Smuzhiyun 				sdram_params->ch.cap_info.rank) * -1;
2162*4882a593Smuzhiyun 	modify_dq_deskew(dram, SKEW_RX_SIGNAL, DESKEW_MDF_DIFF_VAL,
2163*4882a593Smuzhiyun 			 min_val, min_val, sdram_params->ch.cap_info.rank);
2164*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
2165*4882a593Smuzhiyun 	save_rw_trn_deskew(phy_base, &rw_trn_result.rd_fsp[fsp],
2166*4882a593Smuzhiyun 			   rw_trn_result.cs_num, (u8)(min_val * (-1)),
2167*4882a593Smuzhiyun 			   SKEW_RX_SIGNAL);
2168*4882a593Smuzhiyun #endif
2169*4882a593Smuzhiyun 
2170*4882a593Smuzhiyun 	min_val = MIN(get_min_value(dram, SKEW_TX_SIGNAL,
2171*4882a593Smuzhiyun 				    sdram_params->ch.cap_info.rank),
2172*4882a593Smuzhiyun 		      get_min_value(dram, SKEW_CA_SIGNAL,
2173*4882a593Smuzhiyun 				    sdram_params->ch.cap_info.rank)) * -1;
2174*4882a593Smuzhiyun 
2175*4882a593Smuzhiyun 	/* clk = 0, rx all skew -7, tx - min_value */
2176*4882a593Smuzhiyun 	modify_ca_deskew(dram, DESKEW_MDF_DIFF_VAL, min_val, min_val, 3,
2177*4882a593Smuzhiyun 			 dramtype);
2178*4882a593Smuzhiyun 
2179*4882a593Smuzhiyun 	modify_dq_deskew(dram, SKEW_TX_SIGNAL, DESKEW_MDF_DIFF_VAL,
2180*4882a593Smuzhiyun 			 min_val, min_val, sdram_params->ch.cap_info.rank);
2181*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
2182*4882a593Smuzhiyun 	save_rw_trn_deskew(phy_base, &rw_trn_result.wr_fsp[fsp],
2183*4882a593Smuzhiyun 			   rw_trn_result.cs_num, (u8)(min_val * (-1)),
2184*4882a593Smuzhiyun 			   SKEW_TX_SIGNAL);
2185*4882a593Smuzhiyun #endif
2186*4882a593Smuzhiyun 
2187*4882a593Smuzhiyun 	ret = data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING);
2188*4882a593Smuzhiyun 	if (sdram_params->ch.cap_info.rank == 2)
2189*4882a593Smuzhiyun 		ret |= data_training(dram, 1, sdram_params, 0,
2190*4882a593Smuzhiyun 				     READ_GATE_TRAINING);
2191*4882a593Smuzhiyun out:
2192*4882a593Smuzhiyun 	return ret;
2193*4882a593Smuzhiyun }
2194*4882a593Smuzhiyun 
set_ddrconfig(struct dram_info * dram,u32 ddrconfig)2195*4882a593Smuzhiyun static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
2196*4882a593Smuzhiyun {
2197*4882a593Smuzhiyun 	writel(ddrconfig, &dram->msch->deviceconf);
2198*4882a593Smuzhiyun 	clrsetbits_le32(&dram->grf->noc_con0, 0x3 << 0, 0 << 0);
2199*4882a593Smuzhiyun }
2200*4882a593Smuzhiyun 
update_noc_timing(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2201*4882a593Smuzhiyun static void update_noc_timing(struct dram_info *dram,
2202*4882a593Smuzhiyun 			      struct rv1126_sdram_params *sdram_params)
2203*4882a593Smuzhiyun {
2204*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2205*4882a593Smuzhiyun 	u32 bw, bl;
2206*4882a593Smuzhiyun 
2207*4882a593Smuzhiyun 	bw = 8 << sdram_params->ch.cap_info.bw;
2208*4882a593Smuzhiyun 	bl = ((readl(pctl_base + DDR_PCTL2_MSTR) >> 16) & 0xf) * 2;
2209*4882a593Smuzhiyun 
2210*4882a593Smuzhiyun 	/* update the noc timing related to data bus width */
2211*4882a593Smuzhiyun 	if ((bw / 8 * bl) <= 16)
2212*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode.b.burstsize = 0;
2213*4882a593Smuzhiyun 	else if ((bw / 8 * bl) == 32)
2214*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode.b.burstsize = 1;
2215*4882a593Smuzhiyun 	else if ((bw / 8 * bl) == 64)
2216*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode.b.burstsize = 2;
2217*4882a593Smuzhiyun 	else
2218*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode.b.burstsize = 3;
2219*4882a593Smuzhiyun 
2220*4882a593Smuzhiyun 	sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty =
2221*4882a593Smuzhiyun 		(bl * bw / 8) > 16 ? (bl / 4) : (16 / (bl * bw / 8)) * bl / 4;
2222*4882a593Smuzhiyun 
2223*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR4 ||
2224*4882a593Smuzhiyun 	    sdram_params->base.dramtype == LPDDR4X) {
2225*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode.b.mwrsize =
2226*4882a593Smuzhiyun 			(bw == 16) ? 0x1 : 0x2;
2227*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrtimingc0.b.wrtomwr =
2228*4882a593Smuzhiyun 			3 * sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty;
2229*4882a593Smuzhiyun 	}
2230*4882a593Smuzhiyun 
2231*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.ddrtiminga0.d32,
2232*4882a593Smuzhiyun 	       &dram->msch->ddrtiminga0);
2233*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.ddrtimingb0.d32,
2234*4882a593Smuzhiyun 	       &dram->msch->ddrtimingb0);
2235*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.ddrtimingc0.d32,
2236*4882a593Smuzhiyun 	       &dram->msch->ddrtimingc0);
2237*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.devtodev0.d32,
2238*4882a593Smuzhiyun 	       &dram->msch->devtodev0);
2239*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
2240*4882a593Smuzhiyun 	writel(sdram_params->ch.noc_timings.ddr4timing.d32,
2241*4882a593Smuzhiyun 	       &dram->msch->ddr4timing);
2242*4882a593Smuzhiyun }
2243*4882a593Smuzhiyun 
split_setup(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2244*4882a593Smuzhiyun static int split_setup(struct dram_info *dram,
2245*4882a593Smuzhiyun 		       struct rv1126_sdram_params *sdram_params)
2246*4882a593Smuzhiyun {
2247*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2248*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
2249*4882a593Smuzhiyun 	u32 split_size, split_mode;
2250*4882a593Smuzhiyun 	u64 cs_cap[2], cap;
2251*4882a593Smuzhiyun 
2252*4882a593Smuzhiyun 	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dramtype);
2253*4882a593Smuzhiyun 	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dramtype);
2254*4882a593Smuzhiyun 	/* only support the larger cap is in low 16bit */
2255*4882a593Smuzhiyun 	if (cap_info->cs0_high16bit_row < cap_info->cs0_row) {
2256*4882a593Smuzhiyun 		cap = cs_cap[0] / (1 << (cap_info->cs0_row -
2257*4882a593Smuzhiyun 		cap_info->cs0_high16bit_row));
2258*4882a593Smuzhiyun 	} else if ((cap_info->cs1_high16bit_row < cap_info->cs1_row) &&
2259*4882a593Smuzhiyun 		   (cap_info->rank == 2)) {
2260*4882a593Smuzhiyun 		if (!cap_info->cs1_high16bit_row)
2261*4882a593Smuzhiyun 			cap = cs_cap[0];
2262*4882a593Smuzhiyun 		else
2263*4882a593Smuzhiyun 			cap = cs_cap[0] + cs_cap[1] / (1 << (cap_info->cs1_row -
2264*4882a593Smuzhiyun 				cap_info->cs1_high16bit_row));
2265*4882a593Smuzhiyun 	} else {
2266*4882a593Smuzhiyun 		goto out;
2267*4882a593Smuzhiyun 	}
2268*4882a593Smuzhiyun 	split_size = (u32)(cap >> 24) & SPLIT_SIZE_MASK;
2269*4882a593Smuzhiyun 	if (cap_info->bw == 2)
2270*4882a593Smuzhiyun 		split_mode = SPLIT_MODE_32_L16_VALID;
2271*4882a593Smuzhiyun 	else
2272*4882a593Smuzhiyun 		split_mode = SPLIT_MODE_16_L8_VALID;
2273*4882a593Smuzhiyun 
2274*4882a593Smuzhiyun 	rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con,
2275*4882a593Smuzhiyun 		     (SPLIT_MODE_MASK << SPLIT_MODE_OFFSET) |
2276*4882a593Smuzhiyun 		     (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) |
2277*4882a593Smuzhiyun 		     (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET),
2278*4882a593Smuzhiyun 		     (split_mode << SPLIT_MODE_OFFSET) |
2279*4882a593Smuzhiyun 		     (0x0 << SPLIT_BYPASS_OFFSET) |
2280*4882a593Smuzhiyun 		     (split_size << SPLIT_SIZE_OFFSET));
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun 	rk_clrsetreg(BUS_SGRF_BASE_ADDR + SGRF_SOC_CON2,
2283*4882a593Smuzhiyun 		     MSCH_AXI_BYPASS_ALL_MASK << MSCH_AXI_BYPASS_ALL_SHIFT,
2284*4882a593Smuzhiyun 		     0x0 << MSCH_AXI_BYPASS_ALL_SHIFT);
2285*4882a593Smuzhiyun 
2286*4882a593Smuzhiyun out:
2287*4882a593Smuzhiyun 	return 0;
2288*4882a593Smuzhiyun }
2289*4882a593Smuzhiyun 
split_bypass(struct dram_info * dram)2290*4882a593Smuzhiyun static void split_bypass(struct dram_info *dram)
2291*4882a593Smuzhiyun {
2292*4882a593Smuzhiyun 	if ((readl(&dram->ddrgrf->grf_ddrsplit_con) &
2293*4882a593Smuzhiyun 	     (1 << SPLIT_BYPASS_OFFSET)) != 0)
2294*4882a593Smuzhiyun 		return;
2295*4882a593Smuzhiyun 
2296*4882a593Smuzhiyun 	/* bypass split */
2297*4882a593Smuzhiyun 	rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con,
2298*4882a593Smuzhiyun 		     (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) |
2299*4882a593Smuzhiyun 		     (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET),
2300*4882a593Smuzhiyun 		     (0x1 << SPLIT_BYPASS_OFFSET) |
2301*4882a593Smuzhiyun 		     (0x0 << SPLIT_SIZE_OFFSET));
2302*4882a593Smuzhiyun }
2303*4882a593Smuzhiyun 
dram_all_config(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2304*4882a593Smuzhiyun static void dram_all_config(struct dram_info *dram,
2305*4882a593Smuzhiyun 			    struct rv1126_sdram_params *sdram_params)
2306*4882a593Smuzhiyun {
2307*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2308*4882a593Smuzhiyun 	u32 dram_type = sdram_params->base.dramtype;
2309*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2310*4882a593Smuzhiyun 	u32 sys_reg2 = 0;
2311*4882a593Smuzhiyun 	u32 sys_reg3 = 0;
2312*4882a593Smuzhiyun 	u64 cs_cap[2];
2313*4882a593Smuzhiyun 	u32 cs_pst;
2314*4882a593Smuzhiyun 
2315*4882a593Smuzhiyun 	set_ddrconfig(dram, cap_info->ddrconfig);
2316*4882a593Smuzhiyun 	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
2317*4882a593Smuzhiyun 			 &sys_reg3, 0);
2318*4882a593Smuzhiyun 	writel(sys_reg2, &dram->pmugrf->os_reg[2]);
2319*4882a593Smuzhiyun 	writel(sys_reg3, &dram->pmugrf->os_reg[3]);
2320*4882a593Smuzhiyun 
2321*4882a593Smuzhiyun 	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dram_type);
2322*4882a593Smuzhiyun 	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dram_type);
2323*4882a593Smuzhiyun 
2324*4882a593Smuzhiyun 	if (cap_info->rank == 2) {
2325*4882a593Smuzhiyun 		cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) +
2326*4882a593Smuzhiyun 			6 + 2;
2327*4882a593Smuzhiyun 		if (cs_pst > 28)
2328*4882a593Smuzhiyun 			cs_cap[0] = 1llu << cs_pst;
2329*4882a593Smuzhiyun 	}
2330*4882a593Smuzhiyun 
2331*4882a593Smuzhiyun 	writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
2332*4882a593Smuzhiyun 			(((cs_cap[0] >> 20) / 64) & 0xff),
2333*4882a593Smuzhiyun 			&dram->msch->devicesize);
2334*4882a593Smuzhiyun 	update_noc_timing(dram, sdram_params);
2335*4882a593Smuzhiyun }
2336*4882a593Smuzhiyun 
enable_low_power(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2337*4882a593Smuzhiyun static void enable_low_power(struct dram_info *dram,
2338*4882a593Smuzhiyun 			     struct rv1126_sdram_params *sdram_params)
2339*4882a593Smuzhiyun {
2340*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2341*4882a593Smuzhiyun 	u32 grf_lp_con;
2342*4882a593Smuzhiyun 
2343*4882a593Smuzhiyun 	writel(0x1f1f0617, &dram->ddrgrf->ddr_grf_con[1]);
2344*4882a593Smuzhiyun 
2345*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4)
2346*4882a593Smuzhiyun 		grf_lp_con = (0x7 << 16) | (1 << 1);
2347*4882a593Smuzhiyun 	else if (sdram_params->base.dramtype == DDR3)
2348*4882a593Smuzhiyun 		grf_lp_con = (0x7 << 16) | (1 << 0);
2349*4882a593Smuzhiyun 	else
2350*4882a593Smuzhiyun 		grf_lp_con = (0x7 << 16) | (1 << 2);
2351*4882a593Smuzhiyun 
2352*4882a593Smuzhiyun 	/* en lpckdis_en */
2353*4882a593Smuzhiyun 	grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
2354*4882a593Smuzhiyun 	writel(grf_lp_con, &dram->ddrgrf->ddr_grf_lp_con);
2355*4882a593Smuzhiyun 
2356*4882a593Smuzhiyun 	/* enable sr, pd */
2357*4882a593Smuzhiyun 	if (dram->pd_idle == 0)
2358*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
2359*4882a593Smuzhiyun 	else
2360*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
2361*4882a593Smuzhiyun 	if (dram->sr_idle == 0)
2362*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
2363*4882a593Smuzhiyun 	else
2364*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
2365*4882a593Smuzhiyun 	setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
2366*4882a593Smuzhiyun }
2367*4882a593Smuzhiyun 
ddr_set_atags(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2368*4882a593Smuzhiyun static void ddr_set_atags(struct dram_info *dram,
2369*4882a593Smuzhiyun 			  struct rv1126_sdram_params *sdram_params)
2370*4882a593Smuzhiyun {
2371*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2372*4882a593Smuzhiyun 	u32 dram_type = sdram_params->base.dramtype;
2373*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2374*4882a593Smuzhiyun 	struct tag_serial t_serial;
2375*4882a593Smuzhiyun 	struct tag_ddr_mem t_ddrmem;
2376*4882a593Smuzhiyun 	struct tag_soc_info t_socinfo;
2377*4882a593Smuzhiyun 	u64 cs_cap[2];
2378*4882a593Smuzhiyun 	u32 cs_pst = 0;
2379*4882a593Smuzhiyun 	u32 split, split_size;
2380*4882a593Smuzhiyun 	u64 reduce_cap = 0;
2381*4882a593Smuzhiyun 
2382*4882a593Smuzhiyun 	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dram_type);
2383*4882a593Smuzhiyun 	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dram_type);
2384*4882a593Smuzhiyun 
2385*4882a593Smuzhiyun 	memset(&t_serial, 0, sizeof(struct tag_serial));
2386*4882a593Smuzhiyun 
2387*4882a593Smuzhiyun 	t_serial.version = 0;
2388*4882a593Smuzhiyun 	t_serial.enable = 1;
2389*4882a593Smuzhiyun 	t_serial.addr = CONFIG_DEBUG_UART_BASE;
2390*4882a593Smuzhiyun 	t_serial.baudrate = CONFIG_BAUDRATE;
2391*4882a593Smuzhiyun 	t_serial.m_mode = SERIAL_M_MODE_M0;
2392*4882a593Smuzhiyun 	t_serial.id = 2;
2393*4882a593Smuzhiyun 
2394*4882a593Smuzhiyun 	atags_destroy();
2395*4882a593Smuzhiyun 	atags_set_tag(ATAG_SERIAL, &t_serial);
2396*4882a593Smuzhiyun 
2397*4882a593Smuzhiyun 	split = readl(&dram->ddrgrf->grf_ddrsplit_con);
2398*4882a593Smuzhiyun 	memset(&t_ddrmem, 0, sizeof(struct tag_ddr_mem));
2399*4882a593Smuzhiyun 	if (cap_info->row_3_4) {
2400*4882a593Smuzhiyun 		cs_cap[0] =  cs_cap[0] * 3 / 4;
2401*4882a593Smuzhiyun 		cs_cap[1] =  cs_cap[1] * 3 / 4;
2402*4882a593Smuzhiyun 	} else if (!(split & (1 << SPLIT_BYPASS_OFFSET))) {
2403*4882a593Smuzhiyun 		split_size = (split >> SPLIT_SIZE_OFFSET) & SPLIT_SIZE_MASK;
2404*4882a593Smuzhiyun 		reduce_cap = (cs_cap[0] + cs_cap[1] - (split_size << 24)) / 2;
2405*4882a593Smuzhiyun 	}
2406*4882a593Smuzhiyun 	t_ddrmem.version = 0;
2407*4882a593Smuzhiyun 	t_ddrmem.bank[0] = CONFIG_SYS_SDRAM_BASE;
2408*4882a593Smuzhiyun 	if (cs_cap[1]) {
2409*4882a593Smuzhiyun 		cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) +
2410*4882a593Smuzhiyun 			6 + 2;
2411*4882a593Smuzhiyun 	}
2412*4882a593Smuzhiyun 
2413*4882a593Smuzhiyun 	if (cs_cap[1] && cs_pst > 27) {
2414*4882a593Smuzhiyun 		t_ddrmem.count = 2;
2415*4882a593Smuzhiyun 		t_ddrmem.bank[1] = 1 << cs_pst;
2416*4882a593Smuzhiyun 		t_ddrmem.bank[2] = cs_cap[0];
2417*4882a593Smuzhiyun 		t_ddrmem.bank[3] = cs_cap[1] - reduce_cap;
2418*4882a593Smuzhiyun 	} else {
2419*4882a593Smuzhiyun 		t_ddrmem.count = 1;
2420*4882a593Smuzhiyun 		t_ddrmem.bank[1] = (u64)cs_cap[0] + (u64)cs_cap[1] - reduce_cap;
2421*4882a593Smuzhiyun 	}
2422*4882a593Smuzhiyun 
2423*4882a593Smuzhiyun 	atags_set_tag(ATAG_DDR_MEM, &t_ddrmem);
2424*4882a593Smuzhiyun 
2425*4882a593Smuzhiyun 	memset(&t_socinfo, 0, sizeof(struct tag_soc_info));
2426*4882a593Smuzhiyun 	t_socinfo.version = 0x1;
2427*4882a593Smuzhiyun 	t_socinfo.name = 0x1126;
2428*4882a593Smuzhiyun 	t_socinfo.flags = SOC_FLAGS_TDBT;
2429*4882a593Smuzhiyun 	atags_set_tag(ATAG_SOC_INFO, &t_socinfo);
2430*4882a593Smuzhiyun }
2431*4882a593Smuzhiyun 
print_ddr_info(struct rv1126_sdram_params * sdram_params)2432*4882a593Smuzhiyun static void print_ddr_info(struct rv1126_sdram_params *sdram_params)
2433*4882a593Smuzhiyun {
2434*4882a593Smuzhiyun 	u32 split;
2435*4882a593Smuzhiyun 
2436*4882a593Smuzhiyun 	if ((readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) &
2437*4882a593Smuzhiyun 	     (1 << SPLIT_BYPASS_OFFSET)) != 0)
2438*4882a593Smuzhiyun 		split = 0;
2439*4882a593Smuzhiyun 	else
2440*4882a593Smuzhiyun 		split = readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) &
2441*4882a593Smuzhiyun 			SPLIT_SIZE_MASK;
2442*4882a593Smuzhiyun 
2443*4882a593Smuzhiyun 	sdram_print_ddr_info(&sdram_params->ch.cap_info,
2444*4882a593Smuzhiyun 			     &sdram_params->base, split);
2445*4882a593Smuzhiyun }
2446*4882a593Smuzhiyun 
modify_ddr34_bw_byte_map(u8 rg_result,struct rv1126_sdram_params * sdram_params)2447*4882a593Smuzhiyun static int modify_ddr34_bw_byte_map(u8 rg_result, struct rv1126_sdram_params *sdram_params)
2448*4882a593Smuzhiyun {
2449*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index = (struct sdram_head_info_index_v2 *)common_info;
2450*4882a593Smuzhiyun 	struct dq_map_info *map_info = (struct dq_map_info *)
2451*4882a593Smuzhiyun 				       ((void *)common_info + index->dq_map_index.offset * 4);
2452*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2453*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
2454*4882a593Smuzhiyun 	u32 byte_map = 0;
2455*4882a593Smuzhiyun 	u32 byte = 0;
2456*4882a593Smuzhiyun 	u32 byte_map_shift;
2457*4882a593Smuzhiyun 	int i;
2458*4882a593Smuzhiyun 
2459*4882a593Smuzhiyun 	if (dramtype == DDR3)
2460*4882a593Smuzhiyun 		byte_map_shift = 24;
2461*4882a593Smuzhiyun 	else if (dramtype == DDR4)
2462*4882a593Smuzhiyun 		byte_map_shift = 0;
2463*4882a593Smuzhiyun 	else
2464*4882a593Smuzhiyun 		return -1;
2465*4882a593Smuzhiyun 
2466*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
2467*4882a593Smuzhiyun 		if ((rg_result & BIT(i)) == 0) {
2468*4882a593Smuzhiyun 			byte_map |= byte << (i * 2);
2469*4882a593Smuzhiyun 			byte++;
2470*4882a593Smuzhiyun 		}
2471*4882a593Smuzhiyun 	}
2472*4882a593Smuzhiyun 	if (byte != 1 && byte != 2 && byte != 4) {
2473*4882a593Smuzhiyun 		printascii("DTT result is abnormal: ");
2474*4882a593Smuzhiyun 		printdec(byte);
2475*4882a593Smuzhiyun 		printascii("byte\n");
2476*4882a593Smuzhiyun 		return -1;
2477*4882a593Smuzhiyun 	}
2478*4882a593Smuzhiyun 	cap_info->bw = byte / 2;
2479*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
2480*4882a593Smuzhiyun 		if ((rg_result & BIT(i)) != 0) {
2481*4882a593Smuzhiyun 			byte_map |= byte << (i * 2);
2482*4882a593Smuzhiyun 			byte++;
2483*4882a593Smuzhiyun 		}
2484*4882a593Smuzhiyun 	}
2485*4882a593Smuzhiyun 
2486*4882a593Smuzhiyun 	if ((u8)byte_map != (u8)(map_info->byte_map[0] >> byte_map_shift)) {
2487*4882a593Smuzhiyun 		clrsetbits_le32(&map_info->byte_map[0],
2488*4882a593Smuzhiyun 				0xff << byte_map_shift, byte_map << byte_map_shift);
2489*4882a593Smuzhiyun 		pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info, dramtype);
2490*4882a593Smuzhiyun 		return 1;
2491*4882a593Smuzhiyun 	}
2492*4882a593Smuzhiyun 
2493*4882a593Smuzhiyun 	return 0;
2494*4882a593Smuzhiyun }
2495*4882a593Smuzhiyun 
sdram_init_(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,u32 post_init)2496*4882a593Smuzhiyun int sdram_init_(struct dram_info *dram, struct rv1126_sdram_params *sdram_params, u32 post_init)
2497*4882a593Smuzhiyun {
2498*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2499*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
2500*4882a593Smuzhiyun 	u32 ddr4_vref;
2501*4882a593Smuzhiyun 	u32 mr_tmp, tmp;
2502*4882a593Smuzhiyun 	int delay = 1000;
2503*4882a593Smuzhiyun 
2504*4882a593Smuzhiyun 	rkclk_configure_ddr(dram, sdram_params);
2505*4882a593Smuzhiyun 
2506*4882a593Smuzhiyun 	rkclk_ddr_reset(dram, 1, 1, 1, 1);
2507*4882a593Smuzhiyun 	udelay(10);
2508*4882a593Smuzhiyun 
2509*4882a593Smuzhiyun 	rkclk_ddr_reset(dram, 1, 1, 1, 0);
2510*4882a593Smuzhiyun 	phy_cfg(dram, sdram_params);
2511*4882a593Smuzhiyun 
2512*4882a593Smuzhiyun 	rkclk_ddr_reset(dram, 1, 1, 0, 0);
2513*4882a593Smuzhiyun 	phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 1);
2514*4882a593Smuzhiyun 
2515*4882a593Smuzhiyun 	rkclk_ddr_reset(dram, 1, 0, 0, 0);
2516*4882a593Smuzhiyun 	pctl_cfg(dram->pctl, &sdram_params->pctl_regs,
2517*4882a593Smuzhiyun 		 dram->sr_idle, dram->pd_idle);
2518*4882a593Smuzhiyun 
2519*4882a593Smuzhiyun 	if (sdram_params->ch.cap_info.bw == 2) {
2520*4882a593Smuzhiyun 		/* 32bit interface use pageclose */
2521*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2);
2522*4882a593Smuzhiyun 		/* pageclose = 1, pageclose_timer = 0 will err in lp4 328MHz */
2523*4882a593Smuzhiyun 		clrsetbits_le32(pctl_base + DDR_PCTL2_SCHED1, 0xff, 0x1 << 0);
2524*4882a593Smuzhiyun 	} else {
2525*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2);
2526*4882a593Smuzhiyun 	}
2527*4882a593Smuzhiyun 
2528*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
2529*4882a593Smuzhiyun 	u32 trefi;
2530*4882a593Smuzhiyun 
2531*4882a593Smuzhiyun 	tmp = readl(pctl_base + DDR_PCTL2_RFSHTMG);
2532*4882a593Smuzhiyun 	trefi = (tmp >> 16) & 0xfff;
2533*4882a593Smuzhiyun 	writel((tmp & 0xf000ffff) | (trefi / 2) << 16,
2534*4882a593Smuzhiyun 	       pctl_base + DDR_PCTL2_RFSHTMG);
2535*4882a593Smuzhiyun #endif
2536*4882a593Smuzhiyun 
2537*4882a593Smuzhiyun 	/* set frequency_mode */
2538*4882a593Smuzhiyun 	setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29);
2539*4882a593Smuzhiyun 	/* set target_frequency to Frequency 0 */
2540*4882a593Smuzhiyun 	clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, 0);
2541*4882a593Smuzhiyun 
2542*4882a593Smuzhiyun 	set_ds_odt(dram, sdram_params, 0);
2543*4882a593Smuzhiyun 	sdram_params->ch.cap_info.ddrconfig = calculate_ddrconfig(sdram_params);
2544*4882a593Smuzhiyun 	set_ctl_address_map(dram, sdram_params);
2545*4882a593Smuzhiyun 
2546*4882a593Smuzhiyun 	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
2547*4882a593Smuzhiyun 
2548*4882a593Smuzhiyun 	rkclk_ddr_reset(dram, 0, 0, 0, 0);
2549*4882a593Smuzhiyun 
2550*4882a593Smuzhiyun 	while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0) {
2551*4882a593Smuzhiyun 		udelay(1);
2552*4882a593Smuzhiyun 		if (delay-- <= 0) {
2553*4882a593Smuzhiyun 			printascii("ERROR: Cannot wait dfi_init_done!\n");
2554*4882a593Smuzhiyun 			while (1)
2555*4882a593Smuzhiyun 				;
2556*4882a593Smuzhiyun 		}
2557*4882a593Smuzhiyun 	}
2558*4882a593Smuzhiyun 
2559*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR3) {
2560*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, LPDDR3);
2561*4882a593Smuzhiyun 	} else if (sdram_params->base.dramtype == LPDDR4 ||
2562*4882a593Smuzhiyun 		   sdram_params->base.dramtype == LPDDR4X) {
2563*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + DDR_PCTL2_INIT6);
2564*4882a593Smuzhiyun 		/* MR11 */
2565*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 11,
2566*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
2567*4882a593Smuzhiyun 			      LPDDR4);
2568*4882a593Smuzhiyun 		/* MR12 */
2569*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 12,
2570*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK,
2571*4882a593Smuzhiyun 			      LPDDR4);
2572*4882a593Smuzhiyun 
2573*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7);
2574*4882a593Smuzhiyun 		/* MR22 */
2575*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 22,
2576*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
2577*4882a593Smuzhiyun 			      LPDDR4);
2578*4882a593Smuzhiyun 	}
2579*4882a593Smuzhiyun 
2580*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR3 && post_init == 0)
2581*4882a593Smuzhiyun 		setbits_le32(PHY_REG(phy_base, 0xf), 0xf);
2582*4882a593Smuzhiyun 	tmp = data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) & 0xf;
2583*4882a593Smuzhiyun 
2584*4882a593Smuzhiyun 	if (tmp != 0) {
2585*4882a593Smuzhiyun 		if (post_init != 0) {
2586*4882a593Smuzhiyun 			printascii("DTT cs0 error\n");
2587*4882a593Smuzhiyun 			return -1;
2588*4882a593Smuzhiyun 		}
2589*4882a593Smuzhiyun 		if (sdram_params->base.dramtype != DDR3 || tmp == 0xf)
2590*4882a593Smuzhiyun 			return -1;
2591*4882a593Smuzhiyun 	}
2592*4882a593Smuzhiyun 
2593*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR3 && post_init == 0) {
2594*4882a593Smuzhiyun 		if (modify_ddr34_bw_byte_map((u8)tmp, sdram_params) != 0)
2595*4882a593Smuzhiyun 			return -1;
2596*4882a593Smuzhiyun 	}
2597*4882a593Smuzhiyun 
2598*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR4) {
2599*4882a593Smuzhiyun 		mr_tmp = read_mr(dram, 1, 14, LPDDR4);
2600*4882a593Smuzhiyun 
2601*4882a593Smuzhiyun 		if (mr_tmp != 0x4d)
2602*4882a593Smuzhiyun 			return -1;
2603*4882a593Smuzhiyun 	}
2604*4882a593Smuzhiyun 
2605*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR4 ||
2606*4882a593Smuzhiyun 	    sdram_params->base.dramtype == LPDDR4X) {
2607*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7);
2608*4882a593Smuzhiyun 		/* MR14 */
2609*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 14,
2610*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
2611*4882a593Smuzhiyun 			      LPDDR4);
2612*4882a593Smuzhiyun 	}
2613*4882a593Smuzhiyun 	if (post_init != 0 && sdram_params->ch.cap_info.rank == 2) {
2614*4882a593Smuzhiyun 		if (data_training(dram, 1, sdram_params, 0,
2615*4882a593Smuzhiyun 				  READ_GATE_TRAINING) != 0) {
2616*4882a593Smuzhiyun 			printascii("DTT cs1 error\n");
2617*4882a593Smuzhiyun 			return -1;
2618*4882a593Smuzhiyun 		}
2619*4882a593Smuzhiyun 	}
2620*4882a593Smuzhiyun 
2621*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR4) {
2622*4882a593Smuzhiyun 		ddr4_vref = readl(PHY_REG(phy_base, 0x105)) * 39;
2623*4882a593Smuzhiyun 		pctl_write_vrefdq(dram->pctl, 0x3, ddr4_vref,
2624*4882a593Smuzhiyun 				  sdram_params->base.dramtype);
2625*4882a593Smuzhiyun 	}
2626*4882a593Smuzhiyun 
2627*4882a593Smuzhiyun 	dram_all_config(dram, sdram_params);
2628*4882a593Smuzhiyun 	enable_low_power(dram, sdram_params);
2629*4882a593Smuzhiyun 
2630*4882a593Smuzhiyun 	return 0;
2631*4882a593Smuzhiyun }
2632*4882a593Smuzhiyun 
dram_detect_cap(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,unsigned char channel)2633*4882a593Smuzhiyun static u64 dram_detect_cap(struct dram_info *dram,
2634*4882a593Smuzhiyun 			   struct rv1126_sdram_params *sdram_params,
2635*4882a593Smuzhiyun 			   unsigned char channel)
2636*4882a593Smuzhiyun {
2637*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2638*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2639*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
2640*4882a593Smuzhiyun 	u32 mr8;
2641*4882a593Smuzhiyun 
2642*4882a593Smuzhiyun 	u32 bktmp;
2643*4882a593Smuzhiyun 	u32 coltmp;
2644*4882a593Smuzhiyun 	u32 rowtmp;
2645*4882a593Smuzhiyun 	u32 cs;
2646*4882a593Smuzhiyun 	u32 dram_type = sdram_params->base.dramtype;
2647*4882a593Smuzhiyun 	u32 pwrctl;
2648*4882a593Smuzhiyun 	u32 i, dq_map;
2649*4882a593Smuzhiyun 	u32 byte1 = 0, byte0 = 0;
2650*4882a593Smuzhiyun 
2651*4882a593Smuzhiyun 	if (dram_type != LPDDR4 && dram_type != LPDDR4X) {
2652*4882a593Smuzhiyun 		if (dram_type != DDR4) {
2653*4882a593Smuzhiyun 			if (dram_type == DDR3)
2654*4882a593Smuzhiyun 				coltmp = 11;
2655*4882a593Smuzhiyun 			else
2656*4882a593Smuzhiyun 				coltmp = 12;
2657*4882a593Smuzhiyun 			bktmp = 3;
2658*4882a593Smuzhiyun 			if (dram_type == LPDDR2)
2659*4882a593Smuzhiyun 				rowtmp = 15;
2660*4882a593Smuzhiyun 			else
2661*4882a593Smuzhiyun 				rowtmp = 16;
2662*4882a593Smuzhiyun 
2663*4882a593Smuzhiyun 			if (sdram_detect_col(cap_info, coltmp) != 0)
2664*4882a593Smuzhiyun 				goto cap_err;
2665*4882a593Smuzhiyun 
2666*4882a593Smuzhiyun 			sdram_detect_bank(cap_info, coltmp, bktmp);
2667*4882a593Smuzhiyun 			if (dram_type != LPDDR3)
2668*4882a593Smuzhiyun 				sdram_detect_dbw(cap_info, dram_type);
2669*4882a593Smuzhiyun 		} else {
2670*4882a593Smuzhiyun 			coltmp = 10;
2671*4882a593Smuzhiyun 			bktmp = 4;
2672*4882a593Smuzhiyun 			rowtmp = 17;
2673*4882a593Smuzhiyun 
2674*4882a593Smuzhiyun 			cap_info->col = 10;
2675*4882a593Smuzhiyun 			cap_info->bk = 2;
2676*4882a593Smuzhiyun 			sdram_detect_bg(cap_info, coltmp);
2677*4882a593Smuzhiyun 		}
2678*4882a593Smuzhiyun 
2679*4882a593Smuzhiyun 		if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
2680*4882a593Smuzhiyun 			goto cap_err;
2681*4882a593Smuzhiyun 
2682*4882a593Smuzhiyun 		sdram_detect_row_3_4(cap_info, coltmp, bktmp);
2683*4882a593Smuzhiyun 	} else {
2684*4882a593Smuzhiyun 		cap_info->col = 10;
2685*4882a593Smuzhiyun 		cap_info->bk = 3;
2686*4882a593Smuzhiyun 		mr8 = read_mr(dram, 1, 8, dram_type);
2687*4882a593Smuzhiyun 		cap_info->dbw = ((mr8 >> 6) & 0x3) == 0 ? 1 : 0;
2688*4882a593Smuzhiyun 		mr8 = (mr8 >> 2) & 0xf;
2689*4882a593Smuzhiyun 		if (mr8 >= 0 && mr8 <= 6) {
2690*4882a593Smuzhiyun 			cap_info->cs0_row = 14 + (mr8 + 1) / 2;
2691*4882a593Smuzhiyun 		} else if (mr8 == 0xc) {
2692*4882a593Smuzhiyun 			cap_info->cs0_row = 13;
2693*4882a593Smuzhiyun 		} else {
2694*4882a593Smuzhiyun 			printascii("Cap ERR: Fail to get cap of LPDDR4/X from MR8\n");
2695*4882a593Smuzhiyun 			goto cap_err;
2696*4882a593Smuzhiyun 		}
2697*4882a593Smuzhiyun 		if (cap_info->dbw == 0)
2698*4882a593Smuzhiyun 			cap_info->cs0_row++;
2699*4882a593Smuzhiyun 		cap_info->row_3_4 = mr8 % 2 == 1 ? 1 : 0;
2700*4882a593Smuzhiyun 		if (cap_info->cs0_row >= 17) {
2701*4882a593Smuzhiyun 			printascii("Cap ERR: ");
2702*4882a593Smuzhiyun 			printascii("RV1126 LPDDR4/X cannot support row >= 17\n");
2703*4882a593Smuzhiyun 			goto cap_err;
2704*4882a593Smuzhiyun 			// cap_info->cs0_row = 16;
2705*4882a593Smuzhiyun 			// cap_info->row_3_4 = 0;
2706*4882a593Smuzhiyun 		}
2707*4882a593Smuzhiyun 	}
2708*4882a593Smuzhiyun 
2709*4882a593Smuzhiyun 	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
2710*4882a593Smuzhiyun 	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
2711*4882a593Smuzhiyun 
2712*4882a593Smuzhiyun 	if (data_training(dram, 1, sdram_params, 0, READ_GATE_TRAINING) == 0)
2713*4882a593Smuzhiyun 		cs = 1;
2714*4882a593Smuzhiyun 	else
2715*4882a593Smuzhiyun 		cs = 0;
2716*4882a593Smuzhiyun 	cap_info->rank = cs + 1;
2717*4882a593Smuzhiyun 
2718*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0xf), 0xf);
2719*4882a593Smuzhiyun 
2720*4882a593Smuzhiyun 	if (dram_type != DDR3) {
2721*4882a593Smuzhiyun 		if ((data_training_rg(dram, 0, dram_type) & 0xf) == 0) {
2722*4882a593Smuzhiyun 			cap_info->bw = 2;
2723*4882a593Smuzhiyun 		} else {
2724*4882a593Smuzhiyun 			dq_map = readl(PHY_REG(phy_base, 0x4f));
2725*4882a593Smuzhiyun 			for (i = 0; i < 4; i++) {
2726*4882a593Smuzhiyun 				if (((dq_map >> (i * 2)) & 0x3) == 0)
2727*4882a593Smuzhiyun 					byte0 = i;
2728*4882a593Smuzhiyun 				if (((dq_map >> (i * 2)) & 0x3) == 1)
2729*4882a593Smuzhiyun 					byte1 = i;
2730*4882a593Smuzhiyun 			}
2731*4882a593Smuzhiyun 			clrsetbits_le32(PHY_REG(phy_base, 0xf), PHY_DQ_WIDTH_MASK,
2732*4882a593Smuzhiyun 					BIT(byte0) | BIT(byte1));
2733*4882a593Smuzhiyun 			if (data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) == 0)
2734*4882a593Smuzhiyun 				cap_info->bw = 1;
2735*4882a593Smuzhiyun 			else
2736*4882a593Smuzhiyun 				cap_info->bw = 0;
2737*4882a593Smuzhiyun 		}
2738*4882a593Smuzhiyun 	}
2739*4882a593Smuzhiyun 	if (cap_info->bw > 0)
2740*4882a593Smuzhiyun 		cap_info->dbw = 1;
2741*4882a593Smuzhiyun 
2742*4882a593Smuzhiyun 	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
2743*4882a593Smuzhiyun 
2744*4882a593Smuzhiyun 	cap_info->cs0_high16bit_row = cap_info->cs0_row;
2745*4882a593Smuzhiyun 	if (cs) {
2746*4882a593Smuzhiyun 		cap_info->cs1_row = cap_info->cs0_row;
2747*4882a593Smuzhiyun 		cap_info->cs1_high16bit_row = cap_info->cs0_row;
2748*4882a593Smuzhiyun 	} else {
2749*4882a593Smuzhiyun 		cap_info->cs1_row = 0;
2750*4882a593Smuzhiyun 		cap_info->cs1_high16bit_row = 0;
2751*4882a593Smuzhiyun 	}
2752*4882a593Smuzhiyun 
2753*4882a593Smuzhiyun 	if (dram_type == LPDDR3)
2754*4882a593Smuzhiyun 		sdram_detect_dbw(cap_info, dram_type);
2755*4882a593Smuzhiyun 
2756*4882a593Smuzhiyun 	return 0;
2757*4882a593Smuzhiyun cap_err:
2758*4882a593Smuzhiyun 	return -1;
2759*4882a593Smuzhiyun }
2760*4882a593Smuzhiyun 
dram_detect_cs1_row(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,unsigned char channel)2761*4882a593Smuzhiyun static int dram_detect_cs1_row(struct dram_info *dram,
2762*4882a593Smuzhiyun 			       struct rv1126_sdram_params *sdram_params,
2763*4882a593Smuzhiyun 			       unsigned char channel)
2764*4882a593Smuzhiyun {
2765*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2766*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2767*4882a593Smuzhiyun 	u32 ret = 0;
2768*4882a593Smuzhiyun 	void __iomem *test_addr;
2769*4882a593Smuzhiyun 	u32 row, bktmp, coltmp, bw;
2770*4882a593Smuzhiyun 	u64 cs0_cap;
2771*4882a593Smuzhiyun 	u32 byte_mask;
2772*4882a593Smuzhiyun 	u32 cs_pst;
2773*4882a593Smuzhiyun 	u32 cs_add = 0;
2774*4882a593Smuzhiyun 	u32 max_row;
2775*4882a593Smuzhiyun 
2776*4882a593Smuzhiyun 	if (cap_info->rank == 2) {
2777*4882a593Smuzhiyun 		cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) +
2778*4882a593Smuzhiyun 			6 + 2;
2779*4882a593Smuzhiyun 		if (cs_pst < 28)
2780*4882a593Smuzhiyun 			cs_add = 1;
2781*4882a593Smuzhiyun 
2782*4882a593Smuzhiyun 		cs0_cap = 1 << cs_pst;
2783*4882a593Smuzhiyun 
2784*4882a593Smuzhiyun 		if (sdram_params->base.dramtype == DDR4) {
2785*4882a593Smuzhiyun 			if (cap_info->dbw == 0)
2786*4882a593Smuzhiyun 				bktmp = cap_info->bk + 2;
2787*4882a593Smuzhiyun 			else
2788*4882a593Smuzhiyun 				bktmp = cap_info->bk + 1;
2789*4882a593Smuzhiyun 		} else {
2790*4882a593Smuzhiyun 			bktmp = cap_info->bk;
2791*4882a593Smuzhiyun 		}
2792*4882a593Smuzhiyun 		bw = cap_info->bw;
2793*4882a593Smuzhiyun 		coltmp = cap_info->col;
2794*4882a593Smuzhiyun 
2795*4882a593Smuzhiyun 		if (bw == 2)
2796*4882a593Smuzhiyun 			byte_mask = 0xFFFF;
2797*4882a593Smuzhiyun 		else
2798*4882a593Smuzhiyun 			byte_mask = 0xFF;
2799*4882a593Smuzhiyun 
2800*4882a593Smuzhiyun 		max_row = (cs_pst == 31) ? 30 : 31;
2801*4882a593Smuzhiyun 
2802*4882a593Smuzhiyun 		max_row = max_row - bktmp - coltmp - bw - cs_add + 1;
2803*4882a593Smuzhiyun 
2804*4882a593Smuzhiyun 		row = (cap_info->cs0_row > max_row) ? max_row :
2805*4882a593Smuzhiyun 			cap_info->cs0_row;
2806*4882a593Smuzhiyun 
2807*4882a593Smuzhiyun 		for (; row > 12; row--) {
2808*4882a593Smuzhiyun 			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
2809*4882a593Smuzhiyun 				    (u32)cs0_cap +
2810*4882a593Smuzhiyun 				    (1ul << (row + bktmp + coltmp +
2811*4882a593Smuzhiyun 					     cs_add + bw - 1ul)));
2812*4882a593Smuzhiyun 
2813*4882a593Smuzhiyun 			writel(0, CONFIG_SYS_SDRAM_BASE + (u32)cs0_cap);
2814*4882a593Smuzhiyun 			writel(PATTERN, test_addr);
2815*4882a593Smuzhiyun 
2816*4882a593Smuzhiyun 			if (((readl(test_addr) & byte_mask) ==
2817*4882a593Smuzhiyun 			     (PATTERN & byte_mask)) &&
2818*4882a593Smuzhiyun 			    ((readl(CONFIG_SYS_SDRAM_BASE + (u32)cs0_cap) &
2819*4882a593Smuzhiyun 			      byte_mask) == 0)) {
2820*4882a593Smuzhiyun 				ret = row;
2821*4882a593Smuzhiyun 				break;
2822*4882a593Smuzhiyun 			}
2823*4882a593Smuzhiyun 		}
2824*4882a593Smuzhiyun 	}
2825*4882a593Smuzhiyun 
2826*4882a593Smuzhiyun 	return ret;
2827*4882a593Smuzhiyun }
2828*4882a593Smuzhiyun 
2829*4882a593Smuzhiyun /* return: 0 = success, other = fail */
sdram_init_detect(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)2830*4882a593Smuzhiyun static int sdram_init_detect(struct dram_info *dram,
2831*4882a593Smuzhiyun 			     struct rv1126_sdram_params *sdram_params)
2832*4882a593Smuzhiyun {
2833*4882a593Smuzhiyun 	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
2834*4882a593Smuzhiyun 	u32 ret;
2835*4882a593Smuzhiyun 	u32 sys_reg = 0;
2836*4882a593Smuzhiyun 	u32 sys_reg3 = 0;
2837*4882a593Smuzhiyun 
2838*4882a593Smuzhiyun 	if (sdram_init_(dram, sdram_params, 0)) {
2839*4882a593Smuzhiyun 		if (sdram_params->base.dramtype == DDR3) {
2840*4882a593Smuzhiyun 			if (sdram_init_(dram, sdram_params, 0))
2841*4882a593Smuzhiyun 				return -1;
2842*4882a593Smuzhiyun 		} else {
2843*4882a593Smuzhiyun 			return -1;
2844*4882a593Smuzhiyun 		}
2845*4882a593Smuzhiyun 	}
2846*4882a593Smuzhiyun 
2847*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR3) {
2848*4882a593Smuzhiyun 		writel(PATTERN, CONFIG_SYS_SDRAM_BASE);
2849*4882a593Smuzhiyun 		if (readl(CONFIG_SYS_SDRAM_BASE) != PATTERN)
2850*4882a593Smuzhiyun 			return -1;
2851*4882a593Smuzhiyun 	}
2852*4882a593Smuzhiyun 
2853*4882a593Smuzhiyun 	split_bypass(dram);
2854*4882a593Smuzhiyun 	if (dram_detect_cap(dram, sdram_params, 0) != 0)
2855*4882a593Smuzhiyun 		return -1;
2856*4882a593Smuzhiyun 
2857*4882a593Smuzhiyun 	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
2858*4882a593Smuzhiyun 				   sdram_params->base.dramtype);
2859*4882a593Smuzhiyun 	ret = sdram_init_(dram, sdram_params, 1);
2860*4882a593Smuzhiyun 	if (ret != 0)
2861*4882a593Smuzhiyun 		goto out;
2862*4882a593Smuzhiyun 
2863*4882a593Smuzhiyun 	cap_info->cs1_row =
2864*4882a593Smuzhiyun 		dram_detect_cs1_row(dram, sdram_params, 0);
2865*4882a593Smuzhiyun 	if (cap_info->cs1_row) {
2866*4882a593Smuzhiyun 		sys_reg = readl(&dram->pmugrf->os_reg[2]);
2867*4882a593Smuzhiyun 		sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
2868*4882a593Smuzhiyun 		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
2869*4882a593Smuzhiyun 				    sys_reg, sys_reg3, 0);
2870*4882a593Smuzhiyun 		writel(sys_reg, &dram->pmugrf->os_reg[2]);
2871*4882a593Smuzhiyun 		writel(sys_reg3, &dram->pmugrf->os_reg[3]);
2872*4882a593Smuzhiyun 	}
2873*4882a593Smuzhiyun 
2874*4882a593Smuzhiyun 	sdram_detect_high_row(cap_info, sdram_params->base.dramtype);
2875*4882a593Smuzhiyun 	split_setup(dram, sdram_params);
2876*4882a593Smuzhiyun out:
2877*4882a593Smuzhiyun 	return ret;
2878*4882a593Smuzhiyun }
2879*4882a593Smuzhiyun 
get_default_sdram_config(u32 freq_mhz)2880*4882a593Smuzhiyun struct rv1126_sdram_params *get_default_sdram_config(u32 freq_mhz)
2881*4882a593Smuzhiyun {
2882*4882a593Smuzhiyun 	u32 i;
2883*4882a593Smuzhiyun 	u32 offset = 0;
2884*4882a593Smuzhiyun 	struct ddr2_3_4_lp2_3_info *ddr_info;
2885*4882a593Smuzhiyun 
2886*4882a593Smuzhiyun 	if (!freq_mhz) {
2887*4882a593Smuzhiyun 		ddr_info = get_ddr_drv_odt_info(sdram_configs[0].base.dramtype);
2888*4882a593Smuzhiyun 		if (ddr_info)
2889*4882a593Smuzhiyun 			freq_mhz =
2890*4882a593Smuzhiyun 				(ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) &
2891*4882a593Smuzhiyun 				DDR_FREQ_MASK;
2892*4882a593Smuzhiyun 		else
2893*4882a593Smuzhiyun 			freq_mhz = 0;
2894*4882a593Smuzhiyun 	}
2895*4882a593Smuzhiyun 
2896*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(sdram_configs); i++) {
2897*4882a593Smuzhiyun 		if (sdram_configs[i].base.ddr_freq == 0 ||
2898*4882a593Smuzhiyun 		    freq_mhz < sdram_configs[i].base.ddr_freq)
2899*4882a593Smuzhiyun 			break;
2900*4882a593Smuzhiyun 	}
2901*4882a593Smuzhiyun 	offset = i == 0 ? 0 : i - 1;
2902*4882a593Smuzhiyun 
2903*4882a593Smuzhiyun 	return &sdram_configs[offset];
2904*4882a593Smuzhiyun }
2905*4882a593Smuzhiyun 
2906*4882a593Smuzhiyun static const u16 pctl_need_update_reg[] = {
2907*4882a593Smuzhiyun 	DDR_PCTL2_RFSHTMG,
2908*4882a593Smuzhiyun 	DDR_PCTL2_INIT3,
2909*4882a593Smuzhiyun 	DDR_PCTL2_INIT4,
2910*4882a593Smuzhiyun 	DDR_PCTL2_INIT6,
2911*4882a593Smuzhiyun 	DDR_PCTL2_INIT7,
2912*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG0,
2913*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG1,
2914*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG2,
2915*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG3,
2916*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG4,
2917*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG5,
2918*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG6,
2919*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG7,
2920*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG8,
2921*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG9,
2922*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG12,
2923*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG13,
2924*4882a593Smuzhiyun 	DDR_PCTL2_DRAMTMG14,
2925*4882a593Smuzhiyun 	DDR_PCTL2_ZQCTL0,
2926*4882a593Smuzhiyun 	DDR_PCTL2_DFITMG0,
2927*4882a593Smuzhiyun 	DDR_PCTL2_ODTCFG
2928*4882a593Smuzhiyun };
2929*4882a593Smuzhiyun 
2930*4882a593Smuzhiyun static const u16 phy_need_update_reg[] = {
2931*4882a593Smuzhiyun 	0x14,
2932*4882a593Smuzhiyun 	0x18,
2933*4882a593Smuzhiyun 	0x1c
2934*4882a593Smuzhiyun };
2935*4882a593Smuzhiyun 
pre_set_rate(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,u32 dst_fsp,u32 dst_fsp_lp4)2936*4882a593Smuzhiyun static void pre_set_rate(struct dram_info *dram,
2937*4882a593Smuzhiyun 			 struct rv1126_sdram_params *sdram_params,
2938*4882a593Smuzhiyun 			 u32 dst_fsp, u32 dst_fsp_lp4)
2939*4882a593Smuzhiyun {
2940*4882a593Smuzhiyun 	u32 i, j, find;
2941*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
2942*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
2943*4882a593Smuzhiyun 	u32 phy_offset;
2944*4882a593Smuzhiyun 	u32 mr_tmp;
2945*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
2946*4882a593Smuzhiyun 
2947*4882a593Smuzhiyun 	sw_set_req(dram);
2948*4882a593Smuzhiyun 	/* pctl timing update */
2949*4882a593Smuzhiyun 	for (i = 0, find = 0; i < ARRAY_SIZE(pctl_need_update_reg); i++) {
2950*4882a593Smuzhiyun 		for (j = find; sdram_params->pctl_regs.pctl[j][0] != 0xFFFFFFFF;
2951*4882a593Smuzhiyun 		     j++) {
2952*4882a593Smuzhiyun 			if (sdram_params->pctl_regs.pctl[j][0] ==
2953*4882a593Smuzhiyun 			    pctl_need_update_reg[i]) {
2954*4882a593Smuzhiyun 				writel(sdram_params->pctl_regs.pctl[j][1],
2955*4882a593Smuzhiyun 				       pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
2956*4882a593Smuzhiyun 				       pctl_need_update_reg[i]);
2957*4882a593Smuzhiyun 				find = j;
2958*4882a593Smuzhiyun 				break;
2959*4882a593Smuzhiyun 			}
2960*4882a593Smuzhiyun 		}
2961*4882a593Smuzhiyun 	}
2962*4882a593Smuzhiyun 
2963*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
2964*4882a593Smuzhiyun 	u32 tmp, trefi;
2965*4882a593Smuzhiyun 
2966*4882a593Smuzhiyun 	tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG);
2967*4882a593Smuzhiyun 	trefi = (tmp >> 16) & 0xfff;
2968*4882a593Smuzhiyun 	writel((tmp & 0xf000ffff) | (trefi / 2) << 16,
2969*4882a593Smuzhiyun 	       pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG);
2970*4882a593Smuzhiyun #endif
2971*4882a593Smuzhiyun 
2972*4882a593Smuzhiyun 	sw_set_ack(dram);
2973*4882a593Smuzhiyun 
2974*4882a593Smuzhiyun 	/* phy timing update */
2975*4882a593Smuzhiyun 	if (dst_fsp == 0)
2976*4882a593Smuzhiyun 		phy_offset = 0;
2977*4882a593Smuzhiyun 	else
2978*4882a593Smuzhiyun 		phy_offset = PHY_REG(0, 0x387 - 5 + (dst_fsp - 1) * 3);
2979*4882a593Smuzhiyun 	/* cl cwl al update */
2980*4882a593Smuzhiyun 	for (i = 0, find = 0; i < ARRAY_SIZE(phy_need_update_reg); i++) {
2981*4882a593Smuzhiyun 		for (j = find; sdram_params->phy_regs.phy[j][0] != 0xFFFFFFFF;
2982*4882a593Smuzhiyun 		     j++) {
2983*4882a593Smuzhiyun 			if (sdram_params->phy_regs.phy[j][0] ==
2984*4882a593Smuzhiyun 			    phy_need_update_reg[i]) {
2985*4882a593Smuzhiyun 				writel(sdram_params->phy_regs.phy[j][1],
2986*4882a593Smuzhiyun 				       phy_base + phy_offset +
2987*4882a593Smuzhiyun 				       phy_need_update_reg[i]);
2988*4882a593Smuzhiyun 				find = j;
2989*4882a593Smuzhiyun 				break;
2990*4882a593Smuzhiyun 			}
2991*4882a593Smuzhiyun 		}
2992*4882a593Smuzhiyun 	}
2993*4882a593Smuzhiyun 
2994*4882a593Smuzhiyun 	set_ds_odt(dram, sdram_params, dst_fsp);
2995*4882a593Smuzhiyun 	if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
2996*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
2997*4882a593Smuzhiyun 			       DDR_PCTL2_INIT4);
2998*4882a593Smuzhiyun 		/* MR13 */
2999*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 13,
3000*4882a593Smuzhiyun 			      ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
3001*4882a593Smuzhiyun 			       PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) |
3002*4882a593Smuzhiyun 			      ((0x2 << 6) >> dst_fsp_lp4), dramtype);
3003*4882a593Smuzhiyun 		writel(((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
3004*4882a593Smuzhiyun 				      PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) |
3005*4882a593Smuzhiyun 				      ((0x2 << 6) >> dst_fsp_lp4),
3006*4882a593Smuzhiyun 				       PHY_REG(phy_base, 0x1b));
3007*4882a593Smuzhiyun 		/* MR3 */
3008*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 3,
3009*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT &
3010*4882a593Smuzhiyun 			      PCTL2_MR_MASK,
3011*4882a593Smuzhiyun 			      dramtype);
3012*4882a593Smuzhiyun 		writel(mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK,
3013*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x19));
3014*4882a593Smuzhiyun 
3015*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3016*4882a593Smuzhiyun 			       DDR_PCTL2_INIT3);
3017*4882a593Smuzhiyun 		/* MR1 */
3018*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 1,
3019*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT &
3020*4882a593Smuzhiyun 			      PCTL2_MR_MASK,
3021*4882a593Smuzhiyun 			      dramtype);
3022*4882a593Smuzhiyun 		writel(mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT & PCTL2_MR_MASK,
3023*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x17));
3024*4882a593Smuzhiyun 		/* MR2 */
3025*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK,
3026*4882a593Smuzhiyun 			      dramtype);
3027*4882a593Smuzhiyun 		writel(mr_tmp & PCTL2_MR_MASK,
3028*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x18));
3029*4882a593Smuzhiyun 
3030*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3031*4882a593Smuzhiyun 			       DDR_PCTL2_INIT6);
3032*4882a593Smuzhiyun 		/* MR11 */
3033*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 11,
3034*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
3035*4882a593Smuzhiyun 			      dramtype);
3036*4882a593Smuzhiyun 		writel(mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
3037*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x1a));
3038*4882a593Smuzhiyun 		/* MR12 */
3039*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 12,
3040*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK,
3041*4882a593Smuzhiyun 			      dramtype);
3042*4882a593Smuzhiyun 
3043*4882a593Smuzhiyun 		mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3044*4882a593Smuzhiyun 			       DDR_PCTL2_INIT7);
3045*4882a593Smuzhiyun 		/* MR22 */
3046*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 22,
3047*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
3048*4882a593Smuzhiyun 			      dramtype);
3049*4882a593Smuzhiyun 		writel(mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
3050*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x1d));
3051*4882a593Smuzhiyun 		/* MR14 */
3052*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 14,
3053*4882a593Smuzhiyun 			      mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
3054*4882a593Smuzhiyun 			      dramtype);
3055*4882a593Smuzhiyun 		writel(mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
3056*4882a593Smuzhiyun 		       PHY_REG(phy_base, 0x1c));
3057*4882a593Smuzhiyun 	}
3058*4882a593Smuzhiyun 
3059*4882a593Smuzhiyun 	update_noc_timing(dram, sdram_params);
3060*4882a593Smuzhiyun }
3061*4882a593Smuzhiyun 
save_fsp_param(struct dram_info * dram,u32 dst_fsp,struct rv1126_sdram_params * sdram_params)3062*4882a593Smuzhiyun static void save_fsp_param(struct dram_info *dram, u32 dst_fsp,
3063*4882a593Smuzhiyun 			   struct rv1126_sdram_params *sdram_params)
3064*4882a593Smuzhiyun {
3065*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
3066*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
3067*4882a593Smuzhiyun 	struct rv1126_fsp_param *p_fsp_param = &fsp_param[dst_fsp];
3068*4882a593Smuzhiyun 	u32 temp, temp1;
3069*4882a593Smuzhiyun 	struct ddr2_3_4_lp2_3_info *ddr_info;
3070*4882a593Smuzhiyun 
3071*4882a593Smuzhiyun 	ddr_info = get_ddr_drv_odt_info(sdram_params->base.dramtype);
3072*4882a593Smuzhiyun 
3073*4882a593Smuzhiyun 	p_fsp_param->freq_mhz = sdram_params->base.ddr_freq;
3074*4882a593Smuzhiyun 
3075*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == LPDDR4 ||
3076*4882a593Smuzhiyun 	    sdram_params->base.dramtype == LPDDR4X) {
3077*4882a593Smuzhiyun 		p_fsp_param->rd_odt_up_en = 0;
3078*4882a593Smuzhiyun 		p_fsp_param->rd_odt_down_en = 1;
3079*4882a593Smuzhiyun 	} else {
3080*4882a593Smuzhiyun 		p_fsp_param->rd_odt_up_en =
3081*4882a593Smuzhiyun 			ODT_INFO_PULLUP_EN(ddr_info->odt_info);
3082*4882a593Smuzhiyun 		p_fsp_param->rd_odt_down_en =
3083*4882a593Smuzhiyun 			ODT_INFO_PULLDOWN_EN(ddr_info->odt_info);
3084*4882a593Smuzhiyun 	}
3085*4882a593Smuzhiyun 
3086*4882a593Smuzhiyun 	if (p_fsp_param->rd_odt_up_en)
3087*4882a593Smuzhiyun 		p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x111));
3088*4882a593Smuzhiyun 	else if (p_fsp_param->rd_odt_down_en)
3089*4882a593Smuzhiyun 		p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x110));
3090*4882a593Smuzhiyun 	else
3091*4882a593Smuzhiyun 		p_fsp_param->rd_odt = 0;
3092*4882a593Smuzhiyun 	p_fsp_param->wr_dq_drv = readl(PHY_REG(phy_base, 0x112));
3093*4882a593Smuzhiyun 	p_fsp_param->wr_ca_drv = readl(PHY_REG(phy_base, 0x100));
3094*4882a593Smuzhiyun 	p_fsp_param->wr_ckcs_drv = readl(PHY_REG(phy_base, 0x102));
3095*4882a593Smuzhiyun 	p_fsp_param->vref_inner = readl(PHY_REG(phy_base, 0x128));
3096*4882a593Smuzhiyun 	p_fsp_param->vref_out = readl(PHY_REG(phy_base, 0x105));
3097*4882a593Smuzhiyun 
3098*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR3) {
3099*4882a593Smuzhiyun 		temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3100*4882a593Smuzhiyun 			     DDR_PCTL2_INIT3);
3101*4882a593Smuzhiyun 		temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK;
3102*4882a593Smuzhiyun 		p_fsp_param->ds_pdds = temp & DDR3_DS_MASK;
3103*4882a593Smuzhiyun 		p_fsp_param->dq_odt = temp & DDR3_RTT_NOM_MASK;
3104*4882a593Smuzhiyun 		p_fsp_param->ca_odt = p_fsp_param->dq_odt;
3105*4882a593Smuzhiyun 	} else if (sdram_params->base.dramtype == DDR4) {
3106*4882a593Smuzhiyun 		temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3107*4882a593Smuzhiyun 			     DDR_PCTL2_INIT3);
3108*4882a593Smuzhiyun 		temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK;
3109*4882a593Smuzhiyun 		p_fsp_param->ds_pdds = temp & DDR4_DS_MASK;
3110*4882a593Smuzhiyun 		p_fsp_param->dq_odt = temp & DDR4_RTT_NOM_MASK;
3111*4882a593Smuzhiyun 		p_fsp_param->ca_odt = p_fsp_param->dq_odt;
3112*4882a593Smuzhiyun 	} else if (sdram_params->base.dramtype == LPDDR3) {
3113*4882a593Smuzhiyun 		temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3114*4882a593Smuzhiyun 			     DDR_PCTL2_INIT4);
3115*4882a593Smuzhiyun 		temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK;
3116*4882a593Smuzhiyun 		p_fsp_param->ds_pdds = temp & 0xf;
3117*4882a593Smuzhiyun 
3118*4882a593Smuzhiyun 		p_fsp_param->dq_odt = lp3_odt_value;
3119*4882a593Smuzhiyun 		p_fsp_param->ca_odt = p_fsp_param->dq_odt;
3120*4882a593Smuzhiyun 	} else if (sdram_params->base.dramtype == LPDDR4 ||
3121*4882a593Smuzhiyun 		   sdram_params->base.dramtype == LPDDR4X) {
3122*4882a593Smuzhiyun 		temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3123*4882a593Smuzhiyun 			     DDR_PCTL2_INIT4);
3124*4882a593Smuzhiyun 		temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK;
3125*4882a593Smuzhiyun 		p_fsp_param->ds_pdds = temp & LPDDR4_PDDS_MASK;
3126*4882a593Smuzhiyun 
3127*4882a593Smuzhiyun 		temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3128*4882a593Smuzhiyun 			     DDR_PCTL2_INIT6);
3129*4882a593Smuzhiyun 		temp = (temp >> PCTL2_LPDDR4_MR11_SHIFT) & PCTL2_MR_MASK;
3130*4882a593Smuzhiyun 		p_fsp_param->dq_odt = temp & LPDDR4_DQODT_MASK;
3131*4882a593Smuzhiyun 		p_fsp_param->ca_odt = temp & LPDDR4_CAODT_MASK;
3132*4882a593Smuzhiyun 
3133*4882a593Smuzhiyun 		temp = MAX(readl(PHY_REG(phy_base, 0x3ae)),
3134*4882a593Smuzhiyun 			   readl(PHY_REG(phy_base, 0x3ce)));
3135*4882a593Smuzhiyun 		temp1 = MIN(readl(PHY_REG(phy_base, 0x3be)),
3136*4882a593Smuzhiyun 			    readl(PHY_REG(phy_base, 0x3de)));
3137*4882a593Smuzhiyun 		p_fsp_param->vref_ca[0] = (temp + temp1) / 2;
3138*4882a593Smuzhiyun 		temp = MAX(readl(PHY_REG(phy_base, 0x3af)),
3139*4882a593Smuzhiyun 			   readl(PHY_REG(phy_base, 0x3cf)));
3140*4882a593Smuzhiyun 		temp1 = MIN(readl(PHY_REG(phy_base, 0x3bf)),
3141*4882a593Smuzhiyun 			    readl(PHY_REG(phy_base, 0x3df)));
3142*4882a593Smuzhiyun 		p_fsp_param->vref_ca[1] = (temp + temp1) / 2;
3143*4882a593Smuzhiyun 		p_fsp_param->vref_ca[0] |=
3144*4882a593Smuzhiyun 			(readl(PHY_REG(phy_base, 0x1e)) & BIT(6));
3145*4882a593Smuzhiyun 		p_fsp_param->vref_ca[1] |=
3146*4882a593Smuzhiyun 			(readl(PHY_REG(phy_base, 0x1e)) & BIT(6));
3147*4882a593Smuzhiyun 
3148*4882a593Smuzhiyun 		p_fsp_param->lp4_drv_pd_en = (readl(PHY_REG(phy_base, 0x114)) >>
3149*4882a593Smuzhiyun 					      3) & 0x1;
3150*4882a593Smuzhiyun 	}
3151*4882a593Smuzhiyun 
3152*4882a593Smuzhiyun 	p_fsp_param->noc_timings.ddrtiminga0 =
3153*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrtiminga0;
3154*4882a593Smuzhiyun 	p_fsp_param->noc_timings.ddrtimingb0 =
3155*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrtimingb0;
3156*4882a593Smuzhiyun 	p_fsp_param->noc_timings.ddrtimingc0 =
3157*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrtimingc0;
3158*4882a593Smuzhiyun 	p_fsp_param->noc_timings.devtodev0 =
3159*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.devtodev0;
3160*4882a593Smuzhiyun 	p_fsp_param->noc_timings.ddrmode =
3161*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddrmode;
3162*4882a593Smuzhiyun 	p_fsp_param->noc_timings.ddr4timing =
3163*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.ddr4timing;
3164*4882a593Smuzhiyun 	p_fsp_param->noc_timings.agingx0 =
3165*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.agingx0;
3166*4882a593Smuzhiyun 	p_fsp_param->noc_timings.aging0 =
3167*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.aging0;
3168*4882a593Smuzhiyun 	p_fsp_param->noc_timings.aging1 =
3169*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.aging1;
3170*4882a593Smuzhiyun 	p_fsp_param->noc_timings.aging2 =
3171*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.aging2;
3172*4882a593Smuzhiyun 	p_fsp_param->noc_timings.aging3 =
3173*4882a593Smuzhiyun 		sdram_params->ch.noc_timings.aging3;
3174*4882a593Smuzhiyun 
3175*4882a593Smuzhiyun 	p_fsp_param->flag = FSP_FLAG;
3176*4882a593Smuzhiyun }
3177*4882a593Smuzhiyun 
3178*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
copy_fsp_param_to_ddr(void)3179*4882a593Smuzhiyun static void copy_fsp_param_to_ddr(void)
3180*4882a593Smuzhiyun {
3181*4882a593Smuzhiyun 	memcpy((void *)FSP_PARAM_STORE_ADDR, (void *)&fsp_param,
3182*4882a593Smuzhiyun 	       sizeof(fsp_param));
3183*4882a593Smuzhiyun }
3184*4882a593Smuzhiyun #endif
3185*4882a593Smuzhiyun 
pctl_modify_trfc(struct ddr_pctl_regs * pctl_regs,struct sdram_cap_info * cap_info,u32 dram_type,u32 freq)3186*4882a593Smuzhiyun static void pctl_modify_trfc(struct ddr_pctl_regs *pctl_regs,
3187*4882a593Smuzhiyun 			     struct sdram_cap_info *cap_info, u32 dram_type,
3188*4882a593Smuzhiyun 			     u32 freq)
3189*4882a593Smuzhiyun {
3190*4882a593Smuzhiyun 	u64 cs0_cap;
3191*4882a593Smuzhiyun 	u32 die_cap;
3192*4882a593Smuzhiyun 	u32 trfc_ns, trfc4_ns;
3193*4882a593Smuzhiyun 	u32 trfc, txsnr;
3194*4882a593Smuzhiyun 	u32 txs_abort_fast = 0;
3195*4882a593Smuzhiyun 	u32 tmp;
3196*4882a593Smuzhiyun 
3197*4882a593Smuzhiyun 	cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
3198*4882a593Smuzhiyun 	die_cap = (u32)(cs0_cap >> (20 + (cap_info->bw - cap_info->dbw)));
3199*4882a593Smuzhiyun 
3200*4882a593Smuzhiyun 	switch (dram_type) {
3201*4882a593Smuzhiyun 	case DDR3:
3202*4882a593Smuzhiyun 		if (die_cap <= DIE_CAP_512MBIT)
3203*4882a593Smuzhiyun 			trfc_ns = 90;
3204*4882a593Smuzhiyun 		else if (die_cap <= DIE_CAP_1GBIT)
3205*4882a593Smuzhiyun 			trfc_ns = 110;
3206*4882a593Smuzhiyun 		else if (die_cap <= DIE_CAP_2GBIT)
3207*4882a593Smuzhiyun 			trfc_ns = 160;
3208*4882a593Smuzhiyun 		else if (die_cap <= DIE_CAP_4GBIT)
3209*4882a593Smuzhiyun 			trfc_ns = 260;
3210*4882a593Smuzhiyun 		else
3211*4882a593Smuzhiyun 			trfc_ns = 350;
3212*4882a593Smuzhiyun 		txsnr = MAX(5, ((trfc_ns + 10) * freq + 999) / 1000);
3213*4882a593Smuzhiyun 		break;
3214*4882a593Smuzhiyun 
3215*4882a593Smuzhiyun 	case DDR4:
3216*4882a593Smuzhiyun 		if (die_cap <= DIE_CAP_2GBIT) {
3217*4882a593Smuzhiyun 			trfc_ns = 160;
3218*4882a593Smuzhiyun 			trfc4_ns = 90;
3219*4882a593Smuzhiyun 		} else if (die_cap <= DIE_CAP_4GBIT) {
3220*4882a593Smuzhiyun 			trfc_ns = 260;
3221*4882a593Smuzhiyun 			trfc4_ns = 110;
3222*4882a593Smuzhiyun 		} else if (die_cap <= DIE_CAP_8GBIT) {
3223*4882a593Smuzhiyun 			trfc_ns = 350;
3224*4882a593Smuzhiyun 			trfc4_ns = 160;
3225*4882a593Smuzhiyun 		} else {
3226*4882a593Smuzhiyun 			trfc_ns = 550;
3227*4882a593Smuzhiyun 			trfc4_ns = 260;
3228*4882a593Smuzhiyun 		}
3229*4882a593Smuzhiyun 		txsnr = ((trfc_ns + 10) * freq + 999) / 1000;
3230*4882a593Smuzhiyun 		txs_abort_fast = ((trfc4_ns + 10) * freq + 999) / 1000;
3231*4882a593Smuzhiyun 		break;
3232*4882a593Smuzhiyun 
3233*4882a593Smuzhiyun 	case LPDDR3:
3234*4882a593Smuzhiyun 		if (die_cap <= DIE_CAP_4GBIT)
3235*4882a593Smuzhiyun 			trfc_ns = 130;
3236*4882a593Smuzhiyun 		else
3237*4882a593Smuzhiyun 			trfc_ns = 210;
3238*4882a593Smuzhiyun 		txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000);
3239*4882a593Smuzhiyun 		break;
3240*4882a593Smuzhiyun 
3241*4882a593Smuzhiyun 	case LPDDR4:
3242*4882a593Smuzhiyun 	case LPDDR4X:
3243*4882a593Smuzhiyun 		if (die_cap <= DIE_CAP_2GBIT)
3244*4882a593Smuzhiyun 			trfc_ns = 130;
3245*4882a593Smuzhiyun 		else if (die_cap <= DIE_CAP_4GBIT)
3246*4882a593Smuzhiyun 			trfc_ns = 180;
3247*4882a593Smuzhiyun 		else if (die_cap <= DIE_CAP_8GBIT)
3248*4882a593Smuzhiyun 			trfc_ns = 280;
3249*4882a593Smuzhiyun 		else
3250*4882a593Smuzhiyun 			trfc_ns = 380;
3251*4882a593Smuzhiyun 		txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000);
3252*4882a593Smuzhiyun 		break;
3253*4882a593Smuzhiyun 
3254*4882a593Smuzhiyun 	default:
3255*4882a593Smuzhiyun 		return;
3256*4882a593Smuzhiyun 	}
3257*4882a593Smuzhiyun 	trfc = (trfc_ns * freq + 999) / 1000;
3258*4882a593Smuzhiyun 
3259*4882a593Smuzhiyun 	for (int i = 0; pctl_regs->pctl[i][0] != 0xffffffff; i++) {
3260*4882a593Smuzhiyun 		switch (pctl_regs->pctl[i][0]) {
3261*4882a593Smuzhiyun 		case DDR_PCTL2_RFSHTMG:
3262*4882a593Smuzhiyun 			tmp = pctl_regs->pctl[i][1];
3263*4882a593Smuzhiyun 			/* t_rfc_min */
3264*4882a593Smuzhiyun 			tmp &= ~((u32)0x3ff);
3265*4882a593Smuzhiyun 			tmp |= ((trfc + 1) / 2) & 0x3ff;
3266*4882a593Smuzhiyun 			pctl_regs->pctl[i][1] = tmp;
3267*4882a593Smuzhiyun 			break;
3268*4882a593Smuzhiyun 
3269*4882a593Smuzhiyun 		case DDR_PCTL2_DRAMTMG8:
3270*4882a593Smuzhiyun 			if (dram_type == DDR3 || dram_type == DDR4) {
3271*4882a593Smuzhiyun 				tmp = pctl_regs->pctl[i][1];
3272*4882a593Smuzhiyun 				/* t_xs_x32 */
3273*4882a593Smuzhiyun 				tmp &= ~((u32)0x7f);
3274*4882a593Smuzhiyun 				tmp |= ((txsnr + 63) / 64 + 1) & 0x7f;
3275*4882a593Smuzhiyun 
3276*4882a593Smuzhiyun 				if (dram_type == DDR4) {
3277*4882a593Smuzhiyun 					/* t_xs_abort_x32 */
3278*4882a593Smuzhiyun 					tmp &= ~((u32)(0x7f << 16));
3279*4882a593Smuzhiyun 					tmp |= (((txs_abort_fast + 63) / 64 + 1) & 0x7f) << 16;
3280*4882a593Smuzhiyun 					/* t_xs_fast_x32 */
3281*4882a593Smuzhiyun 					tmp &= ~((u32)(0x7f << 24));
3282*4882a593Smuzhiyun 					tmp |= (((txs_abort_fast + 63) / 64 + 1) & 0x7f) << 24;
3283*4882a593Smuzhiyun 				}
3284*4882a593Smuzhiyun 
3285*4882a593Smuzhiyun 				pctl_regs->pctl[i][1] = tmp;
3286*4882a593Smuzhiyun 			}
3287*4882a593Smuzhiyun 			break;
3288*4882a593Smuzhiyun 
3289*4882a593Smuzhiyun 		case DDR_PCTL2_DRAMTMG14:
3290*4882a593Smuzhiyun 			if (dram_type == LPDDR3 ||
3291*4882a593Smuzhiyun 			    dram_type == LPDDR4 || dram_type == LPDDR4X) {
3292*4882a593Smuzhiyun 				tmp = pctl_regs->pctl[i][1];
3293*4882a593Smuzhiyun 				/* t_xsr */
3294*4882a593Smuzhiyun 				tmp &= ~((u32)0xfff);
3295*4882a593Smuzhiyun 				tmp |= ((txsnr + 1) / 2) & 0xfff;
3296*4882a593Smuzhiyun 				pctl_regs->pctl[i][1] = tmp;
3297*4882a593Smuzhiyun 			}
3298*4882a593Smuzhiyun 			break;
3299*4882a593Smuzhiyun 
3300*4882a593Smuzhiyun 		default:
3301*4882a593Smuzhiyun 			break;
3302*4882a593Smuzhiyun 		}
3303*4882a593Smuzhiyun 	}
3304*4882a593Smuzhiyun }
3305*4882a593Smuzhiyun 
ddr_set_rate(struct dram_info * dram,struct rv1126_sdram_params * sdram_params,u32 freq,u32 cur_freq,u32 dst_fsp,u32 dst_fsp_lp4,u32 training_en)3306*4882a593Smuzhiyun void ddr_set_rate(struct dram_info *dram,
3307*4882a593Smuzhiyun 		  struct rv1126_sdram_params *sdram_params,
3308*4882a593Smuzhiyun 		  u32 freq, u32 cur_freq, u32 dst_fsp,
3309*4882a593Smuzhiyun 		  u32 dst_fsp_lp4, u32 training_en)
3310*4882a593Smuzhiyun {
3311*4882a593Smuzhiyun 	u32 dest_dll_off, cur_init3, dst_init3, cur_fsp, cur_dll_off;
3312*4882a593Smuzhiyun 	u32 mr_tmp;
3313*4882a593Smuzhiyun 	u32 lp_stat;
3314*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
3315*4882a593Smuzhiyun 	struct rv1126_sdram_params *sdram_params_new;
3316*4882a593Smuzhiyun 	void __iomem *pctl_base = dram->pctl;
3317*4882a593Smuzhiyun 	void __iomem *phy_base = dram->phy;
3318*4882a593Smuzhiyun 	int delay = 1000;
3319*4882a593Smuzhiyun 
3320*4882a593Smuzhiyun 	lp_stat = low_power_update(dram, 0);
3321*4882a593Smuzhiyun 	sdram_params_new = get_default_sdram_config(freq);
3322*4882a593Smuzhiyun 	sdram_params_new->ch.cap_info.rank = sdram_params->ch.cap_info.rank;
3323*4882a593Smuzhiyun 	sdram_params_new->ch.cap_info.bw = sdram_params->ch.cap_info.bw;
3324*4882a593Smuzhiyun 
3325*4882a593Smuzhiyun 	pctl_modify_trfc(&sdram_params_new->pctl_regs,
3326*4882a593Smuzhiyun 			 &sdram_params->ch.cap_info, dramtype, freq);
3327*4882a593Smuzhiyun 	pre_set_rate(dram, sdram_params_new, dst_fsp, dst_fsp_lp4);
3328*4882a593Smuzhiyun 
3329*4882a593Smuzhiyun 	while ((readl(pctl_base + DDR_PCTL2_STAT) &
3330*4882a593Smuzhiyun 			 PCTL2_OPERATING_MODE_MASK) ==
3331*4882a593Smuzhiyun 			 PCTL2_OPERATING_MODE_SR)
3332*4882a593Smuzhiyun 		continue;
3333*4882a593Smuzhiyun 
3334*4882a593Smuzhiyun 	dest_dll_off = 0;
3335*4882a593Smuzhiyun 	dst_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3336*4882a593Smuzhiyun 			  DDR_PCTL2_INIT3);
3337*4882a593Smuzhiyun 	if ((dramtype == DDR3 && (dst_init3 & 1)) ||
3338*4882a593Smuzhiyun 	    (dramtype == DDR4 && !(dst_init3 & 1)))
3339*4882a593Smuzhiyun 		dest_dll_off = 1;
3340*4882a593Smuzhiyun 
3341*4882a593Smuzhiyun 	cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
3342*4882a593Smuzhiyun 	cur_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
3343*4882a593Smuzhiyun 			  DDR_PCTL2_INIT3);
3344*4882a593Smuzhiyun 	cur_init3 &= PCTL2_MR_MASK;
3345*4882a593Smuzhiyun 	cur_dll_off = 1;
3346*4882a593Smuzhiyun 	if ((dramtype == DDR3 && !(cur_init3 & 1)) ||
3347*4882a593Smuzhiyun 	    (dramtype == DDR4 && (cur_init3 & 1)))
3348*4882a593Smuzhiyun 		cur_dll_off = 0;
3349*4882a593Smuzhiyun 
3350*4882a593Smuzhiyun 	if (!cur_dll_off) {
3351*4882a593Smuzhiyun 		if (dramtype == DDR3)
3352*4882a593Smuzhiyun 			cur_init3 |= 1;
3353*4882a593Smuzhiyun 		else
3354*4882a593Smuzhiyun 			cur_init3 &= ~1;
3355*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 2, 1, cur_init3, dramtype);
3356*4882a593Smuzhiyun 	}
3357*4882a593Smuzhiyun 
3358*4882a593Smuzhiyun 	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3,
3359*4882a593Smuzhiyun 		     PCTL2_DIS_AUTO_REFRESH);
3360*4882a593Smuzhiyun 	update_refresh_reg(dram);
3361*4882a593Smuzhiyun 
3362*4882a593Smuzhiyun 	enter_sr(dram, 1);
3363*4882a593Smuzhiyun 
3364*4882a593Smuzhiyun 	writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK |
3365*4882a593Smuzhiyun 	       PMUGRF_CON_DDRPHY_BUFFEREN_EN,
3366*4882a593Smuzhiyun 	       &dram->pmugrf->soc_con[0]);
3367*4882a593Smuzhiyun 	sw_set_req(dram);
3368*4882a593Smuzhiyun 	clrbits_le32(pctl_base + DDR_PCTL2_DFIMISC,
3369*4882a593Smuzhiyun 		     PCTL2_DFI_INIT_COMPLETE_EN);
3370*4882a593Smuzhiyun 	sw_set_ack(dram);
3371*4882a593Smuzhiyun 
3372*4882a593Smuzhiyun 	sw_set_req(dram);
3373*4882a593Smuzhiyun 	if ((dramtype == DDR3 || dramtype == DDR4) && dest_dll_off)
3374*4882a593Smuzhiyun 		setbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE);
3375*4882a593Smuzhiyun 	else
3376*4882a593Smuzhiyun 		clrbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE);
3377*4882a593Smuzhiyun 
3378*4882a593Smuzhiyun 	setbits_le32(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_ZQCTL0,
3379*4882a593Smuzhiyun 		     PCTL2_DIS_SRX_ZQCL);
3380*4882a593Smuzhiyun 	setbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_ZQCTL0,
3381*4882a593Smuzhiyun 		     PCTL2_DIS_SRX_ZQCL);
3382*4882a593Smuzhiyun 	sw_set_ack(dram);
3383*4882a593Smuzhiyun 
3384*4882a593Smuzhiyun 	writel(DDR_MSCH_EN_MASK | (0x1 << DDR_MSCH_EN_SHIFT),
3385*4882a593Smuzhiyun 	       &dram->cru->clkgate_con[21]);
3386*4882a593Smuzhiyun 	writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK |
3387*4882a593Smuzhiyun 					(0x1 << CLK_DDR_UPCTL_EN_SHIFT) |
3388*4882a593Smuzhiyun 					(0x1 << ACLK_DDR_UPCTL_EN_SHIFT),
3389*4882a593Smuzhiyun 			BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12);
3390*4882a593Smuzhiyun 
3391*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET);
3392*4882a593Smuzhiyun 	rkclk_set_dpll(dram, freq * MHz / 2);
3393*4882a593Smuzhiyun 	phy_pll_set(dram, freq * MHz, 0);
3394*4882a593Smuzhiyun 	phy_pll_set(dram, freq * MHz, 1);
3395*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET);
3396*4882a593Smuzhiyun 
3397*4882a593Smuzhiyun 	writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK |
3398*4882a593Smuzhiyun 			PMUGRF_CON_DDRPHY_BUFFEREN_DIS,
3399*4882a593Smuzhiyun 			&dram->pmugrf->soc_con[0]);
3400*4882a593Smuzhiyun 	writel(DDR_MSCH_EN_MASK | (0x0 << DDR_MSCH_EN_SHIFT),
3401*4882a593Smuzhiyun 	       &dram->cru->clkgate_con[21]);
3402*4882a593Smuzhiyun 	writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK |
3403*4882a593Smuzhiyun 					(0x0 << CLK_DDR_UPCTL_EN_SHIFT) |
3404*4882a593Smuzhiyun 					(0x0 << ACLK_DDR_UPCTL_EN_SHIFT),
3405*4882a593Smuzhiyun 			BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12);
3406*4882a593Smuzhiyun 	while ((readl(pctl_base + DDR_PCTL2_DFISTAT) &
3407*4882a593Smuzhiyun 	       PCTL2_DFI_INIT_COMPLETE) != PCTL2_DFI_INIT_COMPLETE) {
3408*4882a593Smuzhiyun 		udelay(1);
3409*4882a593Smuzhiyun 		if (delay-- <= 0) {
3410*4882a593Smuzhiyun 			printascii("ERROR: Cannot wait DFI_INIT_COMPLETE\n");
3411*4882a593Smuzhiyun 			while (1)
3412*4882a593Smuzhiyun 				;
3413*4882a593Smuzhiyun 		}
3414*4882a593Smuzhiyun 	}
3415*4882a593Smuzhiyun 
3416*4882a593Smuzhiyun 	sw_set_req(dram);
3417*4882a593Smuzhiyun 	setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29);
3418*4882a593Smuzhiyun 	clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, dst_fsp);
3419*4882a593Smuzhiyun 	sw_set_ack(dram);
3420*4882a593Smuzhiyun 	update_refresh_reg(dram);
3421*4882a593Smuzhiyun 	clrsetbits_le32(PHY_REG(phy_base, 0xc), 0x3 << 2, dst_fsp << 2);
3422*4882a593Smuzhiyun 
3423*4882a593Smuzhiyun 	enter_sr(dram, 0);
3424*4882a593Smuzhiyun 
3425*4882a593Smuzhiyun 	setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
3426*4882a593Smuzhiyun 	clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
3427*4882a593Smuzhiyun 
3428*4882a593Smuzhiyun 	mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_INIT4);
3429*4882a593Smuzhiyun 	if (dramtype == LPDDR3) {
3430*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 1,
3431*4882a593Smuzhiyun 			      (dst_init3 >> PCTL2_LPDDR234_MR1_SHIFT) &
3432*4882a593Smuzhiyun 			      PCTL2_MR_MASK,
3433*4882a593Smuzhiyun 			      dramtype);
3434*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 2, dst_init3 & PCTL2_MR_MASK,
3435*4882a593Smuzhiyun 			      dramtype);
3436*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 3,
3437*4882a593Smuzhiyun 			      (mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT) &
3438*4882a593Smuzhiyun 			      PCTL2_MR_MASK,
3439*4882a593Smuzhiyun 			      dramtype);
3440*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, dramtype);
3441*4882a593Smuzhiyun 	} else if ((dramtype == DDR3) || (dramtype == DDR4)) {
3442*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 1, dst_init3 & PCTL2_MR_MASK,
3443*4882a593Smuzhiyun 			      dramtype);
3444*4882a593Smuzhiyun 		if (!dest_dll_off) {
3445*4882a593Smuzhiyun 			pctl_write_mr(dram->pctl, 3, 0,
3446*4882a593Smuzhiyun 				      ((dst_init3 >> PCTL2_DDR34_MR0_SHIFT) &
3447*4882a593Smuzhiyun 				      PCTL2_MR_MASK) | DDR3_DLL_RESET,
3448*4882a593Smuzhiyun 				      dramtype);
3449*4882a593Smuzhiyun 			udelay(2);
3450*4882a593Smuzhiyun 		}
3451*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 0,
3452*4882a593Smuzhiyun 			      (dst_init3 >> PCTL2_DDR34_MR0_SHIFT &
3453*4882a593Smuzhiyun 			       PCTL2_MR_MASK) & (~DDR3_DLL_RESET),
3454*4882a593Smuzhiyun 			      dramtype);
3455*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 2,
3456*4882a593Smuzhiyun 			      ((mr_tmp >> PCTL2_DDR34_MR2_SHIFT) &
3457*4882a593Smuzhiyun 			       PCTL2_MR_MASK), dramtype);
3458*4882a593Smuzhiyun 		if (dramtype == DDR4) {
3459*4882a593Smuzhiyun 			pctl_write_mr(dram->pctl, 3, 3, mr_tmp & PCTL2_MR_MASK,
3460*4882a593Smuzhiyun 				      dramtype);
3461*4882a593Smuzhiyun 			mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3462*4882a593Smuzhiyun 				       DDR_PCTL2_INIT6);
3463*4882a593Smuzhiyun 			pctl_write_mr(dram->pctl, 3, 4,
3464*4882a593Smuzhiyun 				      (mr_tmp >> PCTL2_DDR4_MR4_SHIFT) &
3465*4882a593Smuzhiyun 				       PCTL2_MR_MASK,
3466*4882a593Smuzhiyun 				      dramtype);
3467*4882a593Smuzhiyun 			pctl_write_mr(dram->pctl, 3, 5,
3468*4882a593Smuzhiyun 				      mr_tmp >> PCTL2_DDR4_MR5_SHIFT &
3469*4882a593Smuzhiyun 				      PCTL2_MR_MASK,
3470*4882a593Smuzhiyun 				      dramtype);
3471*4882a593Smuzhiyun 
3472*4882a593Smuzhiyun 			mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
3473*4882a593Smuzhiyun 				       DDR_PCTL2_INIT7);
3474*4882a593Smuzhiyun 			pctl_write_mr(dram->pctl, 3, 6,
3475*4882a593Smuzhiyun 				      mr_tmp >> PCTL2_DDR4_MR6_SHIFT &
3476*4882a593Smuzhiyun 				      PCTL2_MR_MASK,
3477*4882a593Smuzhiyun 				      dramtype);
3478*4882a593Smuzhiyun 		}
3479*4882a593Smuzhiyun 	} else if (dramtype == LPDDR4 || dramtype == LPDDR4X) {
3480*4882a593Smuzhiyun 		pctl_write_mr(dram->pctl, 3, 13,
3481*4882a593Smuzhiyun 			      ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
3482*4882a593Smuzhiyun 			       PCTL2_MR_MASK) & (~(BIT(7)))) |
3483*4882a593Smuzhiyun 			      dst_fsp_lp4 << 7, dramtype);
3484*4882a593Smuzhiyun 	}
3485*4882a593Smuzhiyun 	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3,
3486*4882a593Smuzhiyun 		     PCTL2_DIS_AUTO_REFRESH);
3487*4882a593Smuzhiyun 	update_refresh_reg(dram);
3488*4882a593Smuzhiyun 
3489*4882a593Smuzhiyun 	/* training */
3490*4882a593Smuzhiyun 	high_freq_training(dram, sdram_params_new, dst_fsp);
3491*4882a593Smuzhiyun 	low_power_update(dram, lp_stat);
3492*4882a593Smuzhiyun 
3493*4882a593Smuzhiyun 	save_fsp_param(dram, dst_fsp, sdram_params_new);
3494*4882a593Smuzhiyun }
3495*4882a593Smuzhiyun 
ddr_set_rate_for_fsp(struct dram_info * dram,struct rv1126_sdram_params * sdram_params)3496*4882a593Smuzhiyun static void ddr_set_rate_for_fsp(struct dram_info *dram,
3497*4882a593Smuzhiyun 				 struct rv1126_sdram_params *sdram_params)
3498*4882a593Smuzhiyun {
3499*4882a593Smuzhiyun 	struct ddr2_3_4_lp2_3_info *ddr_info;
3500*4882a593Smuzhiyun 	u32 f0;
3501*4882a593Smuzhiyun 	u32 dramtype = sdram_params->base.dramtype;
3502*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
3503*4882a593Smuzhiyun 	u32 f1, f2, f3;
3504*4882a593Smuzhiyun #endif
3505*4882a593Smuzhiyun 
3506*4882a593Smuzhiyun 	ddr_info = get_ddr_drv_odt_info(dramtype);
3507*4882a593Smuzhiyun 	if (!ddr_info)
3508*4882a593Smuzhiyun 		return;
3509*4882a593Smuzhiyun 
3510*4882a593Smuzhiyun 	f0 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) &
3511*4882a593Smuzhiyun 	     DDR_FREQ_MASK;
3512*4882a593Smuzhiyun 
3513*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
3514*4882a593Smuzhiyun 	memset((void *)FSP_PARAM_STORE_ADDR, 0, sizeof(fsp_param));
3515*4882a593Smuzhiyun 	memset((void *)&fsp_param, 0, sizeof(fsp_param));
3516*4882a593Smuzhiyun 
3517*4882a593Smuzhiyun 	f1 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F1_SHIFT) &
3518*4882a593Smuzhiyun 	     DDR_FREQ_MASK;
3519*4882a593Smuzhiyun 	f2 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F2_SHIFT) &
3520*4882a593Smuzhiyun 	     DDR_FREQ_MASK;
3521*4882a593Smuzhiyun 	f3 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F3_SHIFT) &
3522*4882a593Smuzhiyun 	     DDR_FREQ_MASK;
3523*4882a593Smuzhiyun #endif
3524*4882a593Smuzhiyun 
3525*4882a593Smuzhiyun 	if (get_wrlvl_val(dram, sdram_params))
3526*4882a593Smuzhiyun 		printascii("get wrlvl value fail\n");
3527*4882a593Smuzhiyun 
3528*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
3529*4882a593Smuzhiyun 	printascii("change to: ");
3530*4882a593Smuzhiyun 	printdec(f1);
3531*4882a593Smuzhiyun 	printascii("MHz\n");
3532*4882a593Smuzhiyun 	ddr_set_rate(&dram_info, sdram_params, f1,
3533*4882a593Smuzhiyun 		     sdram_params->base.ddr_freq, 1, 1, 1);
3534*4882a593Smuzhiyun 	printascii("change to: ");
3535*4882a593Smuzhiyun 	printdec(f2);
3536*4882a593Smuzhiyun 	printascii("MHz\n");
3537*4882a593Smuzhiyun 	ddr_set_rate(&dram_info, sdram_params, f2, f1, 2, 0, 1);
3538*4882a593Smuzhiyun 	printascii("change to: ");
3539*4882a593Smuzhiyun 	printdec(f3);
3540*4882a593Smuzhiyun 	printascii("MHz\n");
3541*4882a593Smuzhiyun 	ddr_set_rate(&dram_info, sdram_params, f3, f2, 3, 1, 1);
3542*4882a593Smuzhiyun #endif
3543*4882a593Smuzhiyun 	printascii("change to: ");
3544*4882a593Smuzhiyun 	printdec(f0);
3545*4882a593Smuzhiyun 	printascii("MHz(final freq)\n");
3546*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
3547*4882a593Smuzhiyun 	ddr_set_rate(&dram_info, sdram_params, f0, f3, 0, 0, 1);
3548*4882a593Smuzhiyun #else
3549*4882a593Smuzhiyun 	ddr_set_rate(&dram_info, sdram_params, f0, sdram_params->base.ddr_freq, 1, 1, 1);
3550*4882a593Smuzhiyun #endif
3551*4882a593Smuzhiyun }
3552*4882a593Smuzhiyun 
get_uart_config(void)3553*4882a593Smuzhiyun int get_uart_config(void)
3554*4882a593Smuzhiyun {
3555*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
3556*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
3557*4882a593Smuzhiyun 	struct global_info *gbl_info;
3558*4882a593Smuzhiyun 
3559*4882a593Smuzhiyun 	gbl_info = (struct global_info *)((void *)common_info +
3560*4882a593Smuzhiyun 		index->global_index.offset * 4);
3561*4882a593Smuzhiyun 
3562*4882a593Smuzhiyun 	return gbl_info->uart_info;
3563*4882a593Smuzhiyun }
3564*4882a593Smuzhiyun 
3565*4882a593Smuzhiyun /* return: 0 = success, other = fail */
sdram_init(void)3566*4882a593Smuzhiyun int sdram_init(void)
3567*4882a593Smuzhiyun {
3568*4882a593Smuzhiyun 	struct rv1126_sdram_params *sdram_params;
3569*4882a593Smuzhiyun 	int ret = 0;
3570*4882a593Smuzhiyun 	struct sdram_head_info_index_v2 *index =
3571*4882a593Smuzhiyun 		(struct sdram_head_info_index_v2 *)common_info;
3572*4882a593Smuzhiyun 	struct global_info *gbl_info;
3573*4882a593Smuzhiyun 
3574*4882a593Smuzhiyun 	dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
3575*4882a593Smuzhiyun 	dram_info.pctl = (void *)UPCTL2_BASE_ADDR;
3576*4882a593Smuzhiyun 	dram_info.grf = (void *)GRF_BASE_ADDR;
3577*4882a593Smuzhiyun 	dram_info.cru = (void *)CRU_BASE_ADDR;
3578*4882a593Smuzhiyun 	dram_info.msch = (void *)SERVER_MSCH_BASE_ADDR;
3579*4882a593Smuzhiyun 	dram_info.ddrgrf = (void *)DDR_GRF_BASE_ADDR;
3580*4882a593Smuzhiyun 	dram_info.pmugrf = (void *)PMU_GRF_BASE_ADDR;
3581*4882a593Smuzhiyun 
3582*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
3583*4882a593Smuzhiyun 	printascii("extended temp support\n");
3584*4882a593Smuzhiyun #endif
3585*4882a593Smuzhiyun 	if (index->version_info != 2 ||
3586*4882a593Smuzhiyun 	    (index->global_index.size != sizeof(struct global_info) / 4) ||
3587*4882a593Smuzhiyun 	    (index->ddr3_index.size !=
3588*4882a593Smuzhiyun 		sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
3589*4882a593Smuzhiyun 	    (index->ddr4_index.size !=
3590*4882a593Smuzhiyun 		sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
3591*4882a593Smuzhiyun 	    (index->lp3_index.size !=
3592*4882a593Smuzhiyun 		sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
3593*4882a593Smuzhiyun 	    (index->lp4_index.size != (sizeof(struct lp4_info) / 4)) ||
3594*4882a593Smuzhiyun 	    (index->lp4x_index.size != (sizeof(struct lp4_info) / 4)) ||
3595*4882a593Smuzhiyun 	    index->global_index.offset == 0 ||
3596*4882a593Smuzhiyun 	    index->ddr3_index.offset == 0 ||
3597*4882a593Smuzhiyun 	    index->ddr4_index.offset == 0 ||
3598*4882a593Smuzhiyun 	    index->lp3_index.offset == 0 ||
3599*4882a593Smuzhiyun 	    index->lp4_index.offset == 0 ||
3600*4882a593Smuzhiyun 	    index->lp4x_index.offset == 0) {
3601*4882a593Smuzhiyun 		printascii("common info error\n");
3602*4882a593Smuzhiyun 		goto error;
3603*4882a593Smuzhiyun 	}
3604*4882a593Smuzhiyun 
3605*4882a593Smuzhiyun 	gbl_info = (struct global_info *)((void *)common_info +
3606*4882a593Smuzhiyun 		index->global_index.offset * 4);
3607*4882a593Smuzhiyun 
3608*4882a593Smuzhiyun 	dram_info.sr_idle = SR_INFO(gbl_info->sr_pd_info);
3609*4882a593Smuzhiyun 	dram_info.pd_idle = PD_INFO(gbl_info->sr_pd_info);
3610*4882a593Smuzhiyun 
3611*4882a593Smuzhiyun 	sdram_params = &sdram_configs[0];
3612*4882a593Smuzhiyun 	#if (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 8)
3613*4882a593Smuzhiyun 	for (int j = 0; j < ARRAY_SIZE(sdram_configs); j++)
3614*4882a593Smuzhiyun 		sdram_configs[j].base.dramtype = LPDDR4X;
3615*4882a593Smuzhiyun 	#endif
3616*4882a593Smuzhiyun 	if (sdram_params->base.dramtype == DDR3 ||
3617*4882a593Smuzhiyun 	    sdram_params->base.dramtype == DDR4) {
3618*4882a593Smuzhiyun 		if (DDR_2T_INFO(gbl_info->info_2t))
3619*4882a593Smuzhiyun 			sdram_params->pctl_regs.pctl[0][1] |= 0x1 << 10;
3620*4882a593Smuzhiyun 		else
3621*4882a593Smuzhiyun 			sdram_params->pctl_regs.pctl[0][1] &=
3622*4882a593Smuzhiyun 				~(0x1 << 10);
3623*4882a593Smuzhiyun 	}
3624*4882a593Smuzhiyun 	ret = sdram_init_detect(&dram_info, sdram_params);
3625*4882a593Smuzhiyun 	if (ret) {
3626*4882a593Smuzhiyun 		sdram_print_dram_type(sdram_params->base.dramtype);
3627*4882a593Smuzhiyun 		printascii(", ");
3628*4882a593Smuzhiyun 		printdec(sdram_params->base.ddr_freq);
3629*4882a593Smuzhiyun 		printascii("MHz\n");
3630*4882a593Smuzhiyun 		goto error;
3631*4882a593Smuzhiyun 	}
3632*4882a593Smuzhiyun 	print_ddr_info(sdram_params);
3633*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
3634*4882a593Smuzhiyun 	init_rw_trn_result_struct(&rw_trn_result, dram_info.phy,
3635*4882a593Smuzhiyun 				  (u8)sdram_params->ch.cap_info.rank);
3636*4882a593Smuzhiyun #endif
3637*4882a593Smuzhiyun 
3638*4882a593Smuzhiyun 	ddr_set_rate_for_fsp(&dram_info, sdram_params);
3639*4882a593Smuzhiyun #ifndef CONFIG_SPL_KERNEL_BOOT
3640*4882a593Smuzhiyun 	copy_fsp_param_to_ddr();
3641*4882a593Smuzhiyun #endif
3642*4882a593Smuzhiyun 
3643*4882a593Smuzhiyun 	ddr_set_atags(&dram_info, sdram_params);
3644*4882a593Smuzhiyun #if defined(CONFIG_CMD_DDR_TEST_TOOL)
3645*4882a593Smuzhiyun 	save_rw_trn_result_to_ddr(&rw_trn_result);
3646*4882a593Smuzhiyun #endif
3647*4882a593Smuzhiyun 
3648*4882a593Smuzhiyun 	printascii("out\n");
3649*4882a593Smuzhiyun 
3650*4882a593Smuzhiyun 	return ret;
3651*4882a593Smuzhiyun error:
3652*4882a593Smuzhiyun 	printascii("error\n");
3653*4882a593Smuzhiyun 	return (-1);
3654*4882a593Smuzhiyun }
3655*4882a593Smuzhiyun #endif /* CONFIG_TPL_BUILD */
3656