This patch adds support of SD3.0 for ZynqMP. Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>lime2-spi
parent
b8e25ef16a
commit
d1f4e39d58
@ -0,0 +1,229 @@ |
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Xilinx ZynqMP SoC Tap Delay Programming |
||||||
|
* |
||||||
|
* Copyright (C) 2018 Xilinx, Inc. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <common.h> |
||||||
|
#include <asm/arch/sys_proto.h> |
||||||
|
|
||||||
|
#define SD_DLL_CTRL 0xFF180358 |
||||||
|
#define SD_ITAP_DLY 0xFF180314 |
||||||
|
#define SD_OTAP_DLY 0xFF180318 |
||||||
|
#define SD0_DLL_RST_MASK 0x00000004 |
||||||
|
#define SD0_DLL_RST 0x00000004 |
||||||
|
#define SD1_DLL_RST_MASK 0x00040000 |
||||||
|
#define SD1_DLL_RST 0x00040000 |
||||||
|
#define SD0_ITAPCHGWIN_MASK 0x00000200 |
||||||
|
#define SD0_ITAPCHGWIN 0x00000200 |
||||||
|
#define SD1_ITAPCHGWIN_MASK 0x02000000 |
||||||
|
#define SD1_ITAPCHGWIN 0x02000000 |
||||||
|
#define SD0_ITAPDLYENA_MASK 0x00000100 |
||||||
|
#define SD0_ITAPDLYENA 0x00000100 |
||||||
|
#define SD1_ITAPDLYENA_MASK 0x01000000 |
||||||
|
#define SD1_ITAPDLYENA 0x01000000 |
||||||
|
#define SD0_ITAPDLYSEL_MASK 0x000000FF |
||||||
|
#define SD0_ITAPDLYSEL_HSD 0x00000015 |
||||||
|
#define SD0_ITAPDLYSEL_SD_DDR50 0x0000003D |
||||||
|
#define SD0_ITAPDLYSEL_MMC_DDR50 0x00000012 |
||||||
|
|
||||||
|
#define SD1_ITAPDLYSEL_MASK 0x00FF0000 |
||||||
|
#define SD1_ITAPDLYSEL_HSD 0x00150000 |
||||||
|
#define SD1_ITAPDLYSEL_SD_DDR50 0x003D0000 |
||||||
|
#define SD1_ITAPDLYSEL_MMC_DDR50 0x00120000 |
||||||
|
|
||||||
|
#define SD0_OTAPDLYSEL_MASK 0x0000003F |
||||||
|
#define SD0_OTAPDLYSEL_MMC_HSD 0x00000006 |
||||||
|
#define SD0_OTAPDLYSEL_SD_HSD 0x00000005 |
||||||
|
#define SD0_OTAPDLYSEL_SDR50 0x00000003 |
||||||
|
#define SD0_OTAPDLYSEL_SDR104_B0 0x00000003 |
||||||
|
#define SD0_OTAPDLYSEL_SDR104_B2 0x00000002 |
||||||
|
#define SD0_OTAPDLYSEL_SD_DDR50 0x00000004 |
||||||
|
#define SD0_OTAPDLYSEL_MMC_DDR50 0x00000006 |
||||||
|
|
||||||
|
#define SD1_OTAPDLYSEL_MASK 0x003F0000 |
||||||
|
#define SD1_OTAPDLYSEL_MMC_HSD 0x00060000 |
||||||
|
#define SD1_OTAPDLYSEL_SD_HSD 0x00050000 |
||||||
|
#define SD1_OTAPDLYSEL_SDR50 0x00030000 |
||||||
|
#define SD1_OTAPDLYSEL_SDR104_B0 0x00030000 |
||||||
|
#define SD1_OTAPDLYSEL_SDR104_B2 0x00020000 |
||||||
|
#define SD1_OTAPDLYSEL_SD_DDR50 0x00040000 |
||||||
|
#define SD1_OTAPDLYSEL_MMC_DDR50 0x00060000 |
||||||
|
|
||||||
|
#define MMC_BANK2 0x2 |
||||||
|
|
||||||
|
#define MMC_TIMING_UHS_SDR25 1 |
||||||
|
#define MMC_TIMING_UHS_SDR50 2 |
||||||
|
#define MMC_TIMING_UHS_SDR104 3 |
||||||
|
#define MMC_TIMING_UHS_DDR50 4 |
||||||
|
#define MMC_TIMING_MMC_HS200 5 |
||||||
|
#define MMC_TIMING_SD_HS 6 |
||||||
|
#define MMC_TIMING_MMC_DDR52 7 |
||||||
|
#define MMC_TIMING_MMC_HS 8 |
||||||
|
|
||||||
|
void zynqmp_dll_reset(u8 deviceid) |
||||||
|
{ |
||||||
|
/* Issue DLL Reset */ |
||||||
|
if (deviceid == 0) |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, |
||||||
|
SD0_DLL_RST); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, |
||||||
|
SD1_DLL_RST); |
||||||
|
|
||||||
|
mdelay(1); |
||||||
|
|
||||||
|
/* Release DLL Reset */ |
||||||
|
if (deviceid == 0) |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); |
||||||
|
} |
||||||
|
|
||||||
|
static void arasan_zynqmp_tap_sdr104(u8 deviceid, u8 timing, u8 bank) |
||||||
|
{ |
||||||
|
if (deviceid == 0) { |
||||||
|
/* Program OTAP */ |
||||||
|
if (bank == MMC_BANK2) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_SDR104_B2); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_SDR104_B0); |
||||||
|
} else { |
||||||
|
/* Program OTAP */ |
||||||
|
if (bank == MMC_BANK2) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_SDR104_B2); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_SDR104_B0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void arasan_zynqmp_tap_hs(u8 deviceid, u8 timing, u8 bank) |
||||||
|
{ |
||||||
|
if (deviceid == 0) { |
||||||
|
/* Program ITAP */ |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, |
||||||
|
SD0_ITAPCHGWIN); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK, |
||||||
|
SD0_ITAPDLYENA); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, |
||||||
|
SD0_ITAPDLYSEL_HSD); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0); |
||||||
|
/* Program OTAP */ |
||||||
|
if (timing == MMC_TIMING_MMC_HS) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_MMC_HSD); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_SD_HSD); |
||||||
|
} else { |
||||||
|
/* Program ITAP */ |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, |
||||||
|
SD1_ITAPCHGWIN); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK, |
||||||
|
SD1_ITAPDLYENA); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, |
||||||
|
SD1_ITAPDLYSEL_HSD); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0); |
||||||
|
/* Program OTAP */ |
||||||
|
if (timing == MMC_TIMING_MMC_HS) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_MMC_HSD); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_SD_HSD); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void arasan_zynqmp_tap_ddr50(u8 deviceid, u8 timing, u8 bank) |
||||||
|
{ |
||||||
|
if (deviceid == 0) { |
||||||
|
/* Program ITAP */ |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, |
||||||
|
SD0_ITAPCHGWIN); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK, |
||||||
|
SD0_ITAPDLYENA); |
||||||
|
if (timing == MMC_TIMING_UHS_DDR50) |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, |
||||||
|
SD0_ITAPDLYSEL_SD_DDR50); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, |
||||||
|
SD0_ITAPDLYSEL_MMC_DDR50); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0); |
||||||
|
/* Program OTAP */ |
||||||
|
if (timing == MMC_TIMING_UHS_DDR50) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_SD_DDR50); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_MMC_DDR50); |
||||||
|
} else { |
||||||
|
/* Program ITAP */ |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, |
||||||
|
SD1_ITAPCHGWIN); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK, |
||||||
|
SD1_ITAPDLYENA); |
||||||
|
if (timing == MMC_TIMING_UHS_DDR50) |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, |
||||||
|
SD1_ITAPDLYSEL_SD_DDR50); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, |
||||||
|
SD1_ITAPDLYSEL_MMC_DDR50); |
||||||
|
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0); |
||||||
|
/* Program OTAP */ |
||||||
|
if (timing == MMC_TIMING_UHS_DDR50) |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_SD_DDR50); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_MMC_DDR50); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void arasan_zynqmp_tap_sdr50(u8 deviceid, u8 timing, u8 bank) |
||||||
|
{ |
||||||
|
if (deviceid == 0) { |
||||||
|
/* Program OTAP */ |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, |
||||||
|
SD0_OTAPDLYSEL_SDR50); |
||||||
|
} else { |
||||||
|
/* Program OTAP */ |
||||||
|
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, |
||||||
|
SD1_OTAPDLYSEL_SDR50); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void arasan_zynqmp_set_tapdelay(u8 deviceid, u8 timing, u8 bank) |
||||||
|
{ |
||||||
|
if (deviceid == 0) |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, |
||||||
|
SD0_DLL_RST); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, |
||||||
|
SD1_DLL_RST); |
||||||
|
|
||||||
|
switch (timing) { |
||||||
|
case MMC_TIMING_UHS_SDR25: |
||||||
|
arasan_zynqmp_tap_hs(deviceid, timing, bank); |
||||||
|
break; |
||||||
|
case MMC_TIMING_UHS_SDR50: |
||||||
|
arasan_zynqmp_tap_sdr50(deviceid, timing, bank); |
||||||
|
break; |
||||||
|
case MMC_TIMING_UHS_SDR104: |
||||||
|
case MMC_TIMING_MMC_HS200: |
||||||
|
arasan_zynqmp_tap_sdr104(deviceid, timing, bank); |
||||||
|
break; |
||||||
|
case MMC_TIMING_UHS_DDR50: |
||||||
|
arasan_zynqmp_tap_ddr50(deviceid, timing, bank); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (deviceid == 0) |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); |
||||||
|
else |
||||||
|
zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */ |
||||||
|
/*
|
||||||
|
* Xilinx ZynqMP SoC Tap Delay Programming |
||||||
|
* |
||||||
|
* Copyright (C) 2018 Xilinx, Inc. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ZYNQMP_TAP_DELAY_H__ |
||||||
|
#define __ZYNQMP_TAP_DELAY_H__ |
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_ZYNQMP |
||||||
|
void zynqmp_dll_reset(u8 deviceid); |
||||||
|
void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank); |
||||||
|
#else |
||||||
|
inline void zynqmp_dll_reset(u8 deviceid) {} |
||||||
|
inline void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank) {} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue