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 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 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 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 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 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 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