2020-01-16 17:05:54

by Veerabhadrarao Badiganti

[permalink] [raw]
Subject: [PATCH V2 0/2] Add CQHCI support for sdhci-msm

Changes since V1: (https://lkml.org/lkml/2019/12/17/455)
- Select MMC_CQHCI in Kconfig
- Making use of host->alloc_desc_size variable for allocation
of ADMA table and host->desc_size for updating decriptor
size dynamically.

Changes since RFC (https://lkml.org/lkml/2017/8/30/313)
- Updated settings so that TDLBA won't get reset when
CQE is enabled.
- Removed new compatible string and moved to supports-cqe
dt flag to identify CQE support.
- Incorporated review comments.

Tested on: qcs404, sc7180

Ritesh Harjani (1):
mmc: sdhci-msm: Add CQHCI support for sdhci-msm

Veerabhadrarao Badiganti (1):
mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-msm.c | 133 ++++++++++++++++++++++++++++++++++++++++++-
drivers/mmc/host/sdhci.c | 7 ++-
drivers/mmc/host/sdhci.h | 1 +
4 files changed, 139 insertions(+), 3 deletions(-)

--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project


2020-01-16 17:06:24

by Veerabhadrarao Badiganti

[permalink] [raw]
Subject: [PATCH V2 1/2] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

Let a vendor driver supply the maximum descriptor size that it
can operate on. ADMA descriptor table would be allocated using this
supplied size.
If any SD Host controller is of version prior to v4.10 spec
but supports 16byte descriptor, this change allows them to supply
correct descriptor size for ADMA table allocation.

Also let a vendor driver update the descriptor size by overriding
sdhc_host->desc_size if it has to operates on a different descriptor
sizes in different conditions.

Suggested-by: Adrian Hunter <[email protected]>
Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
---
drivers/mmc/host/sdhci.c | 7 +++++--
drivers/mmc/host/sdhci.h | 1 +
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3140fe2..19a5ad3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3822,9 +3822,12 @@ int sdhci_setup_host(struct sdhci_host *host)
void *buf;

if (host->flags & SDHCI_USE_64_BIT_DMA) {
+ if (!host->alloc_desc_sz)
+ host->alloc_desc_sz =
+ SDHCI_ADMA2_64_DESC_SZ(host);
+ host->desc_sz = host->alloc_desc_sz;
host->adma_table_sz = host->adma_table_cnt *
- SDHCI_ADMA2_64_DESC_SZ(host);
- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
+ host->desc_sz;
} else {
host->adma_table_sz = host->adma_table_cnt *
SDHCI_ADMA2_32_DESC_SZ;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0ed3e0e..8e7c77d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -555,6 +555,7 @@ struct sdhci_host {
dma_addr_t align_addr; /* Mapped bounce buffer */

unsigned int desc_sz; /* ADMA descriptor size */
+ unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */

struct workqueue_struct *complete_wq; /* Request completion wq */
struct work_struct complete_work; /* Request completion work */
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-16 17:06:31

by Veerabhadrarao Badiganti

[permalink] [raw]
Subject: [PATCH V2 2/2] mmc: sdhci-msm: Add CQHCI support for sdhci-msm

From: Ritesh Harjani <[email protected]>

This adds CQHCI support for sdhci-msm platforms.

Signed-off-by: Ritesh Harjani <[email protected]>
Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
---
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-msm.c | 133 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index d06b2df..7f2ae59 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -501,6 +501,7 @@ config MMC_SDHCI_MSM
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
depends on MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
+ select MMC_CQHCI
help
This selects the Secure Digital Host Controller Interface (SDHCI)
support present in Qualcomm SOCs. The controller supports
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3d0bb5e..0b4d01f 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -15,6 +15,7 @@
#include <linux/regulator/consumer.h>

#include "sdhci-pltfm.h"
+#include "cqhci.h"

#define CORE_MCI_VERSION 0x50
#define CORE_VERSION_MAJOR_SHIFT 28
@@ -122,6 +123,10 @@
#define msm_host_writel(msm_host, val, host, offset) \
msm_host->var_ops->msm_writel_relaxed(val, host, offset)

+/* CQHCI vendor specific registers */
+#define CQHCI_VENDOR_CFG1 0xA00
+#define CQHCI_VENDOR_DIS_RST_ON_CQ_EN (0x3 << 13)
+
struct sdhci_msm_offset {
u32 core_hc_mode;
u32 core_mci_data_cnt;
@@ -1567,6 +1572,127 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
__sdhci_msm_set_clock(host, clock);
}

+/*****************************************************************************\
+ * *
+ * MSM Command Queue Engine (CQE) *
+ * *
+\*****************************************************************************/
+
+static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
+{
+ int cmd_error = 0;
+ int data_error = 0;
+
+ if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
+ return intmask;
+
+ cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ return 0;
+}
+
+void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+ u32 ctrl;
+
+ /*
+ * When CQE is halted, the legacy SDHCI path operates only
+ * on 16-byte descriptors in 64bit mode.
+ */
+ if (host->flags & SDHCI_USE_64_BIT_DMA)
+ host->desc_sz = 16;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ /*
+ * During CQE command transfers, command complete bit gets latched.
+ * So s/w should clear command complete interrupt status when CQE is
+ * either halted or disabled. Otherwise unexpected SDCHI legacy
+ * interrupt gets triggered when CQE is halted/disabled.
+ */
+ ctrl = sdhci_readl(host, SDHCI_INT_ENABLE);
+ ctrl |= SDHCI_INT_RESPONSE;
+ sdhci_writel(host, ctrl, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ sdhci_cqe_disable(mmc, recovery);
+}
+
+static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
+ .enable = sdhci_cqe_enable,
+ .disable = sdhci_msm_cqe_disable,
+};
+
+static int sdhci_msm_cqe_add_host(struct sdhci_host *host,
+ struct platform_device *pdev)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+ struct cqhci_host *cq_host;
+ bool dma64;
+ u32 cqcfg;
+ int ret;
+
+ /*
+ * When CQE is halted, SDHC operates only on 16byte ADMA descriptors.
+ * So ensure ADMA table is allocated for 16byte descriptors.
+ */
+ if (host->caps & SDHCI_CAN_64BIT)
+ host->alloc_desc_sz = 16;
+
+ ret = sdhci_setup_host(host);
+ if (ret)
+ return ret;
+
+ cq_host = cqhci_pltfm_init(pdev);
+ if (IS_ERR(cq_host)) {
+ ret = PTR_ERR(cq_host);
+ dev_err(&pdev->dev, "cqhci-pltfm init: failed: %d\n", ret);
+ goto cleanup;
+ }
+
+ msm_host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
+ cq_host->ops = &sdhci_msm_cqhci_ops;
+
+ dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
+
+ ret = cqhci_init(cq_host, host->mmc, dma64);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: CQE init: failed (%d)\n",
+ mmc_hostname(host->mmc), ret);
+ goto cleanup;
+ }
+
+ /* Disable cqe reset due to cqe enable signal */
+ cqcfg = cqhci_readl(cq_host, CQHCI_VENDOR_CFG1);
+ cqcfg |= CQHCI_VENDOR_DIS_RST_ON_CQ_EN;
+ cqhci_writel(cq_host, cqcfg, CQHCI_VENDOR_CFG1);
+
+ /*
+ * SDHC expects 12byte ADMA descriptors till CQE is enabled.
+ * So limit desc_sz to 12 so that the data commands that are sent
+ * during card initialization (before CQE gets enabled) would
+ * get executed without any issues.
+ */
+ if (host->flags & SDHCI_USE_64_BIT_DMA)
+ host->desc_sz = 12;
+
+ ret = __sdhci_add_host(host);
+ if (ret)
+ goto cleanup;
+
+ dev_info(&pdev->dev, "%s: CQE init: success\n",
+ mmc_hostname(host->mmc));
+ return ret;
+
+cleanup:
+ sdhci_cleanup_host(host);
+ return ret;
+}
+
/*
* Platform specific register write functions. This is so that, if any
* register write needs to be followed up by platform specific actions,
@@ -1731,6 +1857,7 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
.set_uhs_signaling = sdhci_msm_set_uhs_signaling,
.write_w = sdhci_msm_writew,
.write_b = sdhci_msm_writeb,
+ .irq = sdhci_msm_cqe_irq,
};

static const struct sdhci_pltfm_data sdhci_msm_pdata = {
@@ -1754,6 +1881,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
u8 core_major;
const struct sdhci_msm_offset *msm_offset;
const struct sdhci_msm_variant_info *var_info;
+ struct device_node *node = pdev->dev.of_node;

host = sdhci_pltfm_init(pdev, &sdhci_msm_pdata, sizeof(*msm_host));
if (IS_ERR(host))
@@ -1952,7 +2080,10 @@ static int sdhci_msm_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(&pdev->dev);

host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;
- ret = sdhci_add_host(host);
+ if (of_property_read_bool(node, "supports-cqe"))
+ ret = sdhci_msm_cqe_add_host(host, pdev);
+ else
+ ret = sdhci_add_host(host);
if (ret)
goto pm_runtime_disable;
sdhci_msm_set_regulator_caps(msm_host);
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-20 09:00:55

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH V2 2/2] mmc: sdhci-msm: Add CQHCI support for sdhci-msm

On 16/01/20 7:03 pm, Veerabhadrarao Badiganti wrote:
> From: Ritesh Harjani <[email protected]>
>
> This adds CQHCI support for sdhci-msm platforms.
>
> Signed-off-by: Ritesh Harjani <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>

Acked-by: Adrian Hunter <[email protected]>

> ---
> drivers/mmc/host/Kconfig | 1 +
> drivers/mmc/host/sdhci-msm.c | 133 ++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 133 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index d06b2df..7f2ae59 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -501,6 +501,7 @@ config MMC_SDHCI_MSM
> depends on ARCH_QCOM || (ARM && COMPILE_TEST)
> depends on MMC_SDHCI_PLTFM
> select MMC_SDHCI_IO_ACCESSORS
> + select MMC_CQHCI
> help
> This selects the Secure Digital Host Controller Interface (SDHCI)
> support present in Qualcomm SOCs. The controller supports
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 3d0bb5e..0b4d01f 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -15,6 +15,7 @@
> #include <linux/regulator/consumer.h>
>
> #include "sdhci-pltfm.h"
> +#include "cqhci.h"
>
> #define CORE_MCI_VERSION 0x50
> #define CORE_VERSION_MAJOR_SHIFT 28
> @@ -122,6 +123,10 @@
> #define msm_host_writel(msm_host, val, host, offset) \
> msm_host->var_ops->msm_writel_relaxed(val, host, offset)
>
> +/* CQHCI vendor specific registers */
> +#define CQHCI_VENDOR_CFG1 0xA00
> +#define CQHCI_VENDOR_DIS_RST_ON_CQ_EN (0x3 << 13)
> +
> struct sdhci_msm_offset {
> u32 core_hc_mode;
> u32 core_mci_data_cnt;
> @@ -1567,6 +1572,127 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
> __sdhci_msm_set_clock(host, clock);
> }
>
> +/*****************************************************************************\
> + * *
> + * MSM Command Queue Engine (CQE) *
> + * *
> +\*****************************************************************************/
> +
> +static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
> +{
> + int cmd_error = 0;
> + int data_error = 0;
> +
> + if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
> + return intmask;
> +
> + cqhci_irq(host->mmc, intmask, cmd_error, data_error);
> + return 0;
> +}
> +
> +void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
> +{
> + struct sdhci_host *host = mmc_priv(mmc);
> + unsigned long flags;
> + u32 ctrl;
> +
> + /*
> + * When CQE is halted, the legacy SDHCI path operates only
> + * on 16-byte descriptors in 64bit mode.
> + */
> + if (host->flags & SDHCI_USE_64_BIT_DMA)
> + host->desc_sz = 16;
> +
> + spin_lock_irqsave(&host->lock, flags);
> +
> + /*
> + * During CQE command transfers, command complete bit gets latched.
> + * So s/w should clear command complete interrupt status when CQE is
> + * either halted or disabled. Otherwise unexpected SDCHI legacy
> + * interrupt gets triggered when CQE is halted/disabled.
> + */
> + ctrl = sdhci_readl(host, SDHCI_INT_ENABLE);
> + ctrl |= SDHCI_INT_RESPONSE;
> + sdhci_writel(host, ctrl, SDHCI_INT_ENABLE);
> + sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
> +
> + spin_unlock_irqrestore(&host->lock, flags);
> +
> + sdhci_cqe_disable(mmc, recovery);
> +}
> +
> +static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
> + .enable = sdhci_cqe_enable,
> + .disable = sdhci_msm_cqe_disable,
> +};
> +
> +static int sdhci_msm_cqe_add_host(struct sdhci_host *host,
> + struct platform_device *pdev)
> +{
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> + struct cqhci_host *cq_host;
> + bool dma64;
> + u32 cqcfg;
> + int ret;
> +
> + /*
> + * When CQE is halted, SDHC operates only on 16byte ADMA descriptors.
> + * So ensure ADMA table is allocated for 16byte descriptors.
> + */
> + if (host->caps & SDHCI_CAN_64BIT)
> + host->alloc_desc_sz = 16;
> +
> + ret = sdhci_setup_host(host);
> + if (ret)
> + return ret;
> +
> + cq_host = cqhci_pltfm_init(pdev);
> + if (IS_ERR(cq_host)) {
> + ret = PTR_ERR(cq_host);
> + dev_err(&pdev->dev, "cqhci-pltfm init: failed: %d\n", ret);
> + goto cleanup;
> + }
> +
> + msm_host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
> + cq_host->ops = &sdhci_msm_cqhci_ops;
> +
> + dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
> +
> + ret = cqhci_init(cq_host, host->mmc, dma64);
> + if (ret) {
> + dev_err(&pdev->dev, "%s: CQE init: failed (%d)\n",
> + mmc_hostname(host->mmc), ret);
> + goto cleanup;
> + }
> +
> + /* Disable cqe reset due to cqe enable signal */
> + cqcfg = cqhci_readl(cq_host, CQHCI_VENDOR_CFG1);
> + cqcfg |= CQHCI_VENDOR_DIS_RST_ON_CQ_EN;
> + cqhci_writel(cq_host, cqcfg, CQHCI_VENDOR_CFG1);
> +
> + /*
> + * SDHC expects 12byte ADMA descriptors till CQE is enabled.
> + * So limit desc_sz to 12 so that the data commands that are sent
> + * during card initialization (before CQE gets enabled) would
> + * get executed without any issues.
> + */
> + if (host->flags & SDHCI_USE_64_BIT_DMA)
> + host->desc_sz = 12;
> +
> + ret = __sdhci_add_host(host);
> + if (ret)
> + goto cleanup;
> +
> + dev_info(&pdev->dev, "%s: CQE init: success\n",
> + mmc_hostname(host->mmc));
> + return ret;
> +
> +cleanup:
> + sdhci_cleanup_host(host);
> + return ret;
> +}
> +
> /*
> * Platform specific register write functions. This is so that, if any
> * register write needs to be followed up by platform specific actions,
> @@ -1731,6 +1857,7 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
> .set_uhs_signaling = sdhci_msm_set_uhs_signaling,
> .write_w = sdhci_msm_writew,
> .write_b = sdhci_msm_writeb,
> + .irq = sdhci_msm_cqe_irq,
> };
>
> static const struct sdhci_pltfm_data sdhci_msm_pdata = {
> @@ -1754,6 +1881,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> u8 core_major;
> const struct sdhci_msm_offset *msm_offset;
> const struct sdhci_msm_variant_info *var_info;
> + struct device_node *node = pdev->dev.of_node;
>
> host = sdhci_pltfm_init(pdev, &sdhci_msm_pdata, sizeof(*msm_host));
> if (IS_ERR(host))
> @@ -1952,7 +2080,10 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> pm_runtime_use_autosuspend(&pdev->dev);
>
> host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;
> - ret = sdhci_add_host(host);
> + if (of_property_read_bool(node, "supports-cqe"))
> + ret = sdhci_msm_cqe_add_host(host, pdev);
> + else
> + ret = sdhci_add_host(host);
> if (ret)
> goto pm_runtime_disable;
> sdhci_msm_set_regulator_caps(msm_host);
>

2020-01-20 09:01:40

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH V2 1/2] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

On 16/01/20 7:03 pm, Veerabhadrarao Badiganti wrote:
> Let a vendor driver supply the maximum descriptor size that it
> can operate on. ADMA descriptor table would be allocated using this
> supplied size.
> If any SD Host controller is of version prior to v4.10 spec
> but supports 16byte descriptor, this change allows them to supply
> correct descriptor size for ADMA table allocation.
>
> Also let a vendor driver update the descriptor size by overriding
> sdhc_host->desc_size if it has to operates on a different descriptor
> sizes in different conditions.
>
> Suggested-by: Adrian Hunter <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>

A couple of minor comments below but with those changes:

Acked-by: Adrian Hunter <[email protected]>

> ---
> drivers/mmc/host/sdhci.c | 7 +++++--
> drivers/mmc/host/sdhci.h | 1 +
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 3140fe2..19a5ad3 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -3822,9 +3822,12 @@ int sdhci_setup_host(struct sdhci_host *host)
> void *buf;
>
> if (host->flags & SDHCI_USE_64_BIT_DMA) {
> + if (!host->alloc_desc_sz)
> + host->alloc_desc_sz =
> + SDHCI_ADMA2_64_DESC_SZ(host);
> + host->desc_sz = host->alloc_desc_sz;
> host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_64_DESC_SZ(host);
> - host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
> + host->desc_sz;
> } else {
> host->adma_table_sz = host->adma_table_cnt *
> SDHCI_ADMA2_32_DESC_SZ;

Please also initialize host->alloc_desc_sz for the 32-bit case here.

> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0ed3e0e..8e7c77d 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -555,6 +555,7 @@ struct sdhci_host {
> dma_addr_t align_addr; /* Mapped bounce buffer */
>
> unsigned int desc_sz; /* ADMA descriptor size */

Please amend the comment above to:
/* ADMA current descriptor size */

> + unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */
>
> struct workqueue_struct *complete_wq; /* Request completion wq */
> struct work_struct complete_work; /* Request completion work */
>

2020-01-20 11:29:15

by Veerabhadrarao Badiganti

[permalink] [raw]
Subject: [PATCH V2 1/2] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

Let a vendor driver supply the maximum descriptor size that it
can operate on. ADMA descriptor table would be allocated using this
supplied size.
If any SD Host controller is of version prior to v4.10 spec
but supports 16byte descriptor, this change allows them to supply
correct descriptor size for ADMA table allocation.

Also let a vendor driver update the descriptor size by overriding
sdhc_host->desc_size if it has to operates on a different descriptor
sizes in different conditions.

Suggested-by: Adrian Hunter <[email protected]>
Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
---
drivers/mmc/host/sdhci.c | 13 +++++++------
drivers/mmc/host/sdhci.h | 3 ++-
2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3140fe2..44fb446 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3822,14 +3822,15 @@ int sdhci_setup_host(struct sdhci_host *host)
void *buf;

if (host->flags & SDHCI_USE_64_BIT_DMA) {
- host->adma_table_sz = host->adma_table_cnt *
- SDHCI_ADMA2_64_DESC_SZ(host);
- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
+ if (!host->alloc_desc_sz)
+ host->alloc_desc_sz =
+ SDHCI_ADMA2_64_DESC_SZ(host);
} else {
- host->adma_table_sz = host->adma_table_cnt *
- SDHCI_ADMA2_32_DESC_SZ;
- host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
+ host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
}
+ host->desc_sz = host->alloc_desc_sz;
+ host->adma_table_sz = host->adma_table_cnt *
+ host->desc_sz;

host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
/*
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0ed3e0e..10bda3a 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -554,7 +554,8 @@ struct sdhci_host {
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */

- unsigned int desc_sz; /* ADMA descriptor size */
+ unsigned int desc_sz; /* ADMA current descriptor size */
+ unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */

struct workqueue_struct *complete_wq; /* Request completion wq */
struct work_struct complete_work; /* Request completion work */
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-20 12:31:52

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH V2 1/2] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

On Mon, 20 Jan 2020 at 12:26, Veerabhadrarao Badiganti
<[email protected]> wrote:
>
> Let a vendor driver supply the maximum descriptor size that it
> can operate on. ADMA descriptor table would be allocated using this
> supplied size.
> If any SD Host controller is of version prior to v4.10 spec
> but supports 16byte descriptor, this change allows them to supply
> correct descriptor size for ADMA table allocation.
>
> Also let a vendor driver update the descriptor size by overriding
> sdhc_host->desc_size if it has to operates on a different descriptor
> sizes in different conditions.
>
> Suggested-by: Adrian Hunter <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>

Applied for next, and by adding Adrian's ack, thanks!

Kind regards
Uffe


> ---
> drivers/mmc/host/sdhci.c | 13 +++++++------
> drivers/mmc/host/sdhci.h | 3 ++-
> 2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 3140fe2..44fb446 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -3822,14 +3822,15 @@ int sdhci_setup_host(struct sdhci_host *host)
> void *buf;
>
> if (host->flags & SDHCI_USE_64_BIT_DMA) {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_64_DESC_SZ(host);
> - host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
> + if (!host->alloc_desc_sz)
> + host->alloc_desc_sz =
> + SDHCI_ADMA2_64_DESC_SZ(host);
> } else {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_32_DESC_SZ;
> - host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> + host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> }
> + host->desc_sz = host->alloc_desc_sz;
> + host->adma_table_sz = host->adma_table_cnt *
> + host->desc_sz;
>
> host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
> /*
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0ed3e0e..10bda3a 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -554,7 +554,8 @@ struct sdhci_host {
> dma_addr_t adma_addr; /* Mapped ADMA descr. table */
> dma_addr_t align_addr; /* Mapped bounce buffer */
>
> - unsigned int desc_sz; /* ADMA descriptor size */
> + unsigned int desc_sz; /* ADMA current descriptor size */
> + unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */
>
> struct workqueue_struct *complete_wq; /* Request completion wq */
> struct work_struct complete_work; /* Request completion work */
> --
> Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-20 12:31:59

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH V2 2/2] mmc: sdhci-msm: Add CQHCI support for sdhci-msm

On Thu, 16 Jan 2020 at 18:05, Veerabhadrarao Badiganti
<[email protected]> wrote:
>
> From: Ritesh Harjani <[email protected]>
>
> This adds CQHCI support for sdhci-msm platforms.
>
> Signed-off-by: Ritesh Harjani <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>

Applied for next, thanks!

Kind regards
Uffe


> ---
> drivers/mmc/host/Kconfig | 1 +
> drivers/mmc/host/sdhci-msm.c | 133 ++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 133 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index d06b2df..7f2ae59 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -501,6 +501,7 @@ config MMC_SDHCI_MSM
> depends on ARCH_QCOM || (ARM && COMPILE_TEST)
> depends on MMC_SDHCI_PLTFM
> select MMC_SDHCI_IO_ACCESSORS
> + select MMC_CQHCI
> help
> This selects the Secure Digital Host Controller Interface (SDHCI)
> support present in Qualcomm SOCs. The controller supports
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 3d0bb5e..0b4d01f 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -15,6 +15,7 @@
> #include <linux/regulator/consumer.h>
>
> #include "sdhci-pltfm.h"
> +#include "cqhci.h"
>
> #define CORE_MCI_VERSION 0x50
> #define CORE_VERSION_MAJOR_SHIFT 28
> @@ -122,6 +123,10 @@
> #define msm_host_writel(msm_host, val, host, offset) \
> msm_host->var_ops->msm_writel_relaxed(val, host, offset)
>
> +/* CQHCI vendor specific registers */
> +#define CQHCI_VENDOR_CFG1 0xA00
> +#define CQHCI_VENDOR_DIS_RST_ON_CQ_EN (0x3 << 13)
> +
> struct sdhci_msm_offset {
> u32 core_hc_mode;
> u32 core_mci_data_cnt;
> @@ -1567,6 +1572,127 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
> __sdhci_msm_set_clock(host, clock);
> }
>
> +/*****************************************************************************\
> + * *
> + * MSM Command Queue Engine (CQE) *
> + * *
> +\*****************************************************************************/
> +
> +static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
> +{
> + int cmd_error = 0;
> + int data_error = 0;
> +
> + if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
> + return intmask;
> +
> + cqhci_irq(host->mmc, intmask, cmd_error, data_error);
> + return 0;
> +}
> +
> +void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery)
> +{
> + struct sdhci_host *host = mmc_priv(mmc);
> + unsigned long flags;
> + u32 ctrl;
> +
> + /*
> + * When CQE is halted, the legacy SDHCI path operates only
> + * on 16-byte descriptors in 64bit mode.
> + */
> + if (host->flags & SDHCI_USE_64_BIT_DMA)
> + host->desc_sz = 16;
> +
> + spin_lock_irqsave(&host->lock, flags);
> +
> + /*
> + * During CQE command transfers, command complete bit gets latched.
> + * So s/w should clear command complete interrupt status when CQE is
> + * either halted or disabled. Otherwise unexpected SDCHI legacy
> + * interrupt gets triggered when CQE is halted/disabled.
> + */
> + ctrl = sdhci_readl(host, SDHCI_INT_ENABLE);
> + ctrl |= SDHCI_INT_RESPONSE;
> + sdhci_writel(host, ctrl, SDHCI_INT_ENABLE);
> + sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
> +
> + spin_unlock_irqrestore(&host->lock, flags);
> +
> + sdhci_cqe_disable(mmc, recovery);
> +}
> +
> +static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
> + .enable = sdhci_cqe_enable,
> + .disable = sdhci_msm_cqe_disable,
> +};
> +
> +static int sdhci_msm_cqe_add_host(struct sdhci_host *host,
> + struct platform_device *pdev)
> +{
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> + struct cqhci_host *cq_host;
> + bool dma64;
> + u32 cqcfg;
> + int ret;
> +
> + /*
> + * When CQE is halted, SDHC operates only on 16byte ADMA descriptors.
> + * So ensure ADMA table is allocated for 16byte descriptors.
> + */
> + if (host->caps & SDHCI_CAN_64BIT)
> + host->alloc_desc_sz = 16;
> +
> + ret = sdhci_setup_host(host);
> + if (ret)
> + return ret;
> +
> + cq_host = cqhci_pltfm_init(pdev);
> + if (IS_ERR(cq_host)) {
> + ret = PTR_ERR(cq_host);
> + dev_err(&pdev->dev, "cqhci-pltfm init: failed: %d\n", ret);
> + goto cleanup;
> + }
> +
> + msm_host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
> + cq_host->ops = &sdhci_msm_cqhci_ops;
> +
> + dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
> +
> + ret = cqhci_init(cq_host, host->mmc, dma64);
> + if (ret) {
> + dev_err(&pdev->dev, "%s: CQE init: failed (%d)\n",
> + mmc_hostname(host->mmc), ret);
> + goto cleanup;
> + }
> +
> + /* Disable cqe reset due to cqe enable signal */
> + cqcfg = cqhci_readl(cq_host, CQHCI_VENDOR_CFG1);
> + cqcfg |= CQHCI_VENDOR_DIS_RST_ON_CQ_EN;
> + cqhci_writel(cq_host, cqcfg, CQHCI_VENDOR_CFG1);
> +
> + /*
> + * SDHC expects 12byte ADMA descriptors till CQE is enabled.
> + * So limit desc_sz to 12 so that the data commands that are sent
> + * during card initialization (before CQE gets enabled) would
> + * get executed without any issues.
> + */
> + if (host->flags & SDHCI_USE_64_BIT_DMA)
> + host->desc_sz = 12;
> +
> + ret = __sdhci_add_host(host);
> + if (ret)
> + goto cleanup;
> +
> + dev_info(&pdev->dev, "%s: CQE init: success\n",
> + mmc_hostname(host->mmc));
> + return ret;
> +
> +cleanup:
> + sdhci_cleanup_host(host);
> + return ret;
> +}
> +
> /*
> * Platform specific register write functions. This is so that, if any
> * register write needs to be followed up by platform specific actions,
> @@ -1731,6 +1857,7 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host)
> .set_uhs_signaling = sdhci_msm_set_uhs_signaling,
> .write_w = sdhci_msm_writew,
> .write_b = sdhci_msm_writeb,
> + .irq = sdhci_msm_cqe_irq,
> };
>
> static const struct sdhci_pltfm_data sdhci_msm_pdata = {
> @@ -1754,6 +1881,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> u8 core_major;
> const struct sdhci_msm_offset *msm_offset;
> const struct sdhci_msm_variant_info *var_info;
> + struct device_node *node = pdev->dev.of_node;
>
> host = sdhci_pltfm_init(pdev, &sdhci_msm_pdata, sizeof(*msm_host));
> if (IS_ERR(host))
> @@ -1952,7 +2080,10 @@ static int sdhci_msm_probe(struct platform_device *pdev)
> pm_runtime_use_autosuspend(&pdev->dev);
>
> host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;
> - ret = sdhci_add_host(host);
> + if (of_property_read_bool(node, "supports-cqe"))
> + ret = sdhci_msm_cqe_add_host(host, pdev);
> + else
> + ret = sdhci_add_host(host);
> if (ret)
> goto pm_runtime_disable;
> sdhci_msm_set_regulator_caps(msm_host);
> --
> Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-20 12:33:30

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH V2 1/2] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

On 20/01/20 1:17 pm, Veerabhadrarao Badiganti wrote:
> Let a vendor driver supply the maximum descriptor size that it
> can operate on. ADMA descriptor table would be allocated using this
> supplied size.
> If any SD Host controller is of version prior to v4.10 spec
> but supports 16byte descriptor, this change allows them to supply
> correct descriptor size for ADMA table allocation.
>
> Also let a vendor driver update the descriptor size by overriding
> sdhc_host->desc_size if it has to operates on a different descriptor
> sizes in different conditions.

A couple of minor tweaks below sorry.

>
> Suggested-by: Adrian Hunter <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
> ---
> drivers/mmc/host/sdhci.c | 13 +++++++------
> drivers/mmc/host/sdhci.h | 3 ++-
> 2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 3140fe2..44fb446 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -3822,14 +3822,15 @@ int sdhci_setup_host(struct sdhci_host *host)
> void *buf;
>
> if (host->flags & SDHCI_USE_64_BIT_DMA) {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_64_DESC_SZ(host);
> - host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
> + if (!host->alloc_desc_sz)
> + host->alloc_desc_sz =
> + SDHCI_ADMA2_64_DESC_SZ(host);
> } else {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_32_DESC_SZ;
> - host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> + host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> }

The following is simpler:

if (!(host->flags & SDHCI_USE_64_BIT_DMA))
host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
else if (!host->alloc_desc_sz)
host->alloc_desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);

> + host->desc_sz = host->alloc_desc_sz;
> + host->adma_table_sz = host->adma_table_cnt *
> + host->desc_sz;

Wrap is not needed

>
> host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
> /*
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0ed3e0e..10bda3a 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -554,7 +554,8 @@ struct sdhci_host {
> dma_addr_t adma_addr; /* Mapped ADMA descr. table */
> dma_addr_t align_addr; /* Mapped bounce buffer */
>
> - unsigned int desc_sz; /* ADMA descriptor size */
> + unsigned int desc_sz; /* ADMA current descriptor size */
> + unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */
>
> struct workqueue_struct *complete_wq; /* Request completion wq */
> struct work_struct complete_work; /* Request completion work */
>

2020-01-20 14:42:18

by Veerabhadrarao Badiganti

[permalink] [raw]
Subject: [PATCH V3] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

Let a vendor driver supply the maximum descriptor size that it
can operate on. ADMA descriptor table would be allocated using this
supplied size.
If any SD Host controller is of version prior to v4.10 spec
but supports 16byte descriptor, this change allows them to supply
correct descriptor size for ADMA table allocation.

Also let a vendor driver update the descriptor size by overriding
sdhc_host->desc_size if it has to operates on a different descriptor
sizes in different conditions.

Suggested-by: Adrian Hunter <[email protected]>
Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
--
Thanks Adrian.

Hi Ulf,
Can you pick this patch instead of earlier one? This is more clean
change, sorry for the multiple interations.
Otherwise let me know, I will make these changes as seperate patch.
---
drivers/mmc/host/sdhci.c | 16 +++++++---------
drivers/mmc/host/sdhci.h | 3 ++-
2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3140fe2..7a7a18e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3821,15 +3821,13 @@ int sdhci_setup_host(struct sdhci_host *host)
dma_addr_t dma;
void *buf;

- if (host->flags & SDHCI_USE_64_BIT_DMA) {
- host->adma_table_sz = host->adma_table_cnt *
- SDHCI_ADMA2_64_DESC_SZ(host);
- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
- } else {
- host->adma_table_sz = host->adma_table_cnt *
- SDHCI_ADMA2_32_DESC_SZ;
- host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
- }
+ if (!(host->flags & SDHCI_USE_64_BIT_DMA))
+ host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
+ else if (!host->alloc_desc_sz)
+ host->alloc_desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
+
+ host->desc_sz = host->alloc_desc_sz;
+ host->adma_table_sz = host->adma_table_cnt * host->desc_sz;

host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
/*
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0ed3e0e..10bda3a 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -554,7 +554,8 @@ struct sdhci_host {
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */

- unsigned int desc_sz; /* ADMA descriptor size */
+ unsigned int desc_sz; /* ADMA current descriptor size */
+ unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */

struct workqueue_struct *complete_wq; /* Request completion wq */
struct work_struct complete_work; /* Request completion work */
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

2020-01-24 11:27:39

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH V3] mmc: sdhci: Let a vendor driver supply and update ADMA descriptor size

On Mon, 20 Jan 2020 at 15:39, Veerabhadrarao Badiganti
<[email protected]> wrote:
>
> Let a vendor driver supply the maximum descriptor size that it
> can operate on. ADMA descriptor table would be allocated using this
> supplied size.
> If any SD Host controller is of version prior to v4.10 spec
> but supports 16byte descriptor, this change allows them to supply
> correct descriptor size for ADMA table allocation.
>
> Also let a vendor driver update the descriptor size by overriding
> sdhc_host->desc_size if it has to operates on a different descriptor
> sizes in different conditions.
>
> Suggested-by: Adrian Hunter <[email protected]>
> Signed-off-by: Veerabhadrarao Badiganti <[email protected]>
> Acked-by: Adrian Hunter <[email protected]>
> --
> Thanks Adrian.
>
> Hi Ulf,
> Can you pick this patch instead of earlier one? This is more clean
> change, sorry for the multiple interations.
> Otherwise let me know, I will make these changes as seperate patch.

Alright, I have replaced the previous version with this one.

Kind regards
Uffe


> ---
> drivers/mmc/host/sdhci.c | 16 +++++++---------
> drivers/mmc/host/sdhci.h | 3 ++-
> 2 files changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 3140fe2..7a7a18e 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -3821,15 +3821,13 @@ int sdhci_setup_host(struct sdhci_host *host)
> dma_addr_t dma;
> void *buf;
>
> - if (host->flags & SDHCI_USE_64_BIT_DMA) {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_64_DESC_SZ(host);
> - host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
> - } else {
> - host->adma_table_sz = host->adma_table_cnt *
> - SDHCI_ADMA2_32_DESC_SZ;
> - host->desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> - }
> + if (!(host->flags & SDHCI_USE_64_BIT_DMA))
> + host->alloc_desc_sz = SDHCI_ADMA2_32_DESC_SZ;
> + else if (!host->alloc_desc_sz)
> + host->alloc_desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
> +
> + host->desc_sz = host->alloc_desc_sz;
> + host->adma_table_sz = host->adma_table_cnt * host->desc_sz;
>
> host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
> /*
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0ed3e0e..10bda3a 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -554,7 +554,8 @@ struct sdhci_host {
> dma_addr_t adma_addr; /* Mapped ADMA descr. table */
> dma_addr_t align_addr; /* Mapped bounce buffer */
>
> - unsigned int desc_sz; /* ADMA descriptor size */
> + unsigned int desc_sz; /* ADMA current descriptor size */
> + unsigned int alloc_desc_sz; /* ADMA descr. max size host supports */
>
> struct workqueue_struct *complete_wq; /* Request completion wq */
> struct work_struct complete_work; /* Request completion work */
> --
> Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project