1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Xilinx ZynqMP SoC Tap Delay Programming
4  *
5  * Copyright (C) 2018 Xilinx, Inc.
6  */
7 
8 #include <common.h>
9 #include <asm/arch/sys_proto.h>
10 
11 #define SD_DLL_CTRL			0xFF180358
12 #define SD_ITAP_DLY			0xFF180314
13 #define SD_OTAP_DLY			0xFF180318
14 #define SD0_DLL_RST_MASK		0x00000004
15 #define SD0_DLL_RST			0x00000004
16 #define SD1_DLL_RST_MASK		0x00040000
17 #define SD1_DLL_RST			0x00040000
18 #define SD0_ITAPCHGWIN_MASK		0x00000200
19 #define SD0_ITAPCHGWIN			0x00000200
20 #define SD1_ITAPCHGWIN_MASK		0x02000000
21 #define SD1_ITAPCHGWIN			0x02000000
22 #define SD0_ITAPDLYENA_MASK		0x00000100
23 #define SD0_ITAPDLYENA			0x00000100
24 #define SD1_ITAPDLYENA_MASK		0x01000000
25 #define SD1_ITAPDLYENA			0x01000000
26 #define SD0_ITAPDLYSEL_MASK		0x000000FF
27 #define SD0_ITAPDLYSEL_HSD		0x00000015
28 #define SD0_ITAPDLYSEL_SD_DDR50		0x0000003D
29 #define SD0_ITAPDLYSEL_MMC_DDR50	0x00000012
30 
31 #define SD1_ITAPDLYSEL_MASK		0x00FF0000
32 #define SD1_ITAPDLYSEL_HSD		0x00150000
33 #define SD1_ITAPDLYSEL_SD_DDR50		0x003D0000
34 #define SD1_ITAPDLYSEL_MMC_DDR50	0x00120000
35 
36 #define SD0_OTAPDLYSEL_MASK		0x0000003F
37 #define SD0_OTAPDLYSEL_MMC_HSD		0x00000006
38 #define SD0_OTAPDLYSEL_SD_HSD		0x00000005
39 #define SD0_OTAPDLYSEL_SDR50		0x00000003
40 #define SD0_OTAPDLYSEL_SDR104_B0	0x00000003
41 #define SD0_OTAPDLYSEL_SDR104_B2	0x00000002
42 #define SD0_OTAPDLYSEL_SD_DDR50		0x00000004
43 #define SD0_OTAPDLYSEL_MMC_DDR50	0x00000006
44 
45 #define SD1_OTAPDLYSEL_MASK		0x003F0000
46 #define SD1_OTAPDLYSEL_MMC_HSD		0x00060000
47 #define SD1_OTAPDLYSEL_SD_HSD		0x00050000
48 #define SD1_OTAPDLYSEL_SDR50		0x00030000
49 #define SD1_OTAPDLYSEL_SDR104_B0	0x00030000
50 #define SD1_OTAPDLYSEL_SDR104_B2	0x00020000
51 #define SD1_OTAPDLYSEL_SD_DDR50		0x00040000
52 #define SD1_OTAPDLYSEL_MMC_DDR50	0x00060000
53 
54 #define MMC_BANK2		0x2
55 
56 #define MMC_TIMING_UHS_SDR25		1
57 #define MMC_TIMING_UHS_SDR50		2
58 #define MMC_TIMING_UHS_SDR104		3
59 #define MMC_TIMING_UHS_DDR50		4
60 #define MMC_TIMING_MMC_HS200		5
61 #define MMC_TIMING_SD_HS		6
62 #define MMC_TIMING_MMC_DDR52		7
63 #define MMC_TIMING_MMC_HS		8
64 
zynqmp_dll_reset(u8 deviceid)65 void zynqmp_dll_reset(u8 deviceid)
66 {
67 	/* Issue DLL Reset */
68 	if (deviceid == 0)
69 		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
70 				  SD0_DLL_RST);
71 	else
72 		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
73 				  SD1_DLL_RST);
74 
75 	mdelay(1);
76 
77 	/* Release DLL Reset */
78 	if (deviceid == 0)
79 		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
80 	else
81 		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
82 }
83 
arasan_zynqmp_tap_sdr104(u8 deviceid,u8 timing,u8 bank)84 static void arasan_zynqmp_tap_sdr104(u8 deviceid, u8 timing, u8 bank)
85 {
86 	if (deviceid == 0) {
87 		/* Program OTAP */
88 		if (bank == MMC_BANK2)
89 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
90 					  SD0_OTAPDLYSEL_SDR104_B2);
91 		else
92 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
93 					  SD0_OTAPDLYSEL_SDR104_B0);
94 	} else {
95 		/* Program OTAP */
96 		if (bank == MMC_BANK2)
97 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
98 					  SD1_OTAPDLYSEL_SDR104_B2);
99 		else
100 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
101 					  SD1_OTAPDLYSEL_SDR104_B0);
102 	}
103 }
104 
arasan_zynqmp_tap_hs(u8 deviceid,u8 timing,u8 bank)105 static void arasan_zynqmp_tap_hs(u8 deviceid, u8 timing, u8 bank)
106 {
107 	if (deviceid == 0) {
108 		/* Program ITAP */
109 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
110 				  SD0_ITAPCHGWIN);
111 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
112 				  SD0_ITAPDLYENA);
113 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
114 				  SD0_ITAPDLYSEL_HSD);
115 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
116 		/* Program OTAP */
117 		if (timing == MMC_TIMING_MMC_HS)
118 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
119 					  SD0_OTAPDLYSEL_MMC_HSD);
120 		else
121 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
122 					  SD0_OTAPDLYSEL_SD_HSD);
123 	} else {
124 		/* Program ITAP */
125 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
126 				  SD1_ITAPCHGWIN);
127 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
128 				  SD1_ITAPDLYENA);
129 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
130 				  SD1_ITAPDLYSEL_HSD);
131 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
132 		/* Program OTAP */
133 		if (timing == MMC_TIMING_MMC_HS)
134 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
135 					  SD1_OTAPDLYSEL_MMC_HSD);
136 		else
137 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
138 					  SD1_OTAPDLYSEL_SD_HSD);
139 	}
140 }
141 
arasan_zynqmp_tap_ddr50(u8 deviceid,u8 timing,u8 bank)142 static void arasan_zynqmp_tap_ddr50(u8 deviceid, u8 timing, u8 bank)
143 {
144 	if (deviceid == 0) {
145 		/* Program ITAP */
146 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
147 				  SD0_ITAPCHGWIN);
148 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
149 				  SD0_ITAPDLYENA);
150 		if (timing == MMC_TIMING_UHS_DDR50)
151 			zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
152 					  SD0_ITAPDLYSEL_SD_DDR50);
153 		else
154 			zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
155 					  SD0_ITAPDLYSEL_MMC_DDR50);
156 		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
157 		/* Program OTAP */
158 		if (timing == MMC_TIMING_UHS_DDR50)
159 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
160 					  SD0_OTAPDLYSEL_SD_DDR50);
161 		else
162 			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
163 					  SD0_OTAPDLYSEL_MMC_DDR50);
164 	} else {
165 		/* Program ITAP */
166 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
167 				  SD1_ITAPCHGWIN);
168 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
169 				  SD1_ITAPDLYENA);
170 		if (timing == MMC_TIMING_UHS_DDR50)
171 			zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
172 					  SD1_ITAPDLYSEL_SD_DDR50);
173 		else
174 			zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
175 					  SD1_ITAPDLYSEL_MMC_DDR50);
176 		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
177 		/* Program OTAP */
178 		if (timing == MMC_TIMING_UHS_DDR50)
179 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
180 					  SD1_OTAPDLYSEL_SD_DDR50);
181 		else
182 			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
183 					  SD1_OTAPDLYSEL_MMC_DDR50);
184 	}
185 }
186 
arasan_zynqmp_tap_sdr50(u8 deviceid,u8 timing,u8 bank)187 static void arasan_zynqmp_tap_sdr50(u8 deviceid, u8 timing, u8 bank)
188 {
189 	if (deviceid == 0) {
190 		/* Program OTAP */
191 		zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
192 				  SD0_OTAPDLYSEL_SDR50);
193 	} else {
194 		/* Program OTAP */
195 		zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
196 				  SD1_OTAPDLYSEL_SDR50);
197 	}
198 }
199 
arasan_zynqmp_set_tapdelay(u8 deviceid,u8 timing,u8 bank)200 void arasan_zynqmp_set_tapdelay(u8 deviceid, u8 timing, u8 bank)
201 {
202 	if (deviceid == 0)
203 		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
204 				  SD0_DLL_RST);
205 	else
206 		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
207 				  SD1_DLL_RST);
208 
209 	switch (timing) {
210 	case MMC_TIMING_UHS_SDR25:
211 		arasan_zynqmp_tap_hs(deviceid, timing, bank);
212 		break;
213 	case MMC_TIMING_UHS_SDR50:
214 		arasan_zynqmp_tap_sdr50(deviceid, timing, bank);
215 		break;
216 	case MMC_TIMING_UHS_SDR104:
217 	case MMC_TIMING_MMC_HS200:
218 		arasan_zynqmp_tap_sdr104(deviceid, timing, bank);
219 		break;
220 	case MMC_TIMING_UHS_DDR50:
221 		arasan_zynqmp_tap_ddr50(deviceid, timing, bank);
222 		break;
223 	}
224 
225 	if (deviceid == 0)
226 		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
227 	else
228 		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
229 }
230