From a70bdafd67afa8d5a5ec73280c74a51a03640b66 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 9 Jul 2021 05:53:42 -0600 Subject: [PATCH] mmc: zynq_sdhci: Split set_tapdelay function to in and out Split arasan_zynqmp_set_tapdelay() to handle input and output tapdelays separately. This is required to handle zero values for ITAP and OTAP values. If we dont split, we will have to remove the if() in the function, which makes ITAP values to be overwritten when OTAP values are called to set and vice-versa. Restrict tap_delay value calculated to max allowed 8 bits for ITAP and 6 bits for OTAP for ZynqMP. Signed-off-by: Ashok Reddy Soma Reviewed-by: Jaehoon Chung Signed-off-by: Michal Simek --- board/xilinx/zynqmp/tap_delays.c | 73 +++++++++++++++++++++------------------- drivers/mmc/zynq_sdhci.c | 10 ++++-- include/zynqmp_tap_delay.h | 7 ++-- 3 files changed, 50 insertions(+), 40 deletions(-) diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c index 1cab25f..d16bbb8 100644 --- a/board/xilinx/zynqmp/tap_delays.c +++ b/board/xilinx/zynqmp/tap_delays.c @@ -50,48 +50,51 @@ void zynqmp_dll_reset(u8 deviceid) zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); } -void arasan_zynqmp_set_tapdelay(u8 deviceid, u32 itap_delay, u32 otap_delay) +void arasan_zynqmp_set_in_tapdelay(u8 deviceid, u32 itap_delay) { if (deviceid == 0) { - zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, - SD0_DLL_RST); - /* Program ITAP */ - if (itap_delay) { - 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, - itap_delay); - zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, - 0x0); - } + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST); - /* Program OTAP */ - if (otap_delay) - zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, - otap_delay); + /* Program ITAP delay */ + 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, itap_delay); + zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0); zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); } else { - zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, - SD1_DLL_RST); - /* Program ITAP */ - if (itap_delay) { - 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, - (itap_delay << 16)); - zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, - 0x0); - } + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST); + + /* Program ITAP delay */ + 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, + (itap_delay << 16)); + zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0); + + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); + } +} + +void arasan_zynqmp_set_out_tapdelay(u8 deviceid, u32 otap_delay) +{ + if (deviceid == 0) { + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST); + + /* Program OTAP delay */ + zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, otap_delay); + + zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0); + } else { + zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST); - /* Program OTAP */ - if (otap_delay) - zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, - (otap_delay << 16)); + /* Program OTAP delay */ + zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, + (otap_delay << 16)); zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0); } diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index bf638e9..95d42cc 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -226,7 +226,10 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay); + /* Limit output tap_delay value to 6 bits */ + tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK; + + arasan_zynqmp_set_out_tapdelay(priv->deviceid, tap_delay); return 0; } @@ -279,7 +282,10 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, tap_delay = (degrees * tap_max) / 360; - arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0); + /* Limit input tap_delay value to 8 bits */ + tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK; + + arasan_zynqmp_set_in_tapdelay(priv->deviceid, tap_delay); return 0; } diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h index 7b71343..1c1e3e7 100644 --- a/include/zynqmp_tap_delay.h +++ b/include/zynqmp_tap_delay.h @@ -10,11 +10,12 @@ #ifdef CONFIG_ARCH_ZYNQMP void zynqmp_dll_reset(u8 deviceid); -void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, u32 otap_delay); +void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay); +void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay); #else inline void zynqmp_dll_reset(u8 deviceid) {} -inline void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, - u32 otap_delay) {} +inline void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay) {} +inline void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay) {} #endif #endif -- 2.7.4