blob: c3ae357bbdb1c7d4edf37acf56f1ca3d69d53577 [file] [log] [blame]
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301// 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
65void 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
84static 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
105static 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
142static 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
187static 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
200void 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}