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 <zynqmp_tap_delay.h>
10 #include <asm/arch/sys_proto.h>
11 #include <linux/delay.h>
12 #include <mmc.h>
13
14 #define SD_DLL_CTRL 0xFF180358
15 #define SD_ITAP_DLY 0xFF180314
16 #define SD_OTAP_DLY 0xFF180318
17 #define SD0_DLL_RST_MASK 0x00000004
18 #define SD0_DLL_RST 0x00000004
19 #define SD1_DLL_RST_MASK 0x00040000
20 #define SD1_DLL_RST 0x00040000
21 #define SD0_ITAPCHGWIN_MASK 0x00000200
22 #define SD0_ITAPCHGWIN 0x00000200
23 #define SD1_ITAPCHGWIN_MASK 0x02000000
24 #define SD1_ITAPCHGWIN 0x02000000
25 #define SD0_ITAPDLYENA_MASK 0x00000100
26 #define SD0_ITAPDLYENA 0x00000100
27 #define SD1_ITAPDLYENA_MASK 0x01000000
28 #define SD1_ITAPDLYENA 0x01000000
29 #define SD0_ITAPDLYSEL_MASK 0x000000FF
30 #define SD1_ITAPDLYSEL_MASK 0x00FF0000
31 #define SD0_OTAPDLYSEL_MASK 0x0000003F
32 #define SD1_OTAPDLYSEL_MASK 0x003F0000
33
zynqmp_dll_reset(u8 deviceid)34 void zynqmp_dll_reset(u8 deviceid)
35 {
36 /* Issue DLL Reset */
37 if (deviceid == 0)
38 zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
39 SD0_DLL_RST);
40 else
41 zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
42 SD1_DLL_RST);
43
44 mdelay(1);
45
46 /* Release DLL Reset */
47 if (deviceid == 0)
48 zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
49 else
50 zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
51 }
52
arasan_zynqmp_set_tapdelay(u8 deviceid,u32 itap_delay,u32 otap_delay)53 void arasan_zynqmp_set_tapdelay(u8 deviceid, u32 itap_delay, u32 otap_delay)
54 {
55 if (deviceid == 0) {
56 zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
57 SD0_DLL_RST);
58 /* Program ITAP */
59 if (itap_delay) {
60 zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
61 SD0_ITAPCHGWIN);
62 zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
63 SD0_ITAPDLYENA);
64 zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
65 itap_delay);
66 zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
67 0x0);
68 }
69
70 /* Program OTAP */
71 if (otap_delay)
72 zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
73 otap_delay);
74
75 zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
76 } else {
77 zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
78 SD1_DLL_RST);
79 /* Program ITAP */
80 if (itap_delay) {
81 zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
82 SD1_ITAPCHGWIN);
83 zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
84 SD1_ITAPDLYENA);
85 zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
86 (itap_delay << 16));
87 zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
88 0x0);
89 }
90
91 /* Program OTAP */
92 if (otap_delay)
93 zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
94 (otap_delay << 16));
95
96 zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
97 }
98 }
99