I created a patch because of this issue today.
Code: Select all
diff -rupN a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
--- a/drivers/mmc/host/Kconfig 2019-10-04 12:40:23.732729225 +0200
+++ b/drivers/mmc/host/Kconfig 2019-10-04 12:40:46.476869118 +0200
@@ -94,7 +94,6 @@ config MMC_SDHCI_PCI
depends on MMC_SDHCI && PCI
select MMC_CQHCI
select IOSF_MBI if X86
- select MMC_SDHCI_IO_ACCESSORS
help
This selects the PCI Secure Digital Host Controller Interface.
Most controllers found today are PCI devices.
diff -rupN a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
--- a/drivers/mmc/host/Makefile 2019-10-04 12:40:23.732729225 +0200
+++ b/drivers/mmc/host/Makefile 2019-10-04 12:40:46.476869118 +0200
@@ -13,7 +13,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o \
- sdhci-pci-dwc-mshc.o sdhci-pci-gli.o
+ sdhci-pci-dwc-mshc.o
obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o
obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
diff -rupN a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
--- a/drivers/mmc/host/sdhci.c 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci.c 2019-10-04 12:40:46.476869118 +0200
@@ -2874,7 +2874,6 @@ static void sdhci_cmd_irq(struct sdhci_h
static void sdhci_adma_show_error(struct sdhci_host *host)
{
void *desc = host->adma_table;
- dma_addr_t dma = host->adma_addr;
sdhci_dumpregs(host);
@@ -2882,21 +2881,18 @@ static void sdhci_adma_show_error(struct
struct sdhci_adma2_64_desc *dma_desc = desc;
if (host->flags & SDHCI_USE_64_BIT_DMA)
- SDHCI_DUMP("%08llx: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n",
- (unsigned long long)dma,
- le32_to_cpu(dma_desc->addr_hi),
+ DBG("%p: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n",
+ desc, le32_to_cpu(dma_desc->addr_hi),
le32_to_cpu(dma_desc->addr_lo),
le16_to_cpu(dma_desc->len),
le16_to_cpu(dma_desc->cmd));
else
- SDHCI_DUMP("%08llx: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
- (unsigned long long)dma,
- le32_to_cpu(dma_desc->addr_lo),
+ DBG("%p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
+ desc, le32_to_cpu(dma_desc->addr_lo),
le16_to_cpu(dma_desc->len),
le16_to_cpu(dma_desc->cmd));
desc += host->desc_sz;
- dma += host->desc_sz;
if (dma_desc->cmd & cpu_to_le16(ADMA2_END))
break;
@@ -2972,8 +2968,7 @@ static void sdhci_data_irq(struct sdhci_
!= MMC_BUS_TEST_R)
host->data->error = -EILSEQ;
else if (intmask & SDHCI_INT_ADMA_ERROR) {
- pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
- intmask);
+ pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
sdhci_adma_show_error(host);
host->data->error = -EIO;
if (host->ops->adma_workaround)
@@ -3781,14 +3776,18 @@ int sdhci_setup_host(struct sdhci_host *
host->flags &= ~SDHCI_USE_ADMA;
}
+ /*
+ * It is assumed that a 64-bit capable device has set a 64-bit DMA mask
+ * and *must* do 64-bit DMA. A driver has the opportunity to change
+ * that during the first call to ->enable_dma(). Similarly
+ * SDHCI_QUIRK2_BROKEN_64_BIT_DMA must be left to the drivers to
+ * implement.
+ */
if (sdhci_can_64bit_dma(host))
host->flags |= SDHCI_USE_64_BIT_DMA;
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
- if (host->ops->set_dma_mask)
- ret = host->ops->set_dma_mask(host);
- else
- ret = sdhci_set_dma_mask(host);
+ ret = sdhci_set_dma_mask(host);
if (!ret && host->ops->enable_dma)
ret = host->ops->enable_dma(host);
diff -rupN a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
--- a/drivers/mmc/host/sdhci.h 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci.h 2019-10-04 12:40:46.476869118 +0200
@@ -622,7 +622,6 @@ struct sdhci_ops {
u32 (*irq)(struct sdhci_host *host, u32 intmask);
- int (*set_dma_mask)(struct sdhci_host *host);
int (*enable_dma)(struct sdhci_host *host);
unsigned int (*get_max_clock)(struct sdhci_host *host);
unsigned int (*get_min_clock)(struct sdhci_host *host);
diff -rupN a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
--- a/drivers/mmc/host/sdhci-of-esdhc.c 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci-of-esdhc.c 2019-10-04 12:40:46.476869118 +0200
@@ -495,12 +495,7 @@ static int esdhc_of_enable_dma(struct sd
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
value = sdhci_readl(host, ESDHC_DMA_SYSCTL);
-
- if (of_dma_is_coherent(dev->of_node))
- value |= ESDHC_DMA_SNOOP;
- else
- value &= ~ESDHC_DMA_SNOOP;
-
+ value |= ESDHC_DMA_SNOOP;
sdhci_writel(host, value, ESDHC_DMA_SYSCTL);
return 0;
}
diff -rupN a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
--- a/drivers/mmc/host/sdhci-pci-core.c 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci-pci-core.c 2019-10-04 12:40:46.476869118 +0200
@@ -1685,8 +1685,6 @@ static const struct pci_device_id pci_id
SDHCI_PCI_DEVICE(O2, SEABIRD1, o2),
SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan),
SDHCI_PCI_DEVICE(SYNOPSYS, DWC_MSHC, snps),
- SDHCI_PCI_DEVICE(GLI, 9750, gl9750),
- SDHCI_PCI_DEVICE(GLI, 9755, gl9755),
SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd),
/* Generic SD host controller */
{PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)},
diff -rupN a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
--- a/drivers/mmc/host/sdhci-pci-gli.c 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci-pci-gli.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,352 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2019 Genesys Logic, Inc.
- *
- * Authors: Ben Chuang <ben.chuang@genesyslogic.com.tw>
- *
- * Version: v0.9.0 (2019-08-08)
- */
-
-#include <linux/bitfield.h>
-#include <linux/bits.h>
-#include <linux/pci.h>
-#include <linux/mmc/mmc.h>
-#include <linux/delay.h>
-#include "sdhci.h"
-#include "sdhci-pci.h"
-
-/* Genesys Logic extra registers */
-#define SDHCI_GLI_9750_WT 0x800
-#define SDHCI_GLI_9750_WT_EN BIT(0)
-#define GLI_9750_WT_EN_ON 0x1
-#define GLI_9750_WT_EN_OFF 0x0
-
-#define SDHCI_GLI_9750_DRIVING 0x860
-#define SDHCI_GLI_9750_DRIVING_1 GENMASK(11, 0)
-#define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26)
-#define GLI_9750_DRIVING_1_VALUE 0xFFF
-#define GLI_9750_DRIVING_2_VALUE 0x3
-
-#define SDHCI_GLI_9750_PLL 0x864
-#define SDHCI_GLI_9750_PLL_TX2_INV BIT(23)
-#define SDHCI_GLI_9750_PLL_TX2_DLY GENMASK(22, 20)
-#define GLI_9750_PLL_TX2_INV_VALUE 0x1
-#define GLI_9750_PLL_TX2_DLY_VALUE 0x0
-
-#define SDHCI_GLI_9750_SW_CTRL 0x874
-#define SDHCI_GLI_9750_SW_CTRL_4 GENMASK(7, 6)
-#define GLI_9750_SW_CTRL_4_VALUE 0x3
-
-#define SDHCI_GLI_9750_MISC 0x878
-#define SDHCI_GLI_9750_MISC_TX1_INV BIT(2)
-#define SDHCI_GLI_9750_MISC_RX_INV BIT(3)
-#define SDHCI_GLI_9750_MISC_TX1_DLY GENMASK(6, 4)
-#define GLI_9750_MISC_TX1_INV_VALUE 0x0
-#define GLI_9750_MISC_RX_INV_ON 0x1
-#define GLI_9750_MISC_RX_INV_OFF 0x0
-#define GLI_9750_MISC_RX_INV_VALUE GLI_9750_MISC_RX_INV_OFF
-#define GLI_9750_MISC_TX1_DLY_VALUE 0x5
-
-#define SDHCI_GLI_9750_TUNING_CONTROL 0x540
-#define SDHCI_GLI_9750_TUNING_CONTROL_EN BIT(4)
-#define GLI_9750_TUNING_CONTROL_EN_ON 0x1
-#define GLI_9750_TUNING_CONTROL_EN_OFF 0x0
-#define SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1 BIT(16)
-#define SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2 GENMASK(20, 19)
-#define GLI_9750_TUNING_CONTROL_GLITCH_1_VALUE 0x1
-#define GLI_9750_TUNING_CONTROL_GLITCH_2_VALUE 0x2
-
-#define SDHCI_GLI_9750_TUNING_PARAMETERS 0x544
-#define SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY GENMASK(2, 0)
-#define GLI_9750_TUNING_PARAMETERS_RX_DLY_VALUE 0x1
-
-#define GLI_MAX_TUNING_LOOP 40
-
-/* Genesys Logic chipset */
-static inline void gl9750_wt_on(struct sdhci_host *host)
-{
- u32 wt_value;
- u32 wt_enable;
-
- wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT);
- wt_enable = FIELD_GET(SDHCI_GLI_9750_WT_EN, wt_value);
-
- if (wt_enable == GLI_9750_WT_EN_ON)
- return;
-
- wt_value &= ~SDHCI_GLI_9750_WT_EN;
- wt_value |= FIELD_PREP(SDHCI_GLI_9750_WT_EN, GLI_9750_WT_EN_ON);
-
- sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT);
-}
-
-static inline void gl9750_wt_off(struct sdhci_host *host)
-{
- u32 wt_value;
- u32 wt_enable;
-
- wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT);
- wt_enable = FIELD_GET(SDHCI_GLI_9750_WT_EN, wt_value);
-
- if (wt_enable == GLI_9750_WT_EN_OFF)
- return;
-
- wt_value &= ~SDHCI_GLI_9750_WT_EN;
- wt_value |= FIELD_PREP(SDHCI_GLI_9750_WT_EN, GLI_9750_WT_EN_OFF);
-
- sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT);
-}
-
-static void gli_set_9750(struct sdhci_host *host)
-{
- u32 driving_value;
- u32 pll_value;
- u32 sw_ctrl_value;
- u32 misc_value;
- u32 parameter_value;
- u32 control_value;
- u16 ctrl2;
-
- gl9750_wt_on(host);
-
- driving_value = sdhci_readl(host, SDHCI_GLI_9750_DRIVING);
- pll_value = sdhci_readl(host, SDHCI_GLI_9750_PLL);
- sw_ctrl_value = sdhci_readl(host, SDHCI_GLI_9750_SW_CTRL);
- misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC);
- parameter_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_PARAMETERS);
- control_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_CONTROL);
-
- driving_value &= ~(SDHCI_GLI_9750_DRIVING_1);
- driving_value &= ~(SDHCI_GLI_9750_DRIVING_2);
- driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_1,
- GLI_9750_DRIVING_1_VALUE);
- driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2,
- GLI_9750_DRIVING_2_VALUE);
- sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING);
-
- sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4;
- sw_ctrl_value |= FIELD_PREP(SDHCI_GLI_9750_SW_CTRL_4,
- GLI_9750_SW_CTRL_4_VALUE);
- sdhci_writel(host, sw_ctrl_value, SDHCI_GLI_9750_SW_CTRL);
-
- /* reset the tuning flow after reinit and before starting tuning */
- pll_value &= ~SDHCI_GLI_9750_PLL_TX2_INV;
- pll_value &= ~SDHCI_GLI_9750_PLL_TX2_DLY;
- pll_value |= FIELD_PREP(SDHCI_GLI_9750_PLL_TX2_INV,
- GLI_9750_PLL_TX2_INV_VALUE);
- pll_value |= FIELD_PREP(SDHCI_GLI_9750_PLL_TX2_DLY,
- GLI_9750_PLL_TX2_DLY_VALUE);
-
- misc_value &= ~SDHCI_GLI_9750_MISC_TX1_INV;
- misc_value &= ~SDHCI_GLI_9750_MISC_RX_INV;
- misc_value &= ~SDHCI_GLI_9750_MISC_TX1_DLY;
- misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_TX1_INV,
- GLI_9750_MISC_TX1_INV_VALUE);
- misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
- GLI_9750_MISC_RX_INV_VALUE);
- misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_TX1_DLY,
- GLI_9750_MISC_TX1_DLY_VALUE);
-
- parameter_value &= ~SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY;
- parameter_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY,
- GLI_9750_TUNING_PARAMETERS_RX_DLY_VALUE);
-
- control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1;
- control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2;
- control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1,
- GLI_9750_TUNING_CONTROL_GLITCH_1_VALUE);
- control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2,
- GLI_9750_TUNING_CONTROL_GLITCH_2_VALUE);
-
- sdhci_writel(host, pll_value, SDHCI_GLI_9750_PLL);
- sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC);
-
- /* disable tuned clk */
- ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
- sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
-
- /* enable tuning parameters control */
- control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_EN;
- control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_EN,
- GLI_9750_TUNING_CONTROL_EN_ON);
- sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL);
-
- /* write tuning parameters */
- sdhci_writel(host, parameter_value, SDHCI_GLI_9750_TUNING_PARAMETERS);
-
- /* disable tuning parameters control */
- control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_EN;
- control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_EN,
- GLI_9750_TUNING_CONTROL_EN_OFF);
- sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL);
-
- /* clear tuned clk */
- ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
- sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
-
- gl9750_wt_off(host);
-}
-
-static void gli_set_9750_rx_inv(struct sdhci_host *host, bool b)
-{
- u32 misc_value;
-
- gl9750_wt_on(host);
-
- misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC);
- misc_value &= ~SDHCI_GLI_9750_MISC_RX_INV;
- if (b) {
- misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
- GLI_9750_MISC_RX_INV_ON);
- } else {
- misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
- GLI_9750_MISC_RX_INV_OFF);
- }
- sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC);
-
- gl9750_wt_off(host);
-}
-
-static int __sdhci_execute_tuning_9750(struct sdhci_host *host, u32 opcode)
-{
- int i;
- int rx_inv;
-
- for (rx_inv = 0; rx_inv < 2; rx_inv++) {
- gli_set_9750_rx_inv(host, !!rx_inv);
- sdhci_start_tuning(host);
-
- for (i = 0; i < GLI_MAX_TUNING_LOOP; i++) {
- u16 ctrl;
-
- sdhci_send_tuning(host, opcode);
-
- if (!host->tuning_done) {
- sdhci_abort_tuning(host, opcode);
- break;
- }
-
- ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
- if (ctrl & SDHCI_CTRL_TUNED_CLK)
- return 0; /* Success! */
- break;
- }
- }
- }
- if (!host->tuning_done) {
- pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
- mmc_hostname(host->mmc));
- return -ETIMEDOUT;
- }
-
- pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
- mmc_hostname(host->mmc));
- sdhci_reset_tuning(host);
-
- return -EAGAIN;
-}
-
-static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode)
-{
- host->mmc->retune_period = 0;
- if (host->tuning_mode == SDHCI_TUNING_MODE_1)
- host->mmc->retune_period = host->tuning_count;
-
- gli_set_9750(host);
- host->tuning_err = __sdhci_execute_tuning_9750(host, opcode);
- sdhci_end_tuning(host);
-
- return 0;
-}
-
-static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot)
-{
- struct sdhci_host *host = slot->host;
-
- slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
- sdhci_enable_v4_mode(host);
-
- return 0;
-}
-
-static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot)
-{
- struct sdhci_host *host = slot->host;
-
- slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
- sdhci_enable_v4_mode(host);
-
- return 0;
-}
-
-static void sdhci_gli_voltage_switch(struct sdhci_host *host)
-{
- /*
- * According to Section 3.6.1 signal voltage switch procedure in
- * SD Host Controller Simplified Spec. 4.20, steps 6~8 are as
- * follows:
- * (6) Set 1.8V Signal Enable in the Host Control 2 register.
- * (7) Wait 5ms. 1.8V voltage regulator shall be stable within this
- * period.
- * (8) If 1.8V Signal Enable is cleared by Host Controller, go to
- * step (12).
- *
- * Wait 5ms after set 1.8V signal enable in Host Control 2 register
- * to ensure 1.8V signal enable bit is set by GL9750/GL9755.
- */
- usleep_range(5000, 5500);
-}
-
-static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask)
-{
- sdhci_reset(host, mask);
- gli_set_9750(host);
-}
-
-static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg)
-{
- u32 value;
-
- value = readl(host->ioaddr + reg);
- if (unlikely(reg == SDHCI_MAX_CURRENT && !(value & 0xff)))
- value |= 0xc8;
-
- return value;
-}
-
-static const struct sdhci_ops sdhci_gl9755_ops = {
- .set_clock = sdhci_set_clock,
- .enable_dma = sdhci_pci_enable_dma,
- .set_bus_width = sdhci_set_bus_width,
- .reset = sdhci_reset,
- .set_uhs_signaling = sdhci_set_uhs_signaling,
- .voltage_switch = sdhci_gli_voltage_switch,
-};
-
-const struct sdhci_pci_fixes sdhci_gl9755 = {
- .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
- .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
- .probe_slot = gli_probe_slot_gl9755,
- .ops = &sdhci_gl9755_ops,
-};
-
-static const struct sdhci_ops sdhci_gl9750_ops = {
- .read_l = sdhci_gl9750_readl,
- .set_clock = sdhci_set_clock,
- .enable_dma = sdhci_pci_enable_dma,
- .set_bus_width = sdhci_set_bus_width,
- .reset = sdhci_gl9750_reset,
- .set_uhs_signaling = sdhci_set_uhs_signaling,
- .voltage_switch = sdhci_gli_voltage_switch,
- .platform_execute_tuning = gl9750_execute_tuning,
-};
-
-const struct sdhci_pci_fixes sdhci_gl9750 = {
- .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
- .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
- .probe_slot = gli_probe_slot_gl9750,
- .ops = &sdhci_gl9750_ops,
-};
diff -rupN a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
--- a/drivers/mmc/host/sdhci-pci.h 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci-pci.h 2019-10-04 12:40:46.476869118 +0200
@@ -68,9 +68,6 @@
#define PCI_DEVICE_ID_SYNOPSYS_DWC_MSHC 0xc202
-#define PCI_DEVICE_ID_GLI_9755 0x9755
-#define PCI_DEVICE_ID_GLI_9750 0x9750
-
/*
* PCI device class and mask
*/
@@ -191,7 +188,5 @@ int sdhci_pci_enable_dma(struct sdhci_ho
extern const struct sdhci_pci_fixes sdhci_arasan;
extern const struct sdhci_pci_fixes sdhci_snps;
extern const struct sdhci_pci_fixes sdhci_o2;
-extern const struct sdhci_pci_fixes sdhci_gl9750;
-extern const struct sdhci_pci_fixes sdhci_gl9755;
#endif /* __SDHCI_PCI_H */
diff -rupN a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
--- a/drivers/mmc/host/sdhci-tegra.c 2019-10-04 12:40:23.736729250 +0200
+++ b/drivers/mmc/host/sdhci-tegra.c 2019-10-04 12:40:46.476869118 +0200
@@ -4,7 +4,6 @@
*/
#include <linux/delay.h>
-#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -105,7 +104,6 @@
struct sdhci_tegra_soc_data {
const struct sdhci_pltfm_data *pdata;
- u64 dma_mask;
u32 nvquirks;
u8 min_tap_delay;
u8 max_tap_delay;
@@ -1235,25 +1233,11 @@ static const struct cqhci_host_ops sdhci
.update_dcmd_desc = sdhci_tegra_update_dcmd_desc,
};
-static int tegra_sdhci_set_dma_mask(struct sdhci_host *host)
-{
- struct sdhci_pltfm_host *platform = sdhci_priv(host);
- struct sdhci_tegra *tegra = sdhci_pltfm_priv(platform);
- const struct sdhci_tegra_soc_data *soc = tegra->soc_data;
- struct device *dev = mmc_dev(host->mmc);
-
- if (soc->dma_mask)
- return dma_set_mask_and_coherent(dev, soc->dma_mask);
-
- return 0;
-}
-
static const struct sdhci_ops tegra_sdhci_ops = {
.get_ro = tegra_sdhci_get_ro,
.read_w = tegra_sdhci_readw,
.write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock,
- .set_dma_mask = tegra_sdhci_set_dma_mask,
.set_bus_width = sdhci_set_bus_width,
.reset = tegra_sdhci_reset,
.platform_execute_tuning = tegra_sdhci_execute_tuning,
@@ -1273,7 +1257,6 @@ static const struct sdhci_pltfm_data sdh
static const struct sdhci_tegra_soc_data soc_data_tegra20 = {
.pdata = &sdhci_tegra20_pdata,
- .dma_mask = DMA_BIT_MASK(32),
.nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 |
NVQUIRK_ENABLE_BLOCK_GAP_DET,
};
@@ -1300,7 +1283,6 @@ static const struct sdhci_pltfm_data sdh
static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
.pdata = &sdhci_tegra30_pdata,
- .dma_mask = DMA_BIT_MASK(32),
.nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 |
NVQUIRK_ENABLE_SDR50 |
NVQUIRK_ENABLE_SDR104 |
@@ -1313,7 +1295,6 @@ static const struct sdhci_ops tegra114_s
.write_w = tegra_sdhci_writew,
.write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock,
- .set_dma_mask = tegra_sdhci_set_dma_mask,
.set_bus_width = sdhci_set_bus_width,
.reset = tegra_sdhci_reset,
.platform_execute_tuning = tegra_sdhci_execute_tuning,
@@ -1335,7 +1316,6 @@ static const struct sdhci_pltfm_data sdh
static const struct sdhci_tegra_soc_data soc_data_tegra114 = {
.pdata = &sdhci_tegra114_pdata,
- .dma_mask = DMA_BIT_MASK(32),
};
static const struct sdhci_pltfm_data sdhci_tegra124_pdata = {
@@ -1345,13 +1325,22 @@ static const struct sdhci_pltfm_data sdh
SDHCI_QUIRK_NO_HISPD_BIT |
SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
- .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+ /*
+ * The TRM states that the SD/MMC controller found on
+ * Tegra124 can address 34 bits (the maximum supported by
+ * the Tegra memory controller), but tests show that DMA
+ * to or from above 4 GiB doesn't work. This is possibly
+ * caused by missing programming, though it's not obvious
+ * what sequence is required. Mark 64-bit DMA broken for
+ * now to fix this for existing users (e.g. Nyan boards).
+ */
+ SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
.ops = &tegra114_sdhci_ops,
};
static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
.pdata = &sdhci_tegra124_pdata,
- .dma_mask = DMA_BIT_MASK(34),
};
static const struct sdhci_ops tegra210_sdhci_ops = {
@@ -1360,7 +1349,6 @@ static const struct sdhci_ops tegra210_s
.write_w = tegra210_sdhci_writew,
.write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock,
- .set_dma_mask = tegra_sdhci_set_dma_mask,
.set_bus_width = sdhci_set_bus_width,
.reset = tegra_sdhci_reset,
.set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
@@ -1381,7 +1369,6 @@ static const struct sdhci_pltfm_data sdh
static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
.pdata = &sdhci_tegra210_pdata,
- .dma_mask = DMA_BIT_MASK(34),
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
NVQUIRK_HAS_PADCALIB |
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
@@ -1396,7 +1383,6 @@ static const struct sdhci_ops tegra186_s
.read_w = tegra_sdhci_readw,
.write_l = tegra_sdhci_writel,
.set_clock = tegra_sdhci_set_clock,
- .set_dma_mask = tegra_sdhci_set_dma_mask,
.set_bus_width = sdhci_set_bus_width,
.reset = tegra_sdhci_reset,
.set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
@@ -1412,13 +1398,20 @@ static const struct sdhci_pltfm_data sdh
SDHCI_QUIRK_NO_HISPD_BIT |
SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
- .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+ /* SDHCI controllers on Tegra186 support 40-bit addressing.
+ * IOVA addresses are 48-bit wide on Tegra186.
+ * With 64-bit dma mask used for SDHCI, accesses can
+ * be broken. Disable 64-bit dma, which would fall back
+ * to 32-bit dma mask. Ideally 40-bit dma mask would work,
+ * But it is not supported as of now.
+ */
+ SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
.ops = &tegra186_sdhci_ops,
};
static const struct sdhci_tegra_soc_data soc_data_tegra186 = {
.pdata = &sdhci_tegra186_pdata,
- .dma_mask = DMA_BIT_MASK(40),
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
NVQUIRK_HAS_PADCALIB |
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
@@ -1431,7 +1424,6 @@ static const struct sdhci_tegra_soc_data
static const struct sdhci_tegra_soc_data soc_data_tegra194 = {
.pdata = &sdhci_tegra186_pdata,
- .dma_mask = DMA_BIT_MASK(39),
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
NVQUIRK_HAS_PADCALIB |
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
After that I patched the RC1 and compiled a new kernel.
Please test it.