diff options
author | Ashok Reddy Soma <ashok.reddy.soma@xilinx.com> | 2021-08-02 23:20:44 -0600 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2021-08-26 08:08:01 +0200 |
commit | 655d69faaf4bb1e7d3e9c31f07259b61c27e719e (patch) | |
tree | 26e6bde163669d5580065f547f591b8ea34960e3 /drivers | |
parent | d04498255559dfc002ad71816dfb37437d29f635 (diff) | |
download | u-boot-655d69faaf4bb1e7d3e9c31f07259b61c27e719e.zip u-boot-655d69faaf4bb1e7d3e9c31f07259b61c27e719e.tar.gz u-boot-655d69faaf4bb1e7d3e9c31f07259b61c27e719e.tar.bz2 |
mmc: zynq_sdhci: Move setting tapdelay code to driver
Move tapdelay function calls to zynq_sdhci.c and make them static
inline. zynqmp_tap_delay.h has function prototypes for the functions
defined in tap_delays.c, which will not be needed anymore.
Remove tap_delays.c and zynqmp_tap_delay.h files.
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/zynq_sdhci.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 8397f24..9a16939 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -15,9 +15,9 @@ #include <dm/device_compat.h> #include <linux/err.h> #include <linux/libfdt.h> +#include <asm/cache.h> #include <malloc.h> #include <sdhci.h> -#include <zynqmp_tap_delay.h> #include <zynqmp_firmware.h> #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 @@ -31,6 +31,20 @@ #define SDHCI_TUNING_LOOP_COUNT 40 #define MMC_BANK2 0x2 +#define SD_DLL_CTRL 0xFF180358 +#define SD_ITAP_DLY 0xFF180314 +#define SD_OTAP_DLY 0xFF180318 +#define SD0_DLL_RST BIT(2) +#define SD1_DLL_RST BIT(18) +#define SD0_ITAPCHGWIN BIT(9) +#define SD1_ITAPCHGWIN BIT(25) +#define SD0_ITAPDLYENA BIT(8) +#define SD1_ITAPDLYENA BIT(24) +#define SD0_ITAPDLYSEL_MASK GENMASK(7, 0) +#define SD1_ITAPDLYSEL_MASK GENMASK(23, 16) +#define SD0_OTAPDLYSEL_MASK GENMASK(5, 0) +#define SD1_OTAPDLYSEL_MASK GENMASK(21, 16) + struct arasan_sdhci_clk_data { int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; @@ -49,6 +63,12 @@ struct arasan_sdhci_priv { u8 no_1p8; }; +/* For Versal platforms zynqmp_mmio_write() won't be available */ +__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value) +{ + return 0; +} + #if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) /* Default settings for ZynqMP Clock Phases */ static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0, @@ -76,6 +96,92 @@ static const u8 mode2timing[] = { [MMC_HS_200] = MMC_TIMING_MMC_HS200, }; +static inline int arasan_zynqmp_set_in_tapdelay(u8 node_id, u32 itap_delay) +{ + int ret; + + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { + if (node_id == NODE_SD_0) { + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN, + SD0_ITAPCHGWIN); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA, + SD0_ITAPDLYENA); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, + itap_delay); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN, 0); + if (ret) + return ret; + } + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN, + SD1_ITAPCHGWIN); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA, + SD1_ITAPDLYENA); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK, + (itap_delay << 16)); + if (ret) + return ret; + + ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN, 0); + if (ret) + return ret; + } else { + return xilinx_pm_request(PM_IOCTL, (u32)node_id, + IOCTL_SET_SD_TAPDELAY, + PM_TAPDELAY_INPUT, itap_delay, NULL); + } + + return 0; +} + +static inline int arasan_zynqmp_set_out_tapdelay(u8 node_id, u32 otap_delay) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { + if (node_id == NODE_SD_0) + return zynqmp_mmio_write(SD_OTAP_DLY, + SD0_OTAPDLYSEL_MASK, + otap_delay); + + return zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK, + (otap_delay << 16)); + } else { + return xilinx_pm_request(PM_IOCTL, (u32)node_id, + IOCTL_SET_SD_TAPDELAY, + PM_TAPDELAY_OUTPUT, otap_delay, NULL); + } +} + +static inline int zynqmp_dll_reset(u8 node_id, u32 type) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { + if (node_id == NODE_SD_0) + return zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST, + type == PM_DLL_RESET_ASSERT ? + SD0_DLL_RST : 0); + + return zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST, + type == PM_DLL_RESET_ASSERT ? + SD1_DLL_RST : 0); + } else { + return xilinx_pm_request(PM_IOCTL, (u32)node_id, + IOCTL_SD_DLL_RESET, type, 0, NULL); + } +} + static int arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 node_id) { struct mmc *mmc = (struct mmc *)host->mmc; |