[PATCH 2/2] mmc: meson-gx: allow the core clock phase to be set from DT

christian.koever-draxl at student.uibk.ac.at christian.koever-draxl at student.uibk.ac.at
Sun Oct 25 12:20:59 PDT 2026


From: Christian Stefan Kövér-Draxl <ckoever at outlook.de>

The core phase is hardcoded to 180 degrees. On an S905W2 board the SD
card fails with CRC errors (-EILSEQ) right after switching to high
speed at 50 MHz.

Sweeping the core phase on the live controller showed that 270 degrees
works on that slot, as the vendor kernel's init_core_phase setting
does. With it the card runs at 50 MHz: 21.7 MB/s sequential read,
6.3 MB/s write, data verified by checksum.

Read the optional amlogic,core-phase-degrees property and keep 180
degrees as the default.

Signed-off-by: Christian Stefan Kövér-Draxl <ckoever at outlook.de>
---
 drivers/mmc/host/meson-gx-mmc.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 694bb443d5f3..42c855248675 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -425,12 +425,25 @@ static int meson_mmc_clk_init(struct meson_host *host)
 	int i, ret = 0;
 	const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
 	const char *clk_parent[1];
-	u32 clk_reg;
+	u32 clk_reg, core_phase = 180;
+
+	/*
+	 * 180 degrees suits most boards, but some only sample reliably at
+	 * high speed with another core phase (the vendor trees carry this as
+	 * "init_core_phase"). The field is in 90 degree steps.
+	 */
+	device_property_read_u32(host->dev, "amlogic,core-phase-degrees",
+				 &core_phase);
+	if (core_phase % 90 || core_phase > 270) {
+		dev_warn(host->dev, "invalid amlogic,core-phase-degrees %u, using 180\n",
+			 core_phase);
+		core_phase = 180;
+	}
 
 	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
 	clk_reg = CLK_ALWAYS_ON(host);
 	clk_reg |= CLK_DIV_MASK;
-	clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, CLK_PHASE_180);
+	clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, core_phase / 90);
 	clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, CLK_PHASE_0);
 	clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, CLK_PHASE_0);
 	if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
-- 
2.56.0




More information about the linux-arm-kernel mailing list