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

Commit 0a0e8d75 authored by Andrew Jeffery's avatar Andrew Jeffery Committed by Ulf Hansson
Browse files

mmc: sdhci-of-aspeed: Allow max-frequency limitation of SDCLK



Add a get_max_clock() handler to sdhci-of-aspeed to report f_max as the
maximum clock rate if it is set. This enables artificial limitation of
the bus speed via max-frequency in the devicetree for e.g. the AST2600
evaluation board where I was seeing errors at 200MHz.

Signed-off-by: default avatarAndrew Jeffery <andrew@aj.id.au>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 7b954cdf
Loading
Loading
Loading
Loading
+18 −2
Original line number Original line Diff line number Diff line
@@ -52,16 +52,24 @@ static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc,


static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
{
	struct sdhci_pltfm_host *pltfm_host;
	unsigned long parent;
	int div;
	int div;
	u16 clk;
	u16 clk;


	pltfm_host = sdhci_priv(host);
	parent = clk_get_rate(pltfm_host->clk);

	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);


	if (clock == 0)
	if (clock == 0)
		return;
		return;


	if (WARN_ON(clock > host->max_clk))
		clock = host->max_clk;

	for (div = 1; div < 256; div *= 2) {
	for (div = 1; div < 256; div *= 2) {
		if ((host->max_clk / div) <= clock)
		if ((parent / div) <= clock)
			break;
			break;
	}
	}
	div >>= 1;
	div >>= 1;
@@ -71,6 +79,14 @@ static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
	sdhci_enable_clk(host, clk);
	sdhci_enable_clk(host, clk);
}
}


static unsigned int aspeed_sdhci_get_max_clock(struct sdhci_host *host)
{
	if (host->mmc->f_max)
		return host->mmc->f_max;

	return sdhci_pltfm_clk_get_max_clock(host);
}

static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width)
static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width)
{
{
	struct sdhci_pltfm_host *pltfm_priv;
	struct sdhci_pltfm_host *pltfm_priv;
@@ -97,7 +113,7 @@ static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width)


static const struct sdhci_ops aspeed_sdhci_ops = {
static const struct sdhci_ops aspeed_sdhci_ops = {
	.set_clock = aspeed_sdhci_set_clock,
	.set_clock = aspeed_sdhci_set_clock,
	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
	.get_max_clock = aspeed_sdhci_get_max_clock,
	.set_bus_width = aspeed_sdhci_set_bus_width,
	.set_bus_width = aspeed_sdhci_set_bus_width,
	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
	.reset = sdhci_reset,
	.reset = sdhci_reset,