diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0853-AMD-eMMC-5.0-support.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0853-AMD-eMMC-5.0-support.patch | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0853-AMD-eMMC-5.0-support.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0853-AMD-eMMC-5.0-support.patch new file mode 100644 index 00000000..a11eeb1a --- /dev/null +++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0853-AMD-eMMC-5.0-support.patch @@ -0,0 +1,270 @@ +From 78fc88276c47e54dd7378827f404b2abcd4e009d Mon Sep 17 00:00:00 2001 +From: Sudheesh Mavila <sudheesh.mavila@amd.com> +Date: Wed, 31 Jan 2018 16:01:25 +0530 +Subject: [PATCH 0853/4131] AMD eMMC 5.0 support + +Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> +--- + drivers/acpi/resource.c | 5 +++ + drivers/mmc/core/mmc.c | 6 +-- + drivers/mmc/host/sdhci-acpi.c | 87 +++++++++++++++++++++++++++++++++++++++++++ + drivers/mmc/host/sdhci.c | 3 +- + drivers/mmc/host/sdhci.h | 5 +++ + include/linux/mmc/host.h | 6 +++ + 6 files changed, 108 insertions(+), 4 deletions(-) + mode change 100644 => 100755 drivers/acpi/resource.c + mode change 100644 => 100755 drivers/mmc/core/mmc.c + mode change 100644 => 100755 drivers/mmc/host/sdhci-acpi.c + mode change 100644 => 100755 drivers/mmc/host/sdhci.c + mode change 100644 => 100755 drivers/mmc/host/sdhci.h + mode change 100644 => 100755 include/linux/mmc/host.h + +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +old mode 100644 +new mode 100755 +index d85e010..e82b5a7 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -425,6 +425,11 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, + triggering = trig; + polarity = pol; + } ++ if (gsi == 5) { ++ polarity = ACPI_ACTIVE_LOW; ++ pr_warning("ACPI: IRQ %d do not override to %s, %s\n", gsi, ++ t ? "level" : "edge", p ? "low" : "high"); ++ } + } + + res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +old mode 100644 +new mode 100755 +index bad5c1b..7ba25a2 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1164,7 +1164,7 @@ static int mmc_select_hs400(struct mmc_card *card) + + /* Set host controller to HS timing */ + mmc_set_timing(card->host, MMC_TIMING_MMC_HS); +- ++ host->ios.transition = HS200_TO_HS_TO_HS400; + /* Reduce frequency to HS frequency */ + max_dtr = card->ext_csd.hs_max_dtr; + mmc_set_clock(host, max_dtr); +@@ -1196,7 +1196,7 @@ static int mmc_select_hs400(struct mmc_card *card) + mmc_hostname(host), err); + return err; + } +- ++ host->ios.transition = SWITCHING_TO_HS400; + /* Set host controller to HS400 timing and frequency */ + mmc_set_timing(host, MMC_TIMING_MMC_HS400); + mmc_set_bus_speed(card); +@@ -1204,7 +1204,7 @@ static int mmc_select_hs400(struct mmc_card *card) + err = mmc_switch_status(card); + if (err) + goto out_err; +- ++ host->ios.transition = SWITCHED_TO_HS400; + return 0; + + out_err: +diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c +old mode 100644 +new mode 100755 +index 08ae0ff..aac8f1f +--- a/drivers/mmc/host/sdhci-acpi.c ++++ b/drivers/mmc/host/sdhci-acpi.c +@@ -89,6 +89,47 @@ static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) + return c->slot && (c->slot->flags & flag); + } + ++ /*AMD Driver Strength function*/ ++ ++static int amd_select_drive_strength(struct mmc_card *card, ++ unsigned int max_dtr, int host_drv, ++ int card_drv, int *drv_type) ++{ ++ return MMC_SET_DRIVER_TYPE_A; ++} ++ ++static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host) ++{ ++ /*AMD Platform requires dll setting*/ ++ sdhci_writel(host, 0x40003210, SDHCI_AMD_REST_DLL_REGISTER); ++ udelay(10); ++ sdhci_writel(host, 0x40033210, SDHCI_AMD_REST_DLL_REGISTER); ++} ++ ++/* ++ * For AMD Platform it is required to disable the tuning ++ * bit first controller to bring to HS Mode from HS200 ++ * mode, later enable to tune to HS400 mode. ++ */ ++ ++static void sdhci_amd_set_hs400_transition(struct sdhci_host *host) ++{ ++ switch (host->mmc->ios.transition) { ++ case HS200_TO_HS_TO_HS400: ++ sdhci_writew(host, 0x9, SDHCI_HOST_CONTROL2); ++ break; ++ ++ case SWITCHING_TO_HS400: ++ sdhci_writew(host, 0x80, SDHCI_HOST_CONTROL2); ++ sdhci_acpi_amd_hs400_dll(host); ++ break; ++ ++ case SWITCHED_TO_HS400: ++ default: ++ break; ++ } ++} ++ + static void sdhci_acpi_int_hw_reset(struct sdhci_host *host) + { + u8 reg; +@@ -123,6 +164,18 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { + .ops = &sdhci_acpi_ops_int, + }; + ++static const struct sdhci_ops sdhci_acpi_ops_amd = { ++ .set_clock = sdhci_set_clock, ++ .set_bus_width = sdhci_set_bus_width, ++ .reset = sdhci_reset, ++ .set_uhs_signaling = sdhci_set_uhs_signaling, ++ .set_platform_hs400_transition = sdhci_amd_set_hs400_transition, ++}; ++ ++static const struct sdhci_acpi_chip sdhci_acpi_chip_amd = { ++ .ops = &sdhci_acpi_ops_amd, ++}; ++ + #ifdef CONFIG_X86 + + static bool sdhci_acpi_byt(void) +@@ -269,6 +322,31 @@ static int bxt_get_cd(struct mmc_host *mmc) + return ret; + } + ++static int sdhci_acpi_emmc_amd_probe_slot(struct platform_device *pdev, ++ const char *hid, const char *uid) ++{ ++ struct sdhci_acpi_host *c = platform_get_drvdata(pdev); ++ struct sdhci_host *host; ++ unsigned int caps1, caps; ++ if (!c || !c->host) ++ return 0; ++ ++ host = c->host; ++ ++ caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ ++ if (caps1 & SDHCI_SUPPORT_DDR50) ++ host->mmc->caps = MMC_CAP_1_8V_DDR; ++ ++ if ((caps1 & SDHCI_SUPPORT_SDR104) && ++ (host->mmc->caps & MMC_CAP_1_8V_DDR)) ++ host->mmc->caps2 = MMC_CAP2_HS400_1_8V; ++ ++ host->mmc_host_ops.select_drive_strength = amd_select_drive_strength; ++ return 0; ++} ++ + static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev, + const char *hid, const char *uid) + { +@@ -367,6 +445,13 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_qcom_sd = { + .caps = MMC_CAP_NONREMOVABLE, + }; + ++static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = { ++ .chip = &sdhci_acpi_chip_amd, ++ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | MMC_CAP_HW_RESET, ++ .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | ++ SDHCI_QUIRK_32BIT_ADMA_SIZE, ++ .probe_slot = sdhci_acpi_emmc_amd_probe_slot, ++}; + struct sdhci_acpi_uid_slot { + const char *hid; + const char *uid; +@@ -390,6 +475,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { + { "PNP0D40" }, + { "QCOM8051", NULL, &sdhci_acpi_slot_qcom_sd_3v }, + { "QCOM8052", NULL, &sdhci_acpi_slot_qcom_sd }, ++ { "AMDI0040", NULL, &sdhci_acpi_slot_amd_emmc}, + { }, + }; + +@@ -406,6 +492,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { + { "PNP0D40" }, + { "QCOM8051" }, + { "QCOM8052" }, ++ { "AMDI0040" }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +old mode 100644 +new mode 100755 +index d35deb7..da341b0 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1687,7 +1687,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + host->ops->set_power(host, ios->power_mode, ios->vdd); + else + sdhci_set_power(host, ios->power_mode, ios->vdd); +- ++ if (host->ops->set_platform_hs400_transition) ++ host->ops->set_platform_hs400_transition(host); + if (host->ops->platform_send_init_74_clocks) + host->ops->platform_send_init_74_clocks(host, ios->power_mode); + +diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h +old mode 100644 +new mode 100755 +index 1d7d61e..c6569ba +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -271,6 +271,9 @@ + #define SDHCI_SPEC_200 1 + #define SDHCI_SPEC_300 2 + ++/* AMD sdhci reset dll register.*/ ++#define SDHCI_AMD_REST_DLL_REGISTER 0x908 ++ + /* + * End of controller registers. + */ +@@ -579,6 +582,8 @@ struct sdhci_ops { + void (*set_bus_width)(struct sdhci_host *host, int width); + void (*platform_send_init_74_clocks)(struct sdhci_host *host, + u8 power_mode); ++ /* ios for transiton phase for going to hs400 */ ++ void (*set_platform_hs400_transition)(struct sdhci_host *host); + unsigned int (*get_ro)(struct sdhci_host *host); + void (*reset)(struct sdhci_host *host, u8 mask); + int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode); +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +old mode 100644 +new mode 100755 +index 9a43763..ae16bc5 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -77,6 +77,12 @@ struct mmc_ios { + #define MMC_SET_DRIVER_TYPE_D 3 + + bool enhanced_strobe; /* hs400es selection */ ++ ++ unsigned int transition; /* track transition modes (hs200 hs400) */ ++ ++#define HS200_TO_HS_TO_HS400 1 ++#define SWITCHING_TO_HS400 2 ++#define SWITCHED_TO_HS400 3 + }; + + struct mmc_host; +-- +2.7.4 + |