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

From: christian . koever-draxl

Date: Sun Oct 25 2026 - 15:22:18 EST


From: Christian Stefan Kövér-Draxl <ckoever@xxxxxxxxxx>

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@xxxxxxxxxx>
---
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