[U-Boot] [UBOOT PATCH v3 0/7] Add support of SD3.0 UHS modes for ZynqMP

This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
-- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

From: Siva Durga Prasad Paladugu sivadur@xilinx.com
This patch adds support to disable clock if clk_disable was set and then enable or set clock if the clock was changed or clock was disabled when clock needs to be enabled.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com --- Changes in v3: - Removed clk_disabled in sdhci_host structure --- drivers/mmc/sdhci.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index d31793a..73d17d7 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -440,6 +440,9 @@ static int sdhci_set_ios(struct mmc *mmc) if (mmc->clock != host->clock) sdhci_set_clock(mmc, mmc->clock);
+ if (mmc->clk_disable) + sdhci_set_clock(mmc, 0); + /* Set bus width */ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (mmc->bus_width == 8) { -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

From: Siva Durga Prasad Paladugu sivadur@xilinx.com
This patch upadted sdhci_send_command to handle execute tuning command.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com --- drivers/mmc/sdhci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 73d17d7..2ce3b57 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -161,7 +161,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
/* We shouldn't wait for data inihibit for stop commands, even though they might use busy signaling */ - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION || + cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) mask &= ~SDHCI_DATA_INHIBIT;
while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { @@ -183,6 +184,9 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
mask = SDHCI_INT_RESPONSE; + if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) + mask = SDHCI_INT_DATA_AVAIL; + if (!(cmd->resp_type & MMC_RSP_PRESENT)) flags = SDHCI_CMD_RESP_NONE; else if (cmd->resp_type & MMC_RSP_136) @@ -198,7 +202,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, flags |= SDHCI_CMD_CRC; if (cmd->resp_type & MMC_RSP_OPCODE) flags |= SDHCI_CMD_INDEX; - if (data) + if (data || cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) flags |= SDHCI_CMD_DATA;
/* Set Transfer mode regarding to data flag */ -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

From: Siva Durga Prasad Paladugu sivadur@xilinx.com
This patch adds new hooks for any platform specific tuning and tap delays programing. These are needed for supporting SD3.0.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com --- include/sdhci.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/sdhci.h b/include/sdhci.h index 7e84012..9e8302e 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -237,6 +237,8 @@ struct sdhci_ops { void (*set_control_reg)(struct sdhci_host *host); void (*set_ios_post)(struct sdhci_host *host); void (*set_clock)(struct sdhci_host *host, u32 div); + int (*platform_execute_tuning)(struct mmc *host, u8 opcode); + void (*set_delay)(struct sdhci_host *host); };
struct sdhci_host { -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

From: Siva Durga Prasad Paladugu sivadur@xilinx.com
This patch adds support to invoke any platform specific tuning and delay routines if available.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com --- drivers/mmc/sdhci.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 2ce3b57..c17ab12 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -306,6 +306,24 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, return -ECOMM; }
+#if defined(CONFIG_DM_MMC) && defined(MMC_SUPPORTS_TUNING) +static int sdhci_execute_tuning(struct udevice *dev, uint opcode) +{ + int err; + struct mmc *mmc = mmc_get_mmc_dev(dev); + struct sdhci_host *host = mmc->priv; + + debug("%s\n", __func__); + + if (host->ops->platform_execute_tuning) { + err = host->ops->platform_execute_tuning(mmc, opcode); + if (err) + return err; + return 0; + } + return 0; +} +#endif static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) { struct sdhci_host *host = mmc->priv; @@ -330,6 +348,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) if (clock == 0) return 0;
+ if (host->ops->set_delay) + host->ops->set_delay(host); + if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { /* * Check if the Host Controller supports Programmable Clock @@ -521,6 +542,9 @@ int sdhci_probe(struct udevice *dev) const struct dm_mmc_ops sdhci_ops = { .send_cmd = sdhci_send_command, .set_ios = sdhci_set_ios, +#ifdef MMC_SUPPORTS_TUNING + .execute_tuning = sdhci_execute_tuning, +#endif }; #else static const struct mmc_ops sdhci_ops = { -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

From: Siva Durga Prasad Paladugu sivadur@xilinx.com
This patch reads the capabilities register1 and update the host caps accordingly for mmc layer usage. This patch mainly reads for UHS capabilities inorder to support SD3.0.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com --- drivers/mmc/sdhci.c | 28 +++++++++++++++++++++++++++- include/sdhci.h | 6 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index c17ab12..1cbd1bb 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -557,7 +557,7 @@ static const struct mmc_ops sdhci_ops = { int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, u32 f_max, u32 f_min) { - u32 caps, caps_1; + u32 caps, caps_1 = 0;
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
@@ -633,6 +633,32 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, cfg->host_caps &= ~MMC_MODE_8BIT; }
+ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); + + if (!(cfg->voltages & MMC_VDD_165_195) || + (host->quirks & SDHCI_QUIRK_NO_1_8_V)) + caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | + SDHCI_SUPPORT_DDR50); + + if (caps_1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | + SDHCI_SUPPORT_DDR50)) + cfg->host_caps |= MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25); + + if (caps_1 & SDHCI_SUPPORT_SDR104) { + cfg->host_caps |= MMC_CAP(UHS_SDR104) | MMC_CAP(UHS_SDR50); + /* + * SD3.0: SDR104 is supported so (for eMMC) the caps2 + * field can be promoted to support HS200. + */ + cfg->host_caps |= MMC_CAP(MMC_HS_200); + } else if (caps_1 & SDHCI_SUPPORT_SDR50) { + cfg->host_caps |= MMC_CAP(UHS_SDR50); + } + + if (caps_1 & SDHCI_SUPPORT_DDR50) + cfg->host_caps |= MMC_CAP(UHS_DDR50); + if (host->host_caps) cfg->host_caps |= host->host_caps;
diff --git a/include/sdhci.h b/include/sdhci.h index 9e8302e..72957dc 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -167,6 +167,11 @@ #define SDHCI_CAN_64BIT BIT(28)
#define SDHCI_CAPABILITIES_1 0x44 +#define SDHCI_SUPPORT_SDR50 0x00000001 +#define SDHCI_SUPPORT_SDR104 0x00000002 +#define SDHCI_SUPPORT_DDR50 0x00000004 +#define SDHCI_USE_SDR50_TUNING 0x00002000 + #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 #define SDHCI_CLOCK_MUL_SHIFT 16
@@ -215,6 +220,7 @@ #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4) #define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6) #define SDHCI_QUIRK_USE_WIDE8 (1 << 8) +#define SDHCI_QUIRK_NO_1_8_V (1 << 9)
/* to make gcc happy */ struct sdhci_host; -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

This patch adds support of SD3.0 for ZynqMP.
Signed-off-by: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com --- Changes for v3: - Used macro for loop counter - Made printf to debug - Fixed if condition to reduce a line as per comment --- board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/zynq_sdhci.c | 231 ++++++++++++++++++++++++++++++++++++++- include/zynqmp_tap_delay.h | 20 ++++ 4 files changed, 477 insertions(+), 5 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 3b7a10e..1d43928 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -26,6 +26,8 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif
+obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o + ifndef CONFIG_SPL_BUILD obj-$(CONFIG_CMD_ZYNQMP) += cmds.o endif diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c new file mode 100644 index 0000000..c3ae357 --- /dev/null +++ b/board/xilinx/zynqmp/tap_delays.c @@ -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); +} diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 9463a06..d61ccaa 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -10,9 +10,11 @@ #include <common.h> #include <dm.h> #include <fdtdec.h> +#include "mmc_private.h" #include <linux/libfdt.h> #include <malloc.h> #include <sdhci.h> +#include <zynqmp_tap_delay.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -22,15 +24,212 @@ struct arasan_sdhci_plat { unsigned int f_max; };
+struct arasan_sdhci_priv { + struct sdhci_host *host; + u8 deviceid; + u8 bank; + u8 no_1p8; + bool pwrseq; +}; + +#if defined(CONFIG_ARCH_ZYNQMP) +static const u8 mode2timing[] = { + [UHS_SDR12] = UHS_SDR12_BUS_SPEED, + [UHS_SDR25] = UHS_SDR25_BUS_SPEED, + [UHS_SDR50] = UHS_SDR50_BUS_SPEED, + [UHS_SDR104] = UHS_SDR104_BUS_SPEED, + [UHS_DDR50] = UHS_DDR50_BUS_SPEED, +}; + +#define SDHCI_HOST_CTRL2 0x3E +#define SDHCI_CTRL2_MODE_MASK 0x7 +#define SDHCI_18V_SIGNAL 0x8 +#define SDHCI_CTRL_EXEC_TUNING 0x0040 +#define SDHCI_CTRL_TUNED_CLK 0x80 +#define SDHCI_TUNING_LOOP_COUNT 40 + +static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid) +{ + u16 clk; + unsigned long timeout; + + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + clk &= ~(SDHCI_CLOCK_CARD_EN); + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Issue DLL Reset */ + zynqmp_dll_reset(deviceid); + + /* Wait max 20 ms */ + timeout = 100; + while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + dev_err(mmc_dev(host->mmc), + ": Internal clock never stabilised.\n"); + return; + } + timeout--; + udelay(1000); + } + + clk |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); +} + +static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) +{ + struct mmc_cmd cmd; + struct mmc_data data; + u32 ctrl; + struct sdhci_host *host; + struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev); + u8 tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT; + u8 deviceid; + + debug("%s\n", __func__); + + host = priv->host; + deviceid = priv->deviceid; + + ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2); + ctrl |= SDHCI_CTRL_EXEC_TUNING; + sdhci_writew(host, ctrl, SDHCI_HOST_CTRL2); + + mdelay(1); + + arasan_zynqmp_dll_reset(host, deviceid); + + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE); + + do { + cmd.cmdidx = opcode; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 0; + + data.blocksize = 64; + data.blocks = 1; + data.flags = MMC_DATA_READ; + + if (tuning_loop_counter-- == 0) + break; + + if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 && + mmc->bus_width == 8) + data.blocksize = 128; + + sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, + data.blocksize), + SDHCI_BLOCK_SIZE); + sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT); + sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); + + mmc_send_cmd(mmc, &cmd, NULL); + ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2); + + if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK) + udelay(1); + + } while (ctrl & SDHCI_CTRL_EXEC_TUNING); + + if (tuning_loop_counter < 0) { + ctrl &= ~SDHCI_CTRL_TUNED_CLK; + sdhci_writel(host, ctrl, SDHCI_HOST_CTRL2); + } + + if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) { + printf("%s:Tuning failed\n", __func__); + return -1; + } + + udelay(1); + arasan_zynqmp_dll_reset(host, deviceid); + + /* Enable only interrupts served by the SD controller */ + sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, + SDHCI_INT_ENABLE); + /* Mask all sdhci interrupt sources */ + sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE); + + return 0; +} + +static void arasan_sdhci_set_tapdelay(struct sdhci_host *host) +{ + struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); + struct mmc *mmc = (struct mmc *)host->mmc; + u8 uhsmode; + + if (!IS_SD(mmc)) + return; + + uhsmode = mode2timing[mmc->selected_mode]; + + if (uhsmode >= UHS_SDR25_BUS_SPEED) + arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode, + priv->bank); +} + +static void arasan_sdhci_set_control_reg(struct sdhci_host *host) +{ + struct mmc *mmc = (struct mmc *)host->mmc; + u32 reg; + + if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { + reg = sdhci_readw(host, SDHCI_HOST_CTRL2); + reg |= SDHCI_18V_SIGNAL; + sdhci_writew(host, reg, SDHCI_HOST_CTRL2); + } + + if (mmc->selected_mode > SD_HS && + mmc->selected_mode <= UHS_DDR50) { + reg = sdhci_readw(host, SDHCI_HOST_CTRL2); + reg &= ~SDHCI_CTRL2_MODE_MASK; + switch (mmc->selected_mode) { + case UHS_SDR12: + reg |= UHS_SDR12_BUS_SPEED; + break; + case UHS_SDR25: + reg |= UHS_SDR25_BUS_SPEED; + break; + case UHS_SDR50: + reg |= UHS_SDR50_BUS_SPEED; + break; + case UHS_SDR104: + reg |= UHS_SDR104_BUS_SPEED; + break; + case UHS_DDR50: + reg |= UHS_DDR50_BUS_SPEED; + break; + default: + break; + } + sdhci_writew(host, reg, SDHCI_HOST_CTRL2); + } +} +#endif + +#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP) +const struct sdhci_ops arasan_ops = { + .platform_execute_tuning = &arasan_sdhci_execute_tuning, + .set_delay = &arasan_sdhci_set_tapdelay, + .set_control_reg = &arasan_sdhci_set_control_reg, +}; +#endif + static int arasan_sdhci_probe(struct udevice *dev) { struct arasan_sdhci_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct sdhci_host *host = dev_get_priv(dev); + struct arasan_sdhci_priv *priv = dev_get_priv(dev); + struct sdhci_host *host; struct clk clk; unsigned long clock; int ret;
+ host = priv->host; + ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) { dev_err(dev, "failed to get clock\n"); @@ -42,6 +241,7 @@ static int arasan_sdhci_probe(struct udevice *dev) dev_err(dev, "failed to get rate\n"); return clock; } + debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk); @@ -57,6 +257,9 @@ static int arasan_sdhci_probe(struct udevice *dev) host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; #endif
+ if (priv->no_1p8) + host->quirks |= SDHCI_QUIRK_NO_1_8_V; + host->max_clk = clock;
ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max, @@ -74,10 +277,28 @@ static int arasan_sdhci_probe(struct udevice *dev) static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) { struct arasan_sdhci_plat *plat = dev_get_platdata(dev); - struct sdhci_host *host = dev_get_priv(dev); + struct arasan_sdhci_priv *priv = dev_get_priv(dev); + + priv->host = calloc(1, sizeof(struct sdhci_host)); + if (!priv->host) + return -1;
- host->name = dev->name; - host->ioaddr = (void *)devfdt_get_addr(dev); + priv->host->name = dev->name; + priv->host->ioaddr = (void *)devfdt_get_addr(dev); + + priv->deviceid = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "xlnx,device_id", -1); + priv->bank = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "xlnx,mio_bank", -1); + if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), + "no-1-8-v", NULL)) + priv->no_1p8 = 1; + else + priv->no_1p8 = 0; + +#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP) + priv->host->ops = &arasan_ops; +#endif
plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ); @@ -105,6 +326,6 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = { .ops = &sdhci_ops, .bind = arasan_sdhci_bind, .probe = arasan_sdhci_probe, - .priv_auto_alloc_size = sizeof(struct sdhci_host), + .priv_auto_alloc_size = sizeof(struct arasan_sdhci_priv), .platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat), }; diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h new file mode 100644 index 0000000..63be099 --- /dev/null +++ b/include/zynqmp_tap_delay.h @@ -0,0 +1,20 @@ +// 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 -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch adds support of SD3.0 for ZynqMP.
Signed-off-by: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Changes for v3:
- Used macro for loop counter
- Made printf to debug
- Fixed if condition to reduce a line as per comment
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/zynq_sdhci.c | 231 ++++++++++++++++++++++++++++++++++++++- include/zynqmp_tap_delay.h | 20 ++++ 4 files changed, 477 insertions(+), 5 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 3b7a10e..1d43928 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -26,6 +26,8 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif
+obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_CMD_ZYNQMP) += cmds.o endif diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c new file mode 100644 index 0000000..c3ae357 --- /dev/null +++ b/board/xilinx/zynqmp/tap_delays.c @@ -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);
+} diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 9463a06..d61ccaa 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -10,9 +10,11 @@ #include <common.h> #include <dm.h> #include <fdtdec.h> +#include "mmc_private.h" #include <linux/libfdt.h> #include <malloc.h> #include <sdhci.h> +#include <zynqmp_tap_delay.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -22,15 +24,212 @@ struct arasan_sdhci_plat { unsigned int f_max; };
+struct arasan_sdhci_priv {
- struct sdhci_host *host;
- u8 deviceid;
- u8 bank;
- u8 no_1p8;
- bool pwrseq;
+};
+#if defined(CONFIG_ARCH_ZYNQMP) +static const u8 mode2timing[] = {
[UHS_SDR12] = UHS_SDR12_BUS_SPEED,
[UHS_SDR25] = UHS_SDR25_BUS_SPEED,
[UHS_SDR50] = UHS_SDR50_BUS_SPEED,
[UHS_SDR104] = UHS_SDR104_BUS_SPEED,
[UHS_DDR50] = UHS_DDR50_BUS_SPEED,
+};
+#define SDHCI_HOST_CTRL2 0x3E +#define SDHCI_CTRL2_MODE_MASK 0x7 +#define SDHCI_18V_SIGNAL 0x8 +#define SDHCI_CTRL_EXEC_TUNING 0x0040 +#define SDHCI_CTRL_TUNED_CLK 0x80 +#define SDHCI_TUNING_LOOP_COUNT 40
+static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid) +{
- u16 clk;
- unsigned long timeout;
- clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
- clk &= ~(SDHCI_CLOCK_CARD_EN);
- sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
- /* Issue DLL Reset */
- zynqmp_dll_reset(deviceid);
- /* Wait max 20 ms */
- timeout = 100;
- while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
dev_err(mmc_dev(host->mmc),
": Internal clock never stabilised.\n");
return;
}
timeout--;
udelay(1000);
- }
- clk |= SDHCI_CLOCK_CARD_EN;
- sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+}
+static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) +{
- struct mmc_cmd cmd;
- struct mmc_data data;
- u32 ctrl;
- struct sdhci_host *host;
- struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
- u8 tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
- u8 deviceid;
- debug("%s\n", __func__);
- host = priv->host;
- deviceid = priv->deviceid;
- ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
- ctrl |= SDHCI_CTRL_EXEC_TUNING;
- sdhci_writew(host, ctrl, SDHCI_HOST_CTRL2);
- mdelay(1);
- arasan_zynqmp_dll_reset(host, deviceid);
- sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
- sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
- do {
cmd.cmdidx = opcode;
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = 0;
data.blocksize = 64;
data.blocks = 1;
data.flags = MMC_DATA_READ;
if (tuning_loop_counter-- == 0)
break;
if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 &&
mmc->bus_width == 8)
data.blocksize = 128;
sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
data.blocksize),
SDHCI_BLOCK_SIZE);
sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT);
sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
mmc_send_cmd(mmc, &cmd, NULL);
ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
udelay(1);
- } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
- if (tuning_loop_counter < 0) {
ctrl &= ~SDHCI_CTRL_TUNED_CLK;
sdhci_writel(host, ctrl, SDHCI_HOST_CTRL2);
- }
- if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
printf("%s:Tuning failed\n", __func__);
return -1;
- }
- udelay(1);
- arasan_zynqmp_dll_reset(host, deviceid);
- /* Enable only interrupts served by the SD controller */
- sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
SDHCI_INT_ENABLE);
- /* Mask all sdhci interrupt sources */
- sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
- return 0;
+}
+static void arasan_sdhci_set_tapdelay(struct sdhci_host *host) +{
- struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
- struct mmc *mmc = (struct mmc *)host->mmc;
- u8 uhsmode;
- if (!IS_SD(mmc))
return;
- uhsmode = mode2timing[mmc->selected_mode];
- if (uhsmode >= UHS_SDR25_BUS_SPEED)
arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode,
priv->bank);
+}
+static void arasan_sdhci_set_control_reg(struct sdhci_host *host) +{
- struct mmc *mmc = (struct mmc *)host->mmc;
- u32 reg;
- if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
reg |= SDHCI_18V_SIGNAL;
sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
- }
- if (mmc->selected_mode > SD_HS &&
mmc->selected_mode <= UHS_DDR50) {
reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
reg &= ~SDHCI_CTRL2_MODE_MASK;
switch (mmc->selected_mode) {
case UHS_SDR12:
reg |= UHS_SDR12_BUS_SPEED;
break;
case UHS_SDR25:
reg |= UHS_SDR25_BUS_SPEED;
break;
case UHS_SDR50:
reg |= UHS_SDR50_BUS_SPEED;
break;
case UHS_SDR104:
reg |= UHS_SDR104_BUS_SPEED;
break;
case UHS_DDR50:
reg |= UHS_DDR50_BUS_SPEED;
break;
default:
break;
}
sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
- }
+} +#endif
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP) +const struct sdhci_ops arasan_ops = {
- .platform_execute_tuning = &arasan_sdhci_execute_tuning,
- .set_delay = &arasan_sdhci_set_tapdelay,
- .set_control_reg = &arasan_sdhci_set_control_reg,
+}; +#endif
static int arasan_sdhci_probe(struct udevice *dev) { struct arasan_sdhci_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
- struct sdhci_host *host = dev_get_priv(dev);
struct arasan_sdhci_priv *priv = dev_get_priv(dev);
struct sdhci_host *host; struct clk clk; unsigned long clock; int ret;
host = priv->host;
ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) { dev_err(dev, "failed to get clock\n"); @@ -42,6 +241,7 @@ static int arasan_sdhci_probe(struct udevice *dev) dev_err(dev, "failed to get rate\n"); return clock; }
debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk);
@@ -57,6 +257,9 @@ static int arasan_sdhci_probe(struct udevice *dev) host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; #endif
if (priv->no_1p8)
host->quirks |= SDHCI_QUIRK_NO_1_8_V;
host->max_clk = clock;
ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
@@ -74,10 +277,28 @@ static int arasan_sdhci_probe(struct udevice *dev) static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) { struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
- struct sdhci_host *host = dev_get_priv(dev);
- struct arasan_sdhci_priv *priv = dev_get_priv(dev);
- priv->host = calloc(1, sizeof(struct sdhci_host));
- if (!priv->host)
return -1;
- host->name = dev->name;
- host->ioaddr = (void *)devfdt_get_addr(dev);
- priv->host->name = dev->name;
- priv->host->ioaddr = (void *)devfdt_get_addr(dev);
- priv->deviceid = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"xlnx,device_id", -1);
- priv->bank = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"xlnx,mio_bank", -1);
- if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev),
"no-1-8-v", NULL))
priv->no_1p8 = 1;
- else
priv->no_1p8 = 0;
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP)
- priv->host->ops = &arasan_ops;
+#endif
plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ); @@ -105,6 +326,6 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = { .ops = &sdhci_ops, .bind = arasan_sdhci_bind, .probe = arasan_sdhci_probe,
- .priv_auto_alloc_size = sizeof(struct sdhci_host),
- .priv_auto_alloc_size = sizeof(struct arasan_sdhci_priv), .platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat),
}; diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h new file mode 100644 index 0000000..63be099 --- /dev/null +++ b/include/zynqmp_tap_delay.h @@ -0,0 +1,20 @@ +// 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
I am not quite sure if no-1-8-v is related to tap delay programming but this is the code we have in Xilinx tree for a while already.
Acked-by: Michal Simek michal.simek@xilinx.com
Thanks, Michal

This patch enables UHS support for ZynqMP zcu102 rev 1.0 board.
Signed-off-by: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com --- configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index 68da9dc..aa2bddd 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -64,6 +64,8 @@ CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_MACRONIX=y -- 2.7.4
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch enables UHS support for ZynqMP zcu102 rev 1.0 board.
Signed-off-by: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index 68da9dc..aa2bddd 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -64,6 +64,8 @@ CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_MACRONIX=y
Acked-by: Michal Simek michal.simek@xilinx.com
Thanks, Michal

Hi Jaehoon,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
Can you please comment this series?
Thanks, Michal

Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Thanks, Michal

On Mon, Apr 30, 2018 at 11:02:24AM +0200, Michal Simek wrote:
Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Are these things that need to come in for v2018.05 to fix regressions or new support? Thanks!

Dne po, 30. dub 2018 16:22 uživatel Tom Rini trini@konsulko.com napsal:
On Mon, Apr 30, 2018 at 11:02:24AM +0200, Michal Simek wrote:
Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229
+++++++++++++++++++++++++
configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231
+++++++++++++++++++++++++-
include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Are these things that need to come in for v2018.05 to fix regressions or new support? Thanks!
New support.
Thanks, Michal

On Mon, Apr 30, 2018 at 04:46:13PM +0000, Michal Simek wrote:
Dne po, 30. dub 2018 16:22 uživatel Tom Rini trini@konsulko.com napsal:
On Mon, Apr 30, 2018 at 11:02:24AM +0200, Michal Simek wrote:
Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229
+++++++++++++++++++++++++
configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231
+++++++++++++++++++++++++-
include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Are these things that need to come in for v2018.05 to fix regressions or new support? Thanks!
New support.
Then yes, assuming Jaehoon doesn't pick it up shortly after v2018.05 feel free to grab it for one of your trees, thanks!

On 04/30/2018 06:02 PM, Michal Simek wrote:
Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Sorry. First, I checked the patches that delegate to me on patchwork. So I missed this patchset. I will check this on Today.
Best Regards, Jaehoon Chung
Thanks, Michal

Hi Jaehoon,
On 2.5.2018 04:05, Jaehoon Chung wrote:
On 04/30/2018 06:02 PM, Michal Simek wrote:
Hi Tom,
On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
It looks like that Jaehoon is out or busy with something else. Can you please recommend someone to take a look at these patches? Definitely feel free to look at it self.
Sorry. First, I checked the patches that delegate to me on patchwork. So I missed this patchset. I will check this on Today.
It looks like that Today wasn't really Today. Anyway giving you one more day and then will apply it via my tree.
Thanks, Michal

On 19.4.2018 09:07, Siva Durga Prasad Paladugu wrote:
This patch series is meant to add SD3.0 support for ZynqMP platform. The first five patches in the series mostly setting up things in sdhci layer to support SD3.0 , the sixth patch is to add SD3.0 support for ZynqMP platform and the last patch is to enable this support for ZynqMP zcu102 rev1.0 eval board.
Siva Durga Prasad Paladugu (7): mmc: sdhci: Add support for disabling clock mmc: sdhci: Handle execute tuning command in sdhci_send_command sdhci: Add new sdhci ops for platform specific tuning and delays mmc: sdhci: Invoke platform specific tuning and delay routines mmc : sdhci: Read capabilities register1 and update host caps mmc: zynq_sdhci: Add support for SD3.0 zynqmp: zcu102: Enable UHS support for ZCU102 Rev1.0 board
board/xilinx/zynqmp/Makefile | 2 + board/xilinx/zynqmp/tap_delays.c | 229 +++++++++++++++++++++++++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 + drivers/mmc/sdhci.c | 63 ++++++- drivers/mmc/zynq_sdhci.c | 231 +++++++++++++++++++++++++- include/sdhci.h | 8 + include/zynqmp_tap_delay.h | 20 +++ 7 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 board/xilinx/zynqmp/tap_delays.c create mode 100644 include/zynqmp_tap_delay.h
Applied to xilinx tree.
Thanks, Michal
participants (5)
-
Jaehoon Chung
-
Michal Simek
-
Michal Simek
-
Siva Durga Prasad Paladugu
-
Tom Rini