[U-Boot] [PATCH 8/9] mmc: tegra: port to standard clock/reset APIs
Stephen Warren
swarren at wwwdotorg.org
Wed Jul 27 23:24:56 CEST 2016
From: Stephen Warren <swarren at nvidia.com>
Tegra186 supports the new standard clock and reset APIs. Older Tegra SoCs
still use custom APIs. Enhance the Tegra MMC driver so that it can operate
with either set of APIs.
Signed-off-by: Stephen Warren <swarren at nvidia.com>
Cc: Pantelis Antoniou <panto at antoniou-consulting.com>
---
arch/arm/include/asm/arch-tegra/tegra_mmc.h | 8 ++++-
drivers/mmc/tegra_mmc.c | 55 ++++++++++++++++++++++++-----
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
index 75e56c4ea786..07ef4c04c858 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
@@ -9,6 +9,9 @@
#ifndef __TEGRA_MMC_H_
#define __TEGRA_MMC_H_
+#include <common.h>
+#include <clk.h>
+#include <reset.h>
#include <fdtdec.h>
#include <asm/gpio.h>
@@ -134,7 +137,10 @@ struct mmc_host {
int id; /* device id/number, 0-3 */
int enabled; /* 1 to enable, 0 to disable */
int width; /* Bus Width, 1, 4 or 8 */
-#ifndef CONFIG_TEGRA186
+#ifdef CONFIG_TEGRA186
+ struct reset_ctl reset_ctl;
+ struct clk clk;
+#else
enum periph_id mmc_id; /* Peripheral ID: PERIPH_ID_... */
#endif
struct gpio_desc cd_gpio; /* Change Detect GPIO */
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index c9d9432e5e87..b27ca635ac50 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -9,6 +9,7 @@
#include <bouncebuf.h>
#include <common.h>
+#include <dm/device.h>
#include <asm/gpio.h>
#include <asm/io.h>
#ifndef CONFIG_TEGRA186
@@ -359,11 +360,14 @@ static void mmc_change_clock(struct mmc_host *host, uint clock)
*/
if (clock == 0)
goto out;
-#ifndef CONFIG_TEGRA186
+#ifdef CONFIG_TEGRA186
+ {
+ ulong rate = clk_set_rate(&host->clk, clock);
+ div = (rate + clock - 1) / clock;
+ }
+#else
clock_adjust_periph_pll_div(host->mmc_id, CLOCK_ID_PERIPH, clock,
&div);
-#else
- div = (20000000 + clock - 1) / clock;
#endif
debug("div = %d\n", div);
@@ -538,6 +542,9 @@ static int do_mmc_init(int dev_index, bool removable)
{
struct mmc_host *host;
struct mmc *mmc;
+#ifdef CONFIG_TEGRA186
+ int ret;
+#endif
/* DT should have been read & host config filled in */
host = &mmc_host[dev_index];
@@ -549,7 +556,21 @@ static int do_mmc_init(int dev_index, bool removable)
gpio_get_number(&host->cd_gpio));
host->clock = 0;
-#ifndef CONFIG_TEGRA186
+
+#ifdef CONFIG_TEGRA186
+ ret = reset_assert(&host->reset_ctl);
+ if (ret)
+ return ret;
+ ret = clk_enable(&host->clk);
+ if (ret)
+ return ret;
+ ret = clk_set_rate(&host->clk, 20000000);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+ ret = reset_deassert(&host->reset_ctl);
+ if (ret)
+ return ret;
+#else
clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);
#endif
@@ -576,11 +597,7 @@ static int do_mmc_init(int dev_index, bool removable)
* (actually 52MHz)
*/
host->cfg.f_min = 375000;
-#ifndef CONFIG_TEGRA186
host->cfg.f_max = 48000000;
-#else
- host->cfg.f_max = 375000;
-#endif
host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
@@ -612,7 +629,27 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
return -FDT_ERR_NOTFOUND;
}
-#ifndef CONFIG_TEGRA186
+#ifdef CONFIG_TEGRA186
+ {
+ /*
+ * FIXME: This variable should go away when the MMC device
+ * actually is a udevice.
+ */
+ struct udevice dev;
+ int ret;
+ dev.of_offset = node;
+ ret = reset_get_by_name(&dev, "sdmmc", &host->reset_ctl);
+ if (ret) {
+ debug("reset_get_by_index() failed: %d\n", ret);
+ return ret;
+ }
+ ret = clk_get_by_name(&dev, "sdmmc", &host->clk);
+ if (ret) {
+ debug("clk_get_by_index() failed: %d\n", ret);
+ return ret;
+ }
+ }
+#else
host->mmc_id = clock_decode_periph_id(blob, node);
if (host->mmc_id == PERIPH_ID_NONE) {
debug("%s: could not decode periph id\n", __func__);
--
2.9.2
More information about the U-Boot
mailing list