Commit 212f4f8a authored by Kishon Vijay Abraham I's avatar Kishon Vijay Abraham I Committed by Ulf Hansson

mmc: sdhci-omap: Workaround for Errata i843

Errata i843 in AM572x Sitara Processors Silicon Revision 2.0, 1.1
(SPRZ429K July 2014–Revised March 2017 [1]) mentions
PG 1.0/1.1 silicon has limitations w.r.t frequencies at which MMC1/2/3
can operate.

Use soc_device_match() to identify rev 1.0/1.1 silicon and
override mmc->f_max according to the errata workaround.
"max-frequency" dt property cannot be used since the device
tree is added for rev 2.0 silicon.

soc_device_match() is also used in order to get the IODelay values
for rev 1.0/1.1 silicon.

[1] -> http://www.ti.com/lit/er/sprz429k/sprz429k.pdfSigned-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 5bc2bda5
......@@ -26,6 +26,7 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/sys_soc.h>
#include "sdhci-pltfm.h"
......@@ -100,6 +101,7 @@ struct sdhci_omap_data {
};
struct sdhci_omap_host {
char *version;
void __iomem *base;
struct device *dev;
struct regulator *pbias;
......@@ -733,12 +735,21 @@ static struct pinctrl_state
u32 *caps, u32 capmask)
{
struct device *dev = omap_host->dev;
char *version = omap_host->version;
struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV);
char str[20];
if (!(*caps & capmask))
goto ret;
if (version) {
snprintf(str, 20, "%s-%s", mode, version);
pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, str);
}
if (IS_ERR(pinctrl_state))
pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode);
if (IS_ERR(pinctrl_state)) {
dev_err(dev, "no pinctrl state for %s mode", mode);
*caps &= ~capmask;
......@@ -830,6 +841,16 @@ static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host
return 0;
}
static const struct soc_device_attribute sdhci_omap_soc_devices[] = {
{
.machine = "DRA7[45]*",
.revision = "ES1.[01]",
},
{
/* sentinel */
}
};
static int sdhci_omap_probe(struct platform_device *pdev)
{
int ret;
......@@ -841,6 +862,7 @@ static int sdhci_omap_probe(struct platform_device *pdev)
struct mmc_host *mmc;
const struct of_device_id *match;
struct sdhci_omap_data *data;
const struct soc_device_attribute *soc;
match = of_match_device(omap_sdhci_match, dev);
if (!match)
......@@ -875,6 +897,17 @@ static int sdhci_omap_probe(struct platform_device *pdev)
if (ret)
goto err_pltfm_free;
soc = soc_device_match(sdhci_omap_soc_devices);
if (soc) {
omap_host->version = "rev11";
if (!strcmp(dev_name(dev), "4809c000.mmc"))
mmc->f_max = 96000000;
if (!strcmp(dev_name(dev), "480b4000.mmc"))
mmc->f_max = 48000000;
if (!strcmp(dev_name(dev), "480ad000.mmc"))
mmc->f_max = 48000000;
}
pltfm_host->clk = devm_clk_get(dev, "fck");
if (IS_ERR(pltfm_host->clk)) {
ret = PTR_ERR(pltfm_host->clk);
......
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