uboot/board/xilinx/zynqmp/tap_delays.c
<<
>>
Prefs
   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
  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}
 230