* [PATCH v2 1/4] dt-bindings: mmc: amlogic,meson-gx-mmc: document the T7 pipeline clock
2026-09-05 15:32 [PATCH v2 0/4] amlogic: t7: give the MMC bus pipeline clock real consumers Lucas Tanure
@ 2026-09-05 15:32 ` Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 2/4] mmc: meson-gx: enable the bus pipeline clock on T7 Lucas Tanure
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Lucas Tanure @ 2026-09-05 15:32 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Jerome Brunet, Kevin Hilman, Martin Blumenstingl,
Stephen Boyd
Cc: Brian Masney, Chuan Liu, Jian Hu, Ronald Claveau, linux-mmc,
devicetree, linux-arm-kernel, linux-amlogic, linux-clk,
linux-kernel
The SD/eMMC controllers of the T7 SoC are physically far from the
NIC_MATRIX bus fabric, so the hardware design inserts a pipeline stage
in the middle of the bus path to help timing closure. This stage is fed
by its own gate clock and, when that clock is disabled, a controller
that starts a DMA transfer can never complete it.
Allow a fourth clock entry, named "pipeline", and require it for the
amlogic,t7-mmc compatible. The other controllers of this family keep
the existing three clocks.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Lucas Tanure <tanure@linux.com>
---
.../bindings/mmc/amlogic,meson-gx-mmc.yaml | 29 ++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
index 976f36de2091..12342b1d78e5 100644
--- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
@@ -15,6 +15,23 @@ maintainers:
allOf:
- $ref: mmc-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: amlogic,t7-mmc
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ minItems: 4
+ else:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ maxItems: 3
properties:
compatible:
@@ -38,13 +55,23 @@ properties:
- description: card detect
clocks:
- maxItems: 3
+ minItems: 3
+ items:
+ - description: core clock
+ - description: clock input 0 of the internal mux
+ - description: clock input 1 of the internal mux
+ - description:
+ clock of the pipeline stage inserted in the bus path between
+ the controller and the DRAM. Without it, the controller cannot
+ complete DMA transfers.
clock-names:
+ minItems: 3
items:
- const: core
- const: clkin0
- const: clkin1
+ - const: pipeline
resets:
maxItems: 1
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 2/4] mmc: meson-gx: enable the bus pipeline clock on T7
2026-09-05 15:32 [PATCH v2 0/4] amlogic: t7: give the MMC bus pipeline clock real consumers Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 1/4] dt-bindings: mmc: amlogic,meson-gx-mmc: document the T7 pipeline clock Lucas Tanure
@ 2026-09-05 15:32 ` Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 3/4] arm64: dts: amlogic: t7: add the pipeline clock to the MMC controllers Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 4/4] clk: meson: t7: don't mark sys_ampipe_nand as critical Lucas Tanure
3 siblings, 0 replies; 5+ messages in thread
From: Lucas Tanure @ 2026-09-05 15:32 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Jerome Brunet, Kevin Hilman, Martin Blumenstingl,
Stephen Boyd
Cc: Brian Masney, Chuan Liu, Jian Hu, Ronald Claveau, linux-mmc,
devicetree, linux-arm-kernel, linux-amlogic, linux-clk,
linux-kernel
On the T7 SoC, the bus path between the SD/eMMC controllers and the
NIC_MATRIX fabric goes through a pipeline stage inserted by the hardware
design to help timing closure. The stage has its own gate clock and,
when that clock is disabled, a controller that starts a DMA transfer can
never complete it, hanging the storage devices and, from there, the
whole system.
Add a dedicated match data for the amlogic,t7-mmc compatible that makes
the driver claim and enable the "pipeline" clock for as long as the
device is bound.
The clock is deliberately not optional: the hardware cannot do DMA
without it, and failing the probe with a clear error is preferable to
booting and hitting an undiagnosable DMA hang later.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Lucas Tanure <tanure@linux.com>
---
drivers/mmc/host/meson-gx-mmc.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 694bb443d5f3..c0f1e929fc13 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -139,6 +139,7 @@ struct meson_mmc_data {
unsigned int always_on;
unsigned int adjust;
unsigned int irq_sdio_sleep;
+ bool has_pipeline_clk;
};
struct sd_emmc_desc {
@@ -1204,6 +1205,15 @@ static int meson_mmc_probe(struct platform_device *pdev)
if (IS_ERR(core_clk))
return PTR_ERR(core_clk);
+ if (host->data->has_pipeline_clk) {
+ struct clk *pipe_clk;
+
+ pipe_clk = devm_clk_get_enabled(&pdev->dev, "pipeline");
+ if (IS_ERR(pipe_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(pipe_clk),
+ "missing pipeline clock\n");
+ }
+
ret = meson_mmc_clk_init(host);
if (ret)
return ret;
@@ -1322,12 +1332,22 @@ static const struct meson_mmc_data meson_axg_data = {
.irq_sdio_sleep = CLK_V3_IRQ_SDIO_SLEEP,
};
+static const struct meson_mmc_data meson_t7_data = {
+ .tx_delay_mask = CLK_V3_TX_DELAY_MASK,
+ .rx_delay_mask = CLK_V3_RX_DELAY_MASK,
+ .always_on = CLK_V3_ALWAYS_ON,
+ .adjust = SD_EMMC_V3_ADJUST,
+ .irq_sdio_sleep = CLK_V3_IRQ_SDIO_SLEEP,
+ .has_pipeline_clk = true,
+};
+
static const struct of_device_id meson_mmc_of_match[] = {
{ .compatible = "amlogic,meson-gx-mmc", .data = &meson_gx_data },
{ .compatible = "amlogic,meson-gxbb-mmc", .data = &meson_gx_data },
{ .compatible = "amlogic,meson-gxl-mmc", .data = &meson_gx_data },
{ .compatible = "amlogic,meson-gxm-mmc", .data = &meson_gx_data },
{ .compatible = "amlogic,meson-axg-mmc", .data = &meson_axg_data },
+ { .compatible = "amlogic,t7-mmc", .data = &meson_t7_data },
{}
};
MODULE_DEVICE_TABLE(of, meson_mmc_of_match);
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 3/4] arm64: dts: amlogic: t7: add the pipeline clock to the MMC controllers
2026-09-05 15:32 [PATCH v2 0/4] amlogic: t7: give the MMC bus pipeline clock real consumers Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 1/4] dt-bindings: mmc: amlogic,meson-gx-mmc: document the T7 pipeline clock Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 2/4] mmc: meson-gx: enable the bus pipeline clock on T7 Lucas Tanure
@ 2026-09-05 15:32 ` Lucas Tanure
2026-09-05 15:32 ` [PATCH v2 4/4] clk: meson: t7: don't mark sys_ampipe_nand as critical Lucas Tanure
3 siblings, 0 replies; 5+ messages in thread
From: Lucas Tanure @ 2026-09-05 15:32 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Jerome Brunet, Kevin Hilman, Martin Blumenstingl,
Stephen Boyd
Cc: Brian Masney, Chuan Liu, Jian Hu, Ronald Claveau, linux-mmc,
devicetree, linux-arm-kernel, linux-amlogic, linux-clk,
linux-kernel
The SD/eMMC controllers reach the DRAM through a pipeline stage that
the hardware design inserts in the bus path to the NIC_MATRIX fabric,
clocked by CLKID_SYS_AMPIPE_NAND. When that clock is disabled, a
controller that starts a DMA transfer can never complete it.
Reference the clock from the three MMC controller nodes so the driver
keeps it running, instead of relying on the clock being marked critical
in the clock controller.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Lucas Tanure <tanure@linux.com>
---
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index c3dc479b137d..dbb4a95652c6 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -730,8 +730,9 @@ sd_emmc_a: mmc@88000 {
interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_A>,
<&clkc_periphs CLKID_SD_EMMC_A>,
- <&scmi_clk CLKID_FCLK_DIV2>;
- clock-names = "core", "clkin0", "clkin1";
+ <&scmi_clk CLKID_FCLK_DIV2>,
+ <&clkc_periphs CLKID_SYS_AMPIPE_NAND>;
+ clock-names = "core", "clkin0", "clkin1", "pipeline";
resets = <&reset RESET_SD_EMMC_A>;
assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_A_SEL>;
assigned-clock-parents = <&xtal>;
@@ -744,8 +745,9 @@ sd_emmc_b: mmc@8a000 {
interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>;
clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_B>,
<&clkc_periphs CLKID_SD_EMMC_B>,
- <&scmi_clk CLKID_FCLK_DIV2>;
- clock-names = "core", "clkin0", "clkin1";
+ <&scmi_clk CLKID_FCLK_DIV2>,
+ <&clkc_periphs CLKID_SYS_AMPIPE_NAND>;
+ clock-names = "core", "clkin0", "clkin1", "pipeline";
resets = <&reset RESET_SD_EMMC_B>;
assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_B_SEL>;
assigned-clock-parents = <&xtal>;
@@ -758,8 +760,9 @@ sd_emmc_c: mmc@8c000 {
interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_C>,
<&clkc_periphs CLKID_SD_EMMC_C>,
- <&scmi_clk CLKID_FCLK_DIV2>;
- clock-names = "core", "clkin0", "clkin1";
+ <&scmi_clk CLKID_FCLK_DIV2>,
+ <&clkc_periphs CLKID_SYS_AMPIPE_NAND>;
+ clock-names = "core", "clkin0", "clkin1", "pipeline";
resets = <&reset RESET_SD_EMMC_C>;
assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_C_SEL>;
assigned-clock-parents = <&xtal>;
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v2 4/4] clk: meson: t7: don't mark sys_ampipe_nand as critical
2026-09-05 15:32 [PATCH v2 0/4] amlogic: t7: give the MMC bus pipeline clock real consumers Lucas Tanure
` (2 preceding siblings ...)
2026-09-05 15:32 ` [PATCH v2 3/4] arm64: dts: amlogic: t7: add the pipeline clock to the MMC controllers Lucas Tanure
@ 2026-09-05 15:32 ` Lucas Tanure
3 siblings, 0 replies; 5+ messages in thread
From: Lucas Tanure @ 2026-09-05 15:32 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Neil Armstrong, Jerome Brunet, Kevin Hilman, Martin Blumenstingl,
Stephen Boyd
Cc: Brian Masney, Chuan Liu, Jian Hu, Ronald Claveau, linux-mmc,
devicetree, linux-arm-kernel, linux-amlogic, linux-clk,
linux-kernel
sys_ampipe_nand clocks the pipeline stage inserted in the bus path
between the SD/eMMC controllers and the NIC_MATRIX fabric. It does have
identifiable consumers - the three MMC controllers - so marking it
critical was the wrong tool: the clock should be referenced from the
consumer nodes and claimed by the mmc driver instead.
Drop the CLK_IS_CRITICAL flag and update the comment accordingly.
sys_am2axi0..2 remain critical as they clock the AXI DMA bus itself and
have no single identifiable consumer.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Lucas Tanure <tanure@linux.com>
---
This patch depends on the MMC controllers actually referencing the clock:
the dt-bindings, mmc driver and t7 DTS changes adding the "pipeline"
clock must land before this patch, otherwise the boot hangs and memory
corruption this clock caused are reintroduced.
drivers/clk/meson/t7-peripherals.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/meson/t7-peripherals.c b/drivers/clk/meson/t7-peripherals.c
index 55d09e78593b..2f429ea86796 100644
--- a/drivers/clk/meson/t7-peripherals.c
+++ b/drivers/clk/meson/t7-peripherals.c
@@ -945,13 +945,13 @@ static T7_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14, 0);
static T7_SYS_PCLK(sys_cec, SYS_CLK_EN0_REG0, 16, 0);
static T7_SYS_PCLK(sys_gdc, SYS_CLK_EN0_REG0, 17, 0);
static T7_SYS_PCLK(sys_deswarp, SYS_CLK_EN0_REG0, 18, 0);
+static T7_SYS_PCLK(sys_ampipe_nand, SYS_CLK_EN0_REG0, 19, 0);
+static T7_SYS_PCLK(sys_ampipe_eth, SYS_CLK_EN0_REG0, 20, 0);
/*
- * NOTE: sys_ampipe_nand and sys_am2axi0..2 provide the clock to the AXI bus
- * used for DMA between the peripherals and the DRAM. After the clocks are
- * disabled, a device that starts a transfer cannot complete it.
+ * NOTE: sys_am2axi0..2 provide the clock to the AXI bus used for DMA between
+ * the peripherals and the DRAM. After the clocks are disabled, a device that
+ * starts a transfer cannot complete it.
*/
-static T7_SYS_PCLK(sys_ampipe_nand, SYS_CLK_EN0_REG0, 19, CLK_IS_CRITICAL);
-static T7_SYS_PCLK(sys_ampipe_eth, SYS_CLK_EN0_REG0, 20, 0);
static T7_SYS_PCLK(sys_am2axi0, SYS_CLK_EN0_REG0, 21, CLK_IS_CRITICAL);
static T7_SYS_PCLK(sys_am2axi1, SYS_CLK_EN0_REG0, 22, CLK_IS_CRITICAL);
static T7_SYS_PCLK(sys_am2axi2, SYS_CLK_EN0_REG0, 23, CLK_IS_CRITICAL);
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread