From b4f2208363a73a4ccfe2006c1ecc4db9b966fc82 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Mon, 7 Dec 2020 22:18:35 +0100 Subject: [PATCH] Fix boot from 128GB Micron eMMC on ODROID-N2(+) (#1064) --- ...change-clock-phase-value-on-SM1-SoCs.patch | 103 ++++++++++++++++++ ...change-clock-phase-value-on-AGX-SoCs.patch | 73 +++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 buildroot-external/board/hardkernel/patches/uboot/0004-mmc-meson-gx-change-clock-phase-value-on-SM1-SoCs.patch create mode 100644 buildroot-external/board/hardkernel/patches/uboot/0005-mmc-meson-gx-change-clock-phase-value-on-AGX-SoCs.patch diff --git a/buildroot-external/board/hardkernel/patches/uboot/0004-mmc-meson-gx-change-clock-phase-value-on-SM1-SoCs.patch b/buildroot-external/board/hardkernel/patches/uboot/0004-mmc-meson-gx-change-clock-phase-value-on-SM1-SoCs.patch new file mode 100644 index 000000000..8bea01863 --- /dev/null +++ b/buildroot-external/board/hardkernel/patches/uboot/0004-mmc-meson-gx-change-clock-phase-value-on-SM1-SoCs.patch @@ -0,0 +1,103 @@ +From 68d89f37f4793b8d59525725cb882130cbd42433 Mon Sep 17 00:00:00 2001 +Message-Id: <68d89f37f4793b8d59525725cb882130cbd42433.1607375763.git.stefan@agner.ch> +In-Reply-To: +References: +From: Neil Armstrong +Date: Wed, 11 Nov 2020 08:22:10 +0900 +Subject: [PATCH 4/5] mmc: meson-gx: change clock phase value on SM1 SoCs + +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 +Signed-off-by: Jaehoon Chung +Tested-by: Anand Moon +--- + arch/arm/include/asm/arch-meson/sd_emmc.h | 5 +++++ + drivers/mmc/meson_gx_mmc.c | 27 +++++++++++++++++++---- + 2 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/include/asm/arch-meson/sd_emmc.h b/arch/arm/include/asm/arch-meson/sd_emmc.h +index e3a72c8b66..a9dbb0884b 100644 +--- a/arch/arm/include/asm/arch-meson/sd_emmc.h ++++ b/arch/arm/include/asm/arch-meson/sd_emmc.h +@@ -8,6 +8,11 @@ + + #include + ++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 +diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c +index b5f5122b1b..b5d22dca1e 100644 +--- a/drivers/mmc/meson_gx_mmc.c ++++ b/drivers/mmc/meson_gx_mmc.c +@@ -15,6 +15,14 @@ + #include + #include + ++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; +@@ -40,6 +48,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; +@@ -50,8 +60,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; +@@ -295,8 +313,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 */ } + }; + +-- +2.29.2 + diff --git a/buildroot-external/board/hardkernel/patches/uboot/0005-mmc-meson-gx-change-clock-phase-value-on-AGX-SoCs.patch b/buildroot-external/board/hardkernel/patches/uboot/0005-mmc-meson-gx-change-clock-phase-value-on-AGX-SoCs.patch new file mode 100644 index 000000000..7e4c64344 --- /dev/null +++ b/buildroot-external/board/hardkernel/patches/uboot/0005-mmc-meson-gx-change-clock-phase-value-on-AGX-SoCs.patch @@ -0,0 +1,73 @@ +From c91d9f6f8137d82d5afe02a33954b322e310d902 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Stefan Agner +Date: Mon, 7 Dec 2020 17:55:28 +0100 +Subject: [PATCH 5/5] mmc: meson-gx: change clock phase value on AGX SoCs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Amlogic AGX SoCs seem to have issue communicating with some eMMC +devices (in particular with a Micron 128GB eMMC 5.1). The device +is detected with 1-bit bus width, and at higher temperature loading +pretty much anything from the storage fails: (e.g. fs_devread read error +- block). + +When phase is set to 270° it is detected with 8-bit bus width and is +working fine accross all temperatures. + +Signed-off-by: Stefan Agner +--- + arch/arm/include/asm/arch-meson/sd_emmc.h | 1 + + drivers/mmc/meson_gx_mmc.c | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/include/asm/arch-meson/sd_emmc.h b/arch/arm/include/asm/arch-meson/sd_emmc.h +index a9dbb0884b..f706761b46 100644 +--- a/arch/arm/include/asm/arch-meson/sd_emmc.h ++++ b/arch/arm/include/asm/arch-meson/sd_emmc.h +@@ -10,6 +10,7 @@ + + enum meson_gx_mmc_compatible { + MMC_COMPATIBLE_GX, ++ MMC_COMPATIBLE_AGX, + MMC_COMPATIBLE_SM1, + }; + +diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c +index b5d22dca1e..e2f9583014 100644 +--- a/drivers/mmc/meson_gx_mmc.c ++++ b/drivers/mmc/meson_gx_mmc.c +@@ -62,14 +62,15 @@ static void meson_mmc_config_clock(struct mmc *mmc) + + /* + * SM1 SoCs doesn't work fine over 50MHz with CLK_CO_PHASE_180 ++ * AGX SoCs don't work reliable with some eMMCs 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 ++ if (meson_gx_mmc_is_compatible(mmc->dev, MMC_COMPATIBLE_GX)) + meson_mmc_clk |= CLK_CO_PHASE_180; ++ else ++ meson_mmc_clk |= CLK_CO_PHASE_270; + + /* 180 phase tx clock */ + meson_mmc_clk |= CLK_TX_PHASE_000; +@@ -314,7 +315,7 @@ int meson_mmc_bind(struct udevice *dev) + + static const struct udevice_id meson_mmc_match[] = { + { .compatible = "amlogic,meson-gx-mmc", .data = MMC_COMPATIBLE_GX }, +- { .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_GX }, ++ { .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_AGX }, + { .compatible = "amlogic,meson-sm1-mmc", .data = MMC_COMPATIBLE_SM1 }, + { /* sentinel */ } + }; +-- +2.29.2 +