• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <common.h>
7 #include <ram.h>
8 #include <asm/io.h>
9 #include <asm/arch-rockchip/sdram.h>
10 #include <asm/arch-rockchip/sdram_common.h>
11 #include <asm/arch-rockchip/sdram_phy_px30.h>
12 
sdram_phy_dll_bypass_set(void __iomem * phy_base,u32 freq)13 static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
14 {
15 	u32 tmp;
16 	u32 i, j;
17 	u32 dqs_dll_freq;
18 
19 	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
20 	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
21 	for (i = 0; i < 4; i++) {
22 		j = 0x26 + i * 0x10;
23 		setbits_le32(PHY_REG(phy_base, j), 1 << 4);
24 		clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
25 	}
26 
27 	if (freq <= 400)
28 		/* DLL bypass */
29 		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
30 	else
31 		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
32 
33 	#ifdef CONFIG_ROCKCHIP_RK3328
34 	dqs_dll_freq = 680;
35 	#else
36 	dqs_dll_freq = 801;
37 	#endif
38 
39 	if (freq <= dqs_dll_freq)
40 		tmp = 2;
41 	else
42 		tmp = 1;
43 
44 	for (i = 0; i < 4; i++) {
45 		j = 0x28 + i * 0x10;
46 		writel(tmp, PHY_REG(phy_base, j));
47 	}
48 }
49 
sdram_phy_set_ds_odt(void __iomem * phy_base,u32 dram_type)50 static void sdram_phy_set_ds_odt(void __iomem *phy_base,
51 				 u32 dram_type)
52 {
53 	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
54 	u32 i, j;
55 
56 	if (dram_type == DDR3) {
57 		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
58 		clk_drv = PHY_DDR3_RON_RTT_45ohm;
59 		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
60 		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
61 	} else {
62 		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
63 		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
64 		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
65 		if (dram_type == LPDDR2)
66 			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
67 		else
68 			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
69 	}
70 	/* DS */
71 	writel(cmd_drv, PHY_REG(phy_base, 0x11));
72 	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
73 	writel(clk_drv, PHY_REG(phy_base, 0x16));
74 	writel(clk_drv, PHY_REG(phy_base, 0x18));
75 
76 	for (i = 0; i < 4; i++) {
77 		j = 0x20 + i * 0x10;
78 		writel(dqs_drv, PHY_REG(phy_base, j));
79 		writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
80 		/* ODT */
81 		writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
82 		writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
83 	}
84 }
85 
phy_soft_reset(void __iomem * phy_base)86 void phy_soft_reset(void __iomem *phy_base)
87 {
88 	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
89 	udelay(1);
90 	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
91 	udelay(5);
92 	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
93 	udelay(1);
94 }
95 
phy_dram_set_bw(void __iomem * phy_base,u32 bw)96 void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
97 {
98 	if (bw == 2) {
99 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
100 		setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
101 		setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
102 	} else if (bw == 1) {
103 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
104 		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
105 		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
106 	} else if (bw == 0) {
107 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
108 		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
109 		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
110 		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
111 	}
112 
113 	phy_soft_reset(phy_base);
114 }
115 
phy_data_training(void __iomem * phy_base,u32 cs,u32 dramtype)116 int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
117 {
118 	u32 ret;
119 	u32 odt_val;
120 	u32 i, j;
121 
122 	odt_val = readl(PHY_REG(phy_base, 0x2e));
123 
124 	for (i = 0; i < 4; i++) {
125 		j = 0x20 + i * 0x10;
126 		writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
127 		writel(0, PHY_REG(phy_base, j + 0xe));
128 	}
129 
130 	if (dramtype == DDR4) {
131 		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
132 		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
133 		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
134 		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
135 	}
136 	/* choose training cs */
137 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
138 	/* enable gate training */
139 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
140 	udelay(50);
141 	ret = readl(PHY_REG(phy_base, 0xff));
142 	/* disable gate training */
143 	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
144 	#ifndef CONFIG_ROCKCHIP_RK3328
145 	clrbits_le32(PHY_REG(phy_base, 2), 0x30);
146 	#endif
147 
148 	if (dramtype == DDR4) {
149 		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
150 		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
151 		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
152 		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
153 	}
154 
155 	if (ret & 0x10) {
156 		ret = -1;
157 	} else {
158 		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
159 		ret = (ret == 0) ? 0 : -1;
160 	}
161 
162 	for (i = 0; i < 4; i++) {
163 		j = 0x20 + i * 0x10;
164 		writel(odt_val, PHY_REG(phy_base, j + 0x1));
165 		writel(odt_val, PHY_REG(phy_base, j + 0xe));
166 	}
167 	return ret;
168 }
169 
phy_cfg(void __iomem * phy_base,struct ddr_phy_regs * phy_regs,struct ddr_phy_skew * skew,struct sdram_base_params * base,u32 bw)170 void phy_cfg(void __iomem *phy_base,
171 	     struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
172 	     struct sdram_base_params *base, u32 bw)
173 {
174 	u32 i;
175 
176 	sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
177 	for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
178 		writel(phy_regs->phy[i][1],
179 		       phy_base + phy_regs->phy[i][0]);
180 	}
181 	if (bw == 2) {
182 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
183 	} else if (bw == 1) {
184 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
185 		/* disable DQS2,DQS3 tx dll  for saving power */
186 		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
187 		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
188 	} else {
189 		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
190 		/* disable DQS2,DQS3 tx dll  for saving power */
191 		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
192 		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
193 		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
194 	}
195 	sdram_phy_set_ds_odt(phy_base, base->dramtype);
196 
197 	/* deskew */
198 	setbits_le32(PHY_REG(phy_base, 2), 8);
199 	sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
200 			  &skew->a0_a1_skew[0], 15 * 4);
201 	sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
202 			  &skew->cs0_dm0_skew[0], 44 * 4);
203 	sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
204 			  &skew->cs1_dm0_skew[0], 44 * 4);
205 }
206