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