Skip to content

Commit

Permalink
mmc: sdhci-tegra: Add support to program MC stream ID
Browse files Browse the repository at this point in the history
SMMU clients are supposed to program stream ID from
their respective address spaces instead of MC override.
Define NVQUIRK_PROGRAM_STREAMID and use it to program
SMMU stream ID from the SDMMC client address space.

Signed-off-by: Aniruddha TVS Rao <anrao@nvidia.com>
Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
  • Loading branch information
Prathamesh Shete authored and intel-lab-lkp committed Sep 20, 2022
1 parent fbb614b commit 8087ec8
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions drivers/mmc/host/sdhci-tegra.c
Expand Up @@ -25,6 +25,7 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/ktime.h>
#include <linux/iommu.h>

#include <soc/tegra/common.h>

Expand Down Expand Up @@ -94,6 +95,8 @@
#define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec
#define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31)

#define SDHCI_TEGRA_CIF2AXI_CTRL_0 0x1fc

#define NVQUIRK_FORCE_SDHCI_SPEC_200 BIT(0)
#define NVQUIRK_ENABLE_BLOCK_GAP_DET BIT(1)
#define NVQUIRK_ENABLE_SDHCI_SPEC_300 BIT(2)
Expand Down Expand Up @@ -121,13 +124,16 @@
#define NVQUIRK_HAS_TMCLK BIT(10)

#define NVQUIRK_HAS_ANDROID_GPT_SECTOR BIT(11)
#define NVQUIRK_PROGRAM_STREAMID BIT(12)

/* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */
#define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000

#define SDHCI_TEGRA_CQE_TRNS_MODE (SDHCI_TRNS_MULTI | \
SDHCI_TRNS_BLK_CNT_EN | \
SDHCI_TRNS_DMA)
#define SDHCI_TEGRA_STREAMID_MASK 0xff
#define SDHCI_TEGRA_WRITE_STREAMID_SHIFT 0x8

struct sdhci_tegra_soc_data {
const struct sdhci_pltfm_data *pdata;
Expand Down Expand Up @@ -177,6 +183,7 @@ struct sdhci_tegra {
bool enable_hwcq;
unsigned long curr_clk_rate;
u8 tuned_tap_delay;
u32 streamid;
};

static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
Expand Down Expand Up @@ -1564,6 +1571,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra234 = {
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
NVQUIRK_ENABLE_SDR50 |
NVQUIRK_ENABLE_SDR104 |
NVQUIRK_PROGRAM_STREAMID |
NVQUIRK_HAS_TMCLK,
.min_tap_delay = 95,
.max_tap_delay = 111,
Expand Down Expand Up @@ -1636,6 +1644,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_tegra *tegra_host;
struct iommu_fwspec *fwspec;
struct clk *clk;
int rc;

Expand Down Expand Up @@ -1775,6 +1784,23 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
if (rc)
goto err_add_host;

/* Program MC streamID for DMA transfers */
if (soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) {
fwspec = dev_iommu_fwspec_get(&pdev->dev);
if (fwspec == NULL) {
dev_warn(mmc_dev(host->mmc),
"iommu fwspec is NULL, continue without stream ID\n");
} else {
tegra_host->streamid = fwspec->ids[0] & 0xffff;
tegra_sdhci_writel(host, (tegra_host->streamid &
SDHCI_TEGRA_STREAMID_MASK) |
((tegra_host->streamid <<
SDHCI_TEGRA_WRITE_STREAMID_SHIFT)
& SDHCI_TEGRA_STREAMID_MASK),
SDHCI_TEGRA_CIF2AXI_CTRL_0);
}
}

return 0;

err_add_host:
Expand Down Expand Up @@ -1861,6 +1887,8 @@ static int sdhci_tegra_suspend(struct device *dev)
static int sdhci_tegra_resume(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
int ret;

ret = mmc_gpio_set_cd_wake(host->mmc, false);
Expand All @@ -1871,6 +1899,13 @@ static int sdhci_tegra_resume(struct device *dev)
if (ret)
return ret;

/* Re-program MC streamID for DMA transfers */
if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) {
tegra_sdhci_writel(host, tegra_host->streamid |
(tegra_host->streamid << 8),
SDHCI_TEGRA_CIF2AXI_CTRL_0);
}

ret = sdhci_resume_host(host);
if (ret)
goto disable_clk;
Expand Down

0 comments on commit 8087ec8

Please sign in to comment.