[PATCH v2 2/3] mmc: meson-gx: change clock phase value on SM1 SoCs

Jaehoon Chung jh80.chung at samsung.com
Wed Nov 11 00:22:10 CET 2020


From: Neil Armstrong <narmstrong at baylibre.com>

Amlogic SM1 SoCs doesn't work over 50MHz. When phase sets to 270', it's
working fine over 50MHz on Amlogic SM1 SoCs.
Since Other Amlogic SoCs doens't report an issue, phase value is using
to 180' by default.

To distinguish which value is used adds an u-boot only sm1 compatible.

In future, it needs to find what value is a proper about each SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Signed-off-by: Jaehoon Chung <jh80.chung at samsung.com>
---
 drivers/mmc/meson_gx_mmc.c | 27 +++++++++++++++++++++++----
 drivers/mmc/meson_gx_mmc.h |  5 +++++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index eedebb317b5f..a5e9ac5637b9 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -17,6 +17,14 @@
 #include <linux/log2.h>
 #include "meson_gx_mmc.h"
 
+bool meson_gx_mmc_is_compatible(struct udevice *dev,
+				enum meson_gx_mmc_compatible family)
+{
+	enum meson_gx_mmc_compatible compat = dev_get_driver_data(dev);
+
+	return compat == family;
+}
+
 static inline void *get_regbase(const struct mmc *mmc)
 {
 	struct meson_mmc_platdata *pdata = mmc->priv;
@@ -42,6 +50,8 @@ static void meson_mmc_config_clock(struct mmc *mmc)
 	if (!mmc->clock)
 		return;
 
+	/* TOFIX This should use the proper clock taken from DT */
+
 	/* 1GHz / CLK_MAX_DIV = 15,9 MHz */
 	if (mmc->clock > 16000000) {
 		clk = SD_EMMC_CLKSRC_DIV2;
@@ -52,8 +62,16 @@ static void meson_mmc_config_clock(struct mmc *mmc)
 	}
 	clk_div = DIV_ROUND_UP(clk, mmc->clock);
 
-	/* 180 phase core clock */
-	meson_mmc_clk |= CLK_CO_PHASE_180;
+	/*
+	 * SM1 SoCs doesn't work fine over 50MHz with CLK_CO_PHASE_180
+	 * If CLK_CO_PHASE_270 is used, it's more stable than other.
+	 * Other SoCs use CLK_CO_PHASE_180 by default.
+	 * It needs to find what is a proper value about each SoCs.
+	 */
+	if (meson_gx_mmc_is_compatible(mmc->dev, MMC_COMPATIBLE_SM1))
+		meson_mmc_clk |= CLK_CO_PHASE_270;
+	else
+		meson_mmc_clk |= CLK_CO_PHASE_180;
 
 	/* 180 phase tx clock */
 	meson_mmc_clk |= CLK_TX_PHASE_000;
@@ -308,8 +326,9 @@ int meson_mmc_bind(struct udevice *dev)
 }
 
 static const struct udevice_id meson_mmc_match[] = {
-	{ .compatible = "amlogic,meson-gx-mmc" },
-	{ .compatible = "amlogic,meson-axg-mmc" },
+	{ .compatible = "amlogic,meson-gx-mmc", .data = MMC_COMPATIBLE_GX },
+	{ .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_GX },
+	{ .compatible = "amlogic,meson-sm1-mmc", .data = MMC_COMPATIBLE_SM1 },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/mmc/meson_gx_mmc.h b/drivers/mmc/meson_gx_mmc.h
index b4544b55628f..92aec5329f6e 100644
--- a/drivers/mmc/meson_gx_mmc.h
+++ b/drivers/mmc/meson_gx_mmc.h
@@ -9,6 +9,11 @@
 #include <mmc.h>
 #include <linux/bitops.h>
 
+enum meson_gx_mmc_compatible {
+	MMC_COMPATIBLE_GX,
+	MMC_COMPATIBLE_SM1,
+};
+
 #define SDIO_PORT_A			0
 #define SDIO_PORT_B			1
 #define SDIO_PORT_C			2
-- 
2.29.0



More information about the U-Boot mailing list