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