Commit f545702b authored by Faiz Abbas's avatar Faiz Abbas Committed by Ulf Hansson

mmc: sdhci_am654: Add Support for Command Queuing Engine to J721E

Add Support for CQHCI (Command Queuing Host Controller Interface)
for each of the host controllers present in TI's J721E devices.
Add cqhci_ops and a .irq() callback to handle cqhci specific interrupts.
Signed-off-by: default avatarFaiz Abbas <faiz_abbas@ti.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent f3d7c229
...@@ -1022,6 +1022,7 @@ config MMC_SDHCI_AM654 ...@@ -1022,6 +1022,7 @@ config MMC_SDHCI_AM654
tristate "Support for the SDHCI Controller in TI's AM654 SOCs" tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
select MMC_SDHCI_IO_ACCESSORS select MMC_SDHCI_IO_ACCESSORS
select MMC_CQHCI
help help
This selects the Secure Digital Host Controller Interface (SDHCI) This selects the Secure Digital Host Controller Interface (SDHCI)
support present in TI's AM654 SOCs. The controller supports support present in TI's AM654 SOCs. The controller supports
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/property.h> #include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include "cqhci.h"
#include "sdhci-pltfm.h" #include "sdhci-pltfm.h"
/* CTL_CFG Registers */ /* CTL_CFG Registers */
...@@ -68,6 +69,9 @@ ...@@ -68,6 +69,9 @@
#define CLOCK_TOO_SLOW_HZ 400000 #define CLOCK_TOO_SLOW_HZ 400000
/* Command Queue Host Controller Interface Base address */
#define SDHCI_AM654_CQE_BASE_ADDR 0x200
static struct regmap_config sdhci_am654_regmap_config = { static struct regmap_config sdhci_am654_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
...@@ -259,6 +263,19 @@ static const struct sdhci_am654_driver_data sdhci_am654_drvdata = { ...@@ -259,6 +263,19 @@ static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT, .flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT,
}; };
static u32 sdhci_am654_cqhci_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;
}
static struct sdhci_ops sdhci_j721e_8bit_ops = { static struct sdhci_ops sdhci_j721e_8bit_ops = {
.get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
.get_timeout_clock = sdhci_pltfm_clk_get_max_clock, .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
...@@ -267,6 +284,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = { ...@@ -267,6 +284,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = {
.set_power = sdhci_am654_set_power, .set_power = sdhci_am654_set_power,
.set_clock = sdhci_am654_set_clock, .set_clock = sdhci_am654_set_clock,
.write_b = sdhci_am654_write_b, .write_b = sdhci_am654_write_b,
.irq = sdhci_am654_cqhci_irq,
.reset = sdhci_reset, .reset = sdhci_reset,
}; };
...@@ -290,6 +308,7 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = { ...@@ -290,6 +308,7 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = {
.set_power = sdhci_am654_set_power, .set_power = sdhci_am654_set_power,
.set_clock = sdhci_j721e_4bit_set_clock, .set_clock = sdhci_j721e_4bit_set_clock,
.write_b = sdhci_am654_write_b, .write_b = sdhci_am654_write_b,
.irq = sdhci_am654_cqhci_irq,
.reset = sdhci_reset, .reset = sdhci_reset,
}; };
...@@ -304,6 +323,40 @@ static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = { ...@@ -304,6 +323,40 @@ static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
.pdata = &sdhci_j721e_4bit_pdata, .pdata = &sdhci_j721e_4bit_pdata,
.flags = IOMUX_PRESENT, .flags = IOMUX_PRESENT,
}; };
static void sdhci_am654_dumpregs(struct mmc_host *mmc)
{
sdhci_dumpregs(mmc_priv(mmc));
}
static const struct cqhci_host_ops sdhci_am654_cqhci_ops = {
.enable = sdhci_cqe_enable,
.disable = sdhci_cqe_disable,
.dumpregs = sdhci_am654_dumpregs,
};
static int sdhci_am654_cqe_add_host(struct sdhci_host *host)
{
struct cqhci_host *cq_host;
int ret;
cq_host = devm_kzalloc(host->mmc->parent, sizeof(struct cqhci_host),
GFP_KERNEL);
if (!cq_host)
return -ENOMEM;
cq_host->mmio = host->ioaddr + SDHCI_AM654_CQE_BASE_ADDR;
cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ;
cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
cq_host->ops = &sdhci_am654_cqhci_ops;
host->mmc->caps2 |= MMC_CAP2_CQE;
ret = cqhci_init(cq_host, host->mmc, 1);
return ret;
}
static int sdhci_am654_init(struct sdhci_host *host) static int sdhci_am654_init(struct sdhci_host *host)
{ {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
...@@ -344,7 +397,23 @@ static int sdhci_am654_init(struct sdhci_host *host) ...@@ -344,7 +397,23 @@ static int sdhci_am654_init(struct sdhci_host *host)
regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK, regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
ctl_cfg_2); ctl_cfg_2);
return sdhci_add_host(host); ret = sdhci_setup_host(host);
if (ret)
return ret;
ret = sdhci_am654_cqe_add_host(host);
if (ret)
goto err_cleanup_host;
ret = __sdhci_add_host(host);
if (ret)
goto err_cleanup_host;
return 0;
err_cleanup_host:
sdhci_cleanup_host(host);
return ret;
} }
static int sdhci_am654_get_of_property(struct platform_device *pdev, static int sdhci_am654_get_of_property(struct platform_device *pdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment