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