Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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.pdf



Signed-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
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -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);