* [PATCH v3 9/9] ARM: dts: mediatek: mt7623n-bananapi-bpi-r2: add HDMI audio machine node
From: Daniel Golle @ 2026-04-24 2:50 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Instantiate the mediatek,mt2701-hdmi-audio machine on the
BananaPi BPI-R2, binding the AFE HDMI playback path to the
on-chip HDMI transmitter acting as the generic HDMI codec.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
index a37f3fa223c7..139a76764faa 100644
--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
@@ -132,6 +132,13 @@ memory@80000000 {
device_type = "memory";
reg = <0 0x80000000 0 0x80000000>;
};
+
+ sound-hdmi {
+ compatible = "mediatek,mt7623n-hdmi-audio",
+ "mediatek,mt2701-hdmi-audio";
+ mediatek,platform = <&afe>;
+ mediatek,audio-codec = <&hdmi0>;
+ };
};
&bls {
--
2.54.0
^ permalink raw reply related
* [PATCH v3 8/9] ARM: dts: mediatek: mt7623: wire HDMI audio path clocks into AFE
From: Daniel Golle @ 2026-04-24 2:50 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Mirror the MT2701 change for the MT7623 SoC dtsi: add HADDS2PLL,
audio_hdmi, audio_spdf and audio_apll to the AFE clocks list and
reparent the AUDPLL mux to HADDS2PLL_98M. Required for HDMI audio
on MT7623N boards via the shared mt2701 AFE driver.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
arch/arm/boot/dts/mediatek/mt7623.dtsi | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi
index 71ac2b94c6ba..4eb028ffee6f 100644
--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi
@@ -665,7 +665,11 @@ afe: audio-controller {
<&audsys CLK_AUD_AFE_CONN>,
<&audsys CLK_AUD_A1SYS>,
<&audsys CLK_AUD_A2SYS>,
- <&audsys CLK_AUD_AFE_MRGIF>;
+ <&audsys CLK_AUD_AFE_MRGIF>,
+ <&topckgen CLK_TOP_HADDS2PLL_294M>,
+ <&audsys CLK_AUD_HDMI>,
+ <&audsys CLK_AUD_SPDF>,
+ <&audsys CLK_AUD_APLL>;
clock-names = "infra_sys_audio_clk",
"top_audio_mux1_sel",
@@ -700,15 +704,22 @@ afe: audio-controller {
"audio_afe_conn_pd",
"audio_a1sys_pd",
"audio_a2sys_pd",
- "audio_mrgif_pd";
+ "audio_mrgif_pd",
+ "hadds2pll_294m",
+ "audio_hdmi_pd",
+ "audio_spdf_pd",
+ "audio_apll_pd";
assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
<&topckgen CLK_TOP_AUD_MUX2_SEL>,
<&topckgen CLK_TOP_AUD_MUX1_DIV>,
- <&topckgen CLK_TOP_AUD_MUX2_DIV>;
+ <&topckgen CLK_TOP_AUD_MUX2_DIV>,
+ <&topckgen CLK_TOP_AUDPLL_MUX_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>,
- <&topckgen CLK_TOP_AUD2PLL_90M>;
- assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
+ <&topckgen CLK_TOP_AUD2PLL_90M>,
+ <0>, <0>,
+ <&topckgen CLK_TOP_HADDS2PLL_98M>;
+ assigned-clock-rates = <0>, <0>, <49152000>, <45158400>, <0>;
};
};
--
2.54.0
^ permalink raw reply related
* [PATCH v3 7/9] ARM: dts: mediatek: mt2701: wire HDMI audio path clocks into AFE
From: Daniel Golle @ 2026-04-24 2:50 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Add the HADDS2 PLL 294 MHz root, the audio_hdmi and audio_spdf
interface gates and the audio_apll gate to the MT2701 AFE node,
and reparent the AUDPLL mux to HADDS2PLL_98M so the HDMI audio
serial clock path has a stable 294.912 MHz source. The clock
names match the updated mediatek,mt2701-audio binding.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
arch/arm/boot/dts/mediatek/mt2701.dtsi | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/mediatek/mt2701.dtsi b/arch/arm/boot/dts/mediatek/mt2701.dtsi
index 128b87229f3d..80c8c7e6a422 100644
--- a/arch/arm/boot/dts/mediatek/mt2701.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt2701.dtsi
@@ -464,7 +464,11 @@ afe: audio-controller {
<&audsys CLK_AUD_AFE_CONN>,
<&audsys CLK_AUD_A1SYS>,
<&audsys CLK_AUD_A2SYS>,
- <&audsys CLK_AUD_AFE_MRGIF>;
+ <&audsys CLK_AUD_AFE_MRGIF>,
+ <&topckgen CLK_TOP_HADDS2PLL_294M>,
+ <&audsys CLK_AUD_HDMI>,
+ <&audsys CLK_AUD_SPDF>,
+ <&audsys CLK_AUD_APLL>;
clock-names = "infra_sys_audio_clk",
"top_audio_mux1_sel",
@@ -499,15 +503,22 @@ afe: audio-controller {
"audio_afe_conn_pd",
"audio_a1sys_pd",
"audio_a2sys_pd",
- "audio_mrgif_pd";
+ "audio_mrgif_pd",
+ "hadds2pll_294m",
+ "audio_hdmi_pd",
+ "audio_spdf_pd",
+ "audio_apll_pd";
assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
<&topckgen CLK_TOP_AUD_MUX2_SEL>,
<&topckgen CLK_TOP_AUD_MUX1_DIV>,
- <&topckgen CLK_TOP_AUD_MUX2_DIV>;
+ <&topckgen CLK_TOP_AUD_MUX2_DIV>,
+ <&topckgen CLK_TOP_AUDPLL_MUX_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>,
- <&topckgen CLK_TOP_AUD2PLL_90M>;
- assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
+ <&topckgen CLK_TOP_AUD2PLL_90M>,
+ <0>, <0>,
+ <&topckgen CLK_TOP_HADDS2PLL_98M>;
+ assigned-clock-rates = <0>, <0>, <49152000>, <45158400>, <0>;
};
};
--
2.54.0
^ permalink raw reply related
* [PATCH v3 6/9] ASoC: mediatek: mt2701: add machine driver for on-chip HDMI codec
From: Daniel Golle @ 2026-04-24 2:50 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Add a simple ASoC machine driver that wires the MT2701/MT7623N
AFE HDMI playback path to the on-chip HDMI transmitter exposed
as a generic hdmi-audio-codec "i2s-hifi" DAI.
The driver binds to "mediatek,mt2701-hdmi-audio". MT7623N device
trees carry "mediatek,mt7623n-hdmi-audio" as a board-specific
fallback, matching the dt-binding.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
sound/soc/mediatek/Kconfig | 10 +++
sound/soc/mediatek/mt2701/Makefile | 1 +
sound/soc/mediatek/mt2701/mt2701-hdmi.c | 114 ++++++++++++++++++++++++
3 files changed, 125 insertions(+)
create mode 100644 sound/soc/mediatek/mt2701/mt2701-hdmi.c
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3a1e1fa3fe5c..fa076e7854ad 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -26,6 +26,16 @@ config SND_SOC_MT2701_CS42448
Select Y if you have such device.
If unsure select "N".
+config SND_SOC_MT2701_HDMI
+ tristate "ASoC Audio driver for MT2701 with on-chip HDMI codec"
+ depends on SND_SOC_MT2701
+ select SND_SOC_HDMI_CODEC
+ help
+ This adds the ASoC machine driver for MediaTek MT2701 and
+ MT7623N boards routing the AFE I2S back-end to the on-chip
+ HDMI transmitter via the generic HDMI codec.
+ If unsure select "N".
+
config SND_SOC_MT2701_WM8960
tristate "ASoc Audio driver for MT2701 with WM8960 codec"
depends on SND_SOC_MT2701 && I2C
diff --git a/sound/soc/mediatek/mt2701/Makefile b/sound/soc/mediatek/mt2701/Makefile
index 507fa26c3945..59623d3d3a03 100644
--- a/sound/soc/mediatek/mt2701/Makefile
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
# machine driver
obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
+obj-$(CONFIG_SND_SOC_MT2701_HDMI) += mt2701-hdmi.o
obj-$(CONFIG_SND_SOC_MT2701_WM8960) += mt2701-wm8960.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-hdmi.c b/sound/soc/mediatek/mt2701/mt2701-hdmi.c
new file mode 100644
index 000000000000..a84907879c04
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-hdmi.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt2701-hdmi.c -- MT2701 HDMI ALSA SoC machine driver
+ *
+ * Copyright (c) 2026 Daniel Golle <daniel@makrotopia.org>
+ *
+ * Based on mt2701-cs42448.c
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <sound/soc.h>
+
+enum {
+ DAI_LINK_FE_HDMI_OUT,
+ DAI_LINK_BE_HDMI_I2S,
+};
+
+SND_SOC_DAILINK_DEFS(fe_hdmi_out,
+ DAILINK_COMP_ARRAY(COMP_CPU("PCM_HDMI")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(be_hdmi_i2s,
+ DAILINK_COMP_ARRAY(COMP_CPU("HDMI I2S")),
+ DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+static struct snd_soc_dai_link mt2701_hdmi_dai_links[] = {
+ [DAI_LINK_FE_HDMI_OUT] = {
+ .name = "HDMI Playback",
+ .stream_name = "HDMI Playback",
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .dynamic = 1,
+ .playback_only = 1,
+ SND_SOC_DAILINK_REG(fe_hdmi_out),
+ },
+ [DAI_LINK_BE_HDMI_I2S] = {
+ .name = "HDMI BE",
+ .no_pcm = 1,
+ .playback_only = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ SND_SOC_DAILINK_REG(be_hdmi_i2s),
+ },
+};
+
+static struct snd_soc_card mt2701_hdmi_soc_card = {
+ .name = "mt2701-hdmi",
+ .owner = THIS_MODULE,
+ .dai_link = mt2701_hdmi_dai_links,
+ .num_links = ARRAY_SIZE(mt2701_hdmi_dai_links),
+};
+
+static int mt2701_hdmi_machine_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &mt2701_hdmi_soc_card;
+ struct device *dev = &pdev->dev;
+ struct device_node *platform_node;
+ struct device_node *codec_node;
+ struct snd_soc_dai_link *dai_link;
+ int ret;
+ int i;
+
+ platform_node = of_parse_phandle(dev->of_node, "mediatek,platform", 0);
+ if (!platform_node)
+ return dev_err_probe(dev, -EINVAL,
+ "Property 'mediatek,platform' missing\n");
+
+ for_each_card_prelinks(card, i, dai_link) {
+ if (dai_link->platforms->name)
+ continue;
+ dai_link->platforms->of_node = platform_node;
+ }
+
+ codec_node = of_parse_phandle(dev->of_node, "mediatek,audio-codec", 0);
+ if (!codec_node) {
+ of_node_put(platform_node);
+ return dev_err_probe(dev, -EINVAL,
+ "Property 'mediatek,audio-codec' missing\n");
+ }
+ mt2701_hdmi_dai_links[DAI_LINK_BE_HDMI_I2S].codecs->of_node = codec_node;
+
+ card->dev = dev;
+
+ ret = devm_snd_soc_register_card(dev, card);
+
+ of_node_put(platform_node);
+ of_node_put(codec_node);
+ return ret;
+}
+
+static const struct of_device_id mt2701_hdmi_machine_dt_match[] = {
+ { .compatible = "mediatek,mt2701-hdmi-audio" },
+ { .compatible = "mediatek,mt7623n-hdmi-audio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mt2701_hdmi_machine_dt_match);
+
+static struct platform_driver mt2701_hdmi_machine = {
+ .driver = {
+ .name = "mt2701-hdmi",
+ .of_match_table = mt2701_hdmi_machine_dt_match,
+ },
+ .probe = mt2701_hdmi_machine_probe,
+};
+module_platform_driver(mt2701_hdmi_machine);
+
+MODULE_DESCRIPTION("MT2701 HDMI ALSA SoC machine driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mt2701-hdmi");
--
2.54.0
^ permalink raw reply related
* [PATCH v3 5/9] ASoC: mediatek: mt2701: add HDMI audio memif, FE and BE DAIs
From: Daniel Golle @ 2026-04-24 2:50 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Extend the MT2701/MT7623N AFE driver with the HDMI playback path:
- a new HDMI DMA memif (MT2701_MEMIF_HDMI) mapped to the
AFE_HDMI_OUT_{CON0,BASE,CUR,END} registers;
- a PCM_HDMI front-end DAI (S16_LE only, 44.1k/48k) which feeds
the memif via DPCM;
- an HDMI BE DAI wrapping the AFE_8CH_I2S_OUT_CON engine that
serialises L/R samples towards the on-chip HDMI transmitter.
Sample-rate programming uses the empirically determined
HDMI_BCK_DIV = 45 * 48000 / rate - 1 formula in AUDIO_TOP_CON3,
which covers 44.1 kHz and 48 kHz within the 6-bit divider range.
The AFE_HDMI_CONN0 interconnect is programmed to route memif
output pairs to the serializer inputs with L/R in the right order
for hdmi-audio-codec.
The existing I2S engine helpers (mt2701_mclk_configuration,
mt2701_i2s_path_enable, mt2701_afe_i2s_path_disable) are reused
for the HDMI BE so that MCLK at 128*fs and the ASYS I2S3 FS field
are programmed and cleanly released across open/close cycles.
Only S16_LE and 44.1k/48k are exposed to userspace. Other rates
fall outside the 6-bit BCK divider range, and wider sample
formats require DMA BIT_WIDTH programming that the current memif
setup does not handle. These limits match what the MT8173 AFE
driver exposes for its HDMI path.
The HDMI-related AFE registers (AUDIO_TOP_CON3, AFE_HDMI_OUT_CON0,
AFE_HDMI_CONN0, AFE_8CH_I2S_OUT_CON) are added to the suspend
backup list so that the existing mtk_afe_suspend/resume framework
saves and restores them across system sleep cycles.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3:
* remove redundant clock un-gating via regmap access
v2:
* use named masks and explicitly set BIT_WIDTH_16 when
programming AFE_HDMI_OUT_CON0 channel count (Mark Brown)
* add AUDIO_TOP_CON3, AFE_HDMI_OUT_CON0, AFE_HDMI_CONN0,
AFE_8CH_I2S_OUT_CON to suspend/resume backup list
(Mark Brown)
sound/soc/mediatek/mt2701/mt2701-afe-common.h | 2 +
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 284 +++++++++++++++++-
2 files changed, 285 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
index 7b15283d6351..8b6f3a200048 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
@@ -33,6 +33,7 @@ enum {
MT2701_MEMIF_UL5,
MT2701_MEMIF_DLBT,
MT2701_MEMIF_ULBT,
+ MT2701_MEMIF_HDMI,
MT2701_MEMIF_NUM,
MT2701_IO_I2S = MT2701_MEMIF_NUM,
MT2701_IO_2ND_I2S,
@@ -41,6 +42,7 @@ enum {
MT2701_IO_5TH_I2S,
MT2701_IO_6TH_I2S,
MT2701_IO_MRG,
+ MT2701_IO_HDMI,
};
enum {
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index fcae38135d93..bb459faa6e05 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -13,6 +13,7 @@
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
+#include <sound/pcm_params.h>
#include "mt2701-afe-common.h"
#include "mt2701-afe-clock-ctrl.h"
@@ -60,6 +61,7 @@ static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
static const unsigned int mt2701_afe_backup_list[] = {
AUDIO_TOP_CON0,
+ AUDIO_TOP_CON3,
AUDIO_TOP_CON4,
AUDIO_TOP_CON5,
ASYS_TOP_CON,
@@ -77,6 +79,9 @@ static const unsigned int mt2701_afe_backup_list[] = {
AFE_CONN22,
AFE_DAC_CON0,
AFE_MEMIF_PBUF_SIZE,
+ AFE_HDMI_OUT_CON0,
+ AFE_HDMI_CONN0,
+ AFE_8CH_I2S_OUT_CON,
};
static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
@@ -542,6 +547,220 @@ static const struct snd_soc_dai_ops mt2701_btmrg_ops = {
.hw_params = mt2701_btmrg_hw_params,
};
+/*
+ * HDMI BE DAI -- drives the on-SoC 8-channel I2S engine whose output
+ * feeds the HDMI transmitter audio port.
+ *
+ * The HDMI audio hardware path is:
+ * HDMI memif DMA (AFE_HDMI_OUT_*) -> interconnect mux (AFE_HDMI_CONN0)
+ * -> 8-channel I2S engine (AFE_8CH_I2S_OUT_CON) -> HDMI TX audio port
+ *
+ * The I2S3 clock tree provides the bit/master clocks; we set its
+ * mclk_rate to 128*fs (matching HDMI_AUD_MCLK_128FS) and let
+ * mt2701_mclk_configuration program the PLL/divider path.
+ */
+#define MT2701_HDMI_I2S_PATH 3
+
+static int mt2701_afe_hdmi_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ int ret;
+
+ if (!afe_priv->hadds2pll_ck || !afe_priv->audio_hdmi_ck) {
+ dev_err(afe->dev, "HDMI audio clocks not available\n");
+ return -ENODEV;
+ }
+
+ ret = clk_prepare_enable(afe_priv->hadds2pll_ck);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(afe_priv->audio_hdmi_ck);
+ if (ret)
+ goto err_hdmi;
+
+ if (afe_priv->audio_spdf_ck) {
+ ret = clk_prepare_enable(afe_priv->audio_spdf_ck);
+ if (ret)
+ goto err_spdf;
+ }
+
+ if (afe_priv->audio_apll_ck) {
+ ret = clk_prepare_enable(afe_priv->audio_apll_ck);
+ if (ret)
+ goto err_apll;
+ }
+
+ ret = mt2701_afe_enable_mclk(afe, MT2701_HDMI_I2S_PATH);
+ if (ret)
+ goto err_mclk;
+
+ return 0;
+
+err_mclk:
+ if (afe_priv->audio_apll_ck)
+ clk_disable_unprepare(afe_priv->audio_apll_ck);
+err_apll:
+ if (afe_priv->audio_spdf_ck)
+ clk_disable_unprepare(afe_priv->audio_spdf_ck);
+err_spdf:
+ clk_disable_unprepare(afe_priv->audio_hdmi_ck);
+err_hdmi:
+ clk_disable_unprepare(afe_priv->hadds2pll_ck);
+ return ret;
+}
+
+static void mt2701_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+ mt2701_afe_disable_mclk(afe, MT2701_HDMI_I2S_PATH);
+ if (afe_priv->audio_apll_ck)
+ clk_disable_unprepare(afe_priv->audio_apll_ck);
+ if (afe_priv->audio_spdf_ck)
+ clk_disable_unprepare(afe_priv->audio_spdf_ck);
+ clk_disable_unprepare(afe_priv->audio_hdmi_ck);
+ clk_disable_unprepare(afe_priv->hadds2pll_ck);
+}
+
+static int mt2701_afe_hdmi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ unsigned int channels = params_channels(params);
+ unsigned int rate = params_rate(params);
+ unsigned int divp1;
+ unsigned int val;
+ unsigned int i;
+ int ret;
+
+ /*
+ * Compute AUDIO_TOP_CON3.HDMI_BCK_DIV up front. The divider
+ * drives an internal reference for the HDMI transmitter's
+ * audio packet engine; it must scale with the sample rate so
+ * that the packet engine's timing matches the data flowing in
+ * from the AFE memif/I2S3 side. Empirically, with audpll_sel
+ * parented to hadds2pll_98m (98.304 MHz), the correct value at
+ * 48 kHz is div = 44 (i.e. (div+1) = 45), giving 1.0923 MHz.
+ * Scaling inversely with rate: (div + 1) = 45 * 48000 / rate.
+ * Integer rounding introduces small (<1%) errors at 32 kHz;
+ * 44.1 kHz is nearly exact via round-to-nearest. Reject rates
+ * that fall outside the 6-bit divider range before touching
+ * any hardware so no side effects are left behind on error.
+ */
+ divp1 = (45U * 48000U + rate / 2) / rate;
+ if (divp1 == 0 || divp1 > 64)
+ return -EINVAL;
+
+ /*
+ * Park the I2S3 clock tree at 128*fs -- this is the MCLK that
+ * the ASYS I2S3 engine uses to derive its BCK/LRCK. The engine
+ * outputs BCK = 64*fs (stereo, 32-bit word length).
+ */
+ afe_priv->i2s_path[MT2701_HDMI_I2S_PATH].mclk_rate = rate * 128;
+ ret = mt2701_mclk_configuration(afe, MT2701_HDMI_I2S_PATH);
+ if (ret)
+ return ret;
+
+ /* Program and start the ASYS I2S3 engine (FS, I2S mode, enable). */
+ mt2701_i2s_path_enable(afe,
+ &afe_priv->i2s_path[MT2701_HDMI_I2S_PATH],
+ SNDRV_PCM_STREAM_PLAYBACK, rate);
+
+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON3,
+ AUDIO_TOP_CON3_HDMI_BCK_DIV_MASK,
+ AUDIO_TOP_CON3_HDMI_BCK_DIV(divp1 - 1));
+
+ /*
+ * HDMI output memif: set channel count and confirm 16-bit
+ * sample width. Both fields must be written together so that
+ * stale reset-default or prior-stream values in BIT_WIDTH
+ * cannot persist.
+ */
+ regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
+ AFE_HDMI_OUT_CON0_CH_NUM_MASK |
+ AFE_HDMI_OUT_CON0_BIT_WIDTH_MASK,
+ AFE_HDMI_OUT_CON0_CH_NUM(channels) |
+ AFE_HDMI_OUT_CON0_BIT_WIDTH_16);
+
+ /*
+ * Interconnect mux -- map DMA input slots to HDMI output slots.
+ * Each output takes a 3-bit field at shift (i*3). Swap the first
+ * two inputs so that the DMA's interleaved L/R pair lands on the
+ * correct HDMI L/R output slots. Remaining slots are identity.
+ */
+ val = (1 << 0) | (0 << 3); /* O20 <- I21, O21 <- I20 */
+ for (i = 2; i < 8; i++)
+ val |= ((i & 0x7) << (i * 3));
+ regmap_write(afe->regmap, AFE_HDMI_CONN0, val);
+
+ /*
+ * 8-channel I2S framing: standard I2S, 32-bit slots,
+ * LRCK/BCK inverted. The wire protocol is fixed.
+ */
+ regmap_update_bits(afe->regmap, AFE_8CH_I2S_OUT_CON,
+ AFE_8CH_I2S_OUT_CON_WLEN_MASK |
+ AFE_8CH_I2S_OUT_CON_I2S_DELAY |
+ AFE_8CH_I2S_OUT_CON_LRCK_INV |
+ AFE_8CH_I2S_OUT_CON_BCK_INV,
+ AFE_8CH_I2S_OUT_CON_WLEN_32BIT |
+ AFE_8CH_I2S_OUT_CON_I2S_DELAY |
+ AFE_8CH_I2S_OUT_CON_LRCK_INV |
+ AFE_8CH_I2S_OUT_CON_BCK_INV);
+ return 0;
+}
+
+static int mt2701_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ /* Enable HDMI output memif. */
+ regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0x1);
+ /* Enable 8-channel I2S engine. */
+ regmap_update_bits(afe->regmap, AFE_8CH_I2S_OUT_CON,
+ AFE_8CH_I2S_OUT_CON_EN,
+ AFE_8CH_I2S_OUT_CON_EN);
+ return 0;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ regmap_update_bits(afe->regmap, AFE_8CH_I2S_OUT_CON,
+ AFE_8CH_I2S_OUT_CON_EN, 0);
+ regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int mt2701_afe_hdmi_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+ mt2701_afe_i2s_path_disable(afe,
+ &afe_priv->i2s_path[MT2701_HDMI_I2S_PATH],
+ SNDRV_PCM_STREAM_PLAYBACK);
+ return 0;
+}
+
+static const struct snd_soc_dai_ops mt2701_afe_hdmi_ops = {
+ .startup = mt2701_afe_hdmi_startup,
+ .shutdown = mt2701_afe_hdmi_shutdown,
+ .hw_params = mt2701_afe_hdmi_hw_params,
+ .hw_free = mt2701_afe_hdmi_hw_free,
+ .trigger = mt2701_afe_hdmi_trigger,
+};
+
static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
/* FE DAIs: memory intefaces to CPU */
{
@@ -628,6 +847,19 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
},
.ops = &mt2701_single_memif_dai_ops,
},
+ {
+ .name = "PCM_HDMI",
+ .id = MT2701_MEMIF_HDMI,
+ .playback = {
+ .stream_name = "HDMI Multich",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = (SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+ .ops = &mt2701_single_memif_dai_ops,
+ },
/* BE DAIs */
{
.name = "I2S0",
@@ -748,7 +980,20 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
},
.ops = &mt2701_btmrg_ops,
.symmetric_rate = 1,
- }
+ },
+ {
+ .name = "HDMI I2S",
+ .id = MT2701_IO_HDMI,
+ .playback = {
+ .stream_name = "HDMI 8CH I2S Playback",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = (SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+ .ops = &mt2701_afe_hdmi_ops,
+ },
};
static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {
@@ -927,6 +1172,14 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
{"I16I17", "Multich I2S2 Out Switch", "DLM"},
{"I18I19", "Multich I2S3 Out Switch", "DLM"},
+ /*
+ * HDMI FE -> BE direct route. The HDMI memif has its own DMA
+ * path that feeds the 8-channel internal I2S straight into the
+ * HDMI transmitter; no mixer/interconnect selection is exposed
+ * to the user.
+ */
+ {"HDMI 8CH I2S Playback", NULL, "HDMI Multich"},
+
{ "I12", NULL, "I12I13" },
{ "I13", NULL, "I12I13" },
{ "I14", NULL, "I14I15" },
@@ -1207,6 +1460,35 @@ static const struct mtk_base_memif_data memif_data_array[MT2701_MEMIF_NUM] = {
.agent_disable_shift = 16,
.msb_reg = -1,
},
+ {
+ /*
+ * HDMI memif feeds the on-SoC 8-channel internal I2S that
+ * drives the HDMI transmitter audio port. Unlike the
+ * standard memifs, the enable bit, channel count and bit
+ * width all live in AFE_HDMI_OUT_CON0, so mono/fs/hd/agent
+ * fields are left at -1 and programmed from the BE DAI ops
+ * instead.
+ */
+ .name = "HDMI",
+ .id = MT2701_MEMIF_HDMI,
+ .reg_ofs_base = AFE_HDMI_OUT_BASE,
+ .reg_ofs_cur = AFE_HDMI_OUT_CUR,
+ .reg_ofs_end = AFE_HDMI_OUT_END,
+ .fs_reg = -1,
+ .fs_shift = -1,
+ .fs_maskbit = 0,
+ .mono_reg = -1,
+ .mono_shift = -1,
+ .enable_reg = AFE_HDMI_OUT_CON0,
+ .enable_shift = 0,
+ .hd_reg = -1,
+ .hd_shift = -1,
+ .hd_align_reg = -1,
+ .hd_align_mshift = 0,
+ .agent_disable_reg = -1,
+ .agent_disable_shift = 0,
+ .msb_reg = -1,
+ },
};
static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
--
2.54.0
^ permalink raw reply related
* [PATCH v3 4/9] ASoC: mediatek: mt2701: add optional HDMI audio path clocks
From: Daniel Golle @ 2026-04-24 2:49 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
The HDMI audio output path on MT2701/MT7623N is rooted in HADDS2PLL
and gated by the audio_hdmi, audio_spdf and audio_apll power gates.
Acquire these four clocks from device tree using devm_clk_get_optional
so that existing platforms which do not wire up HDMI audio keep
probing unchanged. Actual clock enable/prepare is deferred to the
upcoming HDMI DAI startup path.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: no changes
.../mediatek/mt2701/mt2701-afe-clock-ctrl.c | 22 +++++++++++++++++++
sound/soc/mediatek/mt2701/mt2701-afe-common.h | 4 ++++
2 files changed, 26 insertions(+)
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
index ae620890bb3a..5a2bcf027b4f 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -95,6 +95,28 @@ int mt2701_init_clock(struct mtk_base_afe *afe)
afe_priv->mrgif_ck = NULL;
}
+ /*
+ * Optional HDMI audio clocks. Platforms that do not wire up the
+ * HDMI output (e.g. MT2701 devkits using only the I2S BE DAIs)
+ * may omit these; in that case the HDMI BE DAI simply cannot be
+ * enabled, but the rest of the AFE still probes.
+ */
+ afe_priv->hadds2pll_ck = devm_clk_get_optional(afe->dev, "hadds2pll_294m");
+ if (IS_ERR(afe_priv->hadds2pll_ck))
+ return PTR_ERR(afe_priv->hadds2pll_ck);
+
+ afe_priv->audio_hdmi_ck = devm_clk_get_optional(afe->dev, "audio_hdmi_pd");
+ if (IS_ERR(afe_priv->audio_hdmi_ck))
+ return PTR_ERR(afe_priv->audio_hdmi_ck);
+
+ afe_priv->audio_spdf_ck = devm_clk_get_optional(afe->dev, "audio_spdf_pd");
+ if (IS_ERR(afe_priv->audio_spdf_ck))
+ return PTR_ERR(afe_priv->audio_spdf_ck);
+
+ afe_priv->audio_apll_ck = devm_clk_get_optional(afe->dev, "audio_apll_pd");
+ if (IS_ERR(afe_priv->audio_apll_ck))
+ return PTR_ERR(afe_priv->audio_apll_ck);
+
return 0;
}
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
index 32bef5e2a56d..7b15283d6351 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
@@ -90,6 +90,10 @@ struct mt2701_afe_private {
struct mt2701_i2s_path *i2s_path;
struct clk *base_ck[MT2701_BASE_CLK_NUM];
struct clk *mrgif_ck;
+ struct clk *hadds2pll_ck;
+ struct clk *audio_hdmi_ck;
+ struct clk *audio_spdf_ck;
+ struct clk *audio_apll_ck;
bool mrg_enable[MTK_STREAM_NUM];
const struct mt2701_soc_variants *soc;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 3/9] ASoC: mediatek: mt2701: add AFE HDMI register definitions
From: Daniel Golle @ 2026-04-24 2:49 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Add register offsets and bit defines for the MT2701/MT7623N AFE
HDMI audio output path: the HDMI BCK divider in AUDIO_TOP_CON3,
the HDMI output memif control and descriptor registers, the 8-bit
AFE_HDMI_CONN0 interconnect, and the AFE_8CH_I2S_OUT_CON engine
that drives the HDMI TX serial link. These are a prerequisite for
adding an HDMI playback path to the mt2701 AFE driver and have no
behavioural effect on their own.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: remove now unused clk bits
v2: no changes
sound/soc/mediatek/mt2701/mt2701-reg.h | 29 ++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h
index c84d14cdd7ae..ca914df02c96 100644
--- a/sound/soc/mediatek/mt2701/mt2701-reg.h
+++ b/sound/soc/mediatek/mt2701/mt2701-reg.h
@@ -10,10 +10,17 @@
#define _MT2701_REG_H_
#define AUDIO_TOP_CON0 0x0000
+#define AUDIO_TOP_CON3 0x000c
#define AUDIO_TOP_CON4 0x0010
#define AUDIO_TOP_CON5 0x0014
#define AFE_DAIBT_CON0 0x001c
#define AFE_MRGIF_CON 0x003c
+#define AFE_HDMI_OUT_CON0 0x0370
+#define AFE_HDMI_OUT_BASE 0x0374
+#define AFE_HDMI_OUT_CUR 0x0378
+#define AFE_HDMI_OUT_END 0x037c
+#define AFE_HDMI_CONN0 0x0390
+#define AFE_8CH_I2S_OUT_CON 0x0394
#define ASMI_TIMING_CON1 0x0100
#define ASMO_TIMING_CON1 0x0104
#define PWR1_ASM_CON1 0x0108
@@ -125,6 +132,28 @@
#define AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK (0x3 << 12)
#define AFE_MEMIF_PBUF_SIZE_DLM_32BYTES (0x1 << 12)
+/* AUDIO_TOP_CON3 (0x000c) -- HDMI BCK divider */
+#define AUDIO_TOP_CON3_HDMI_BCK_DIV_MASK (0x3f << 8)
+#define AUDIO_TOP_CON3_HDMI_BCK_DIV(x) (((x) & 0x3f) << 8)
+
+/* AFE_HDMI_OUT_CON0 (0x0370) */
+#define AFE_HDMI_OUT_CON0_OUT_ON (0x1 << 0)
+#define AFE_HDMI_OUT_CON0_BIT_WIDTH_MASK (0x1 << 1)
+#define AFE_HDMI_OUT_CON0_BIT_WIDTH_16 (0x0 << 1)
+#define AFE_HDMI_OUT_CON0_BIT_WIDTH_32 (0x1 << 1)
+#define AFE_HDMI_OUT_CON0_CH_NUM_MASK (0xf << 4)
+#define AFE_HDMI_OUT_CON0_CH_NUM(x) (((x) & 0xf) << 4)
+
+/* AFE_8CH_I2S_OUT_CON (0x0394) -- on-SoC 8-channel I2S that feeds HDMI TX */
+#define AFE_8CH_I2S_OUT_CON_EN (0x1 << 0)
+#define AFE_8CH_I2S_OUT_CON_BCK_INV (0x1 << 1)
+#define AFE_8CH_I2S_OUT_CON_LRCK_INV (0x1 << 2)
+#define AFE_8CH_I2S_OUT_CON_I2S_DELAY (0x1 << 3)
+#define AFE_8CH_I2S_OUT_CON_WLEN_MASK (0x3 << 4)
+#define AFE_8CH_I2S_OUT_CON_WLEN_16BIT (0x1 << 4)
+#define AFE_8CH_I2S_OUT_CON_WLEN_24BIT (0x2 << 4)
+#define AFE_8CH_I2S_OUT_CON_WLEN_32BIT (0x3 << 4)
+
/* I2S in/out register bit control */
#define ASYS_I2S_CON_FS (0x1f << 8)
#define ASYS_I2S_CON_FS_SET(x) ((x) << 8)
--
2.54.0
^ permalink raw reply related
* [PATCH v3 2/9] ASoC: dt-bindings: mediatek,mt2701-hdmi-audio: add MT2701 HDMI audio
From: Daniel Golle @ 2026-04-24 2:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Describe the sound card node that routes the MT2701/MT7623N AFE
HDMI playback path to the on-chip HDMI transmitter. This is
separate from the AFE platform binding (mediatek,mt2701-audio)
because it represents board-level audio routing between the AFE
and the HDMI codec, not an additional IP block. MT7623N boards
carry the same IP and use the mt7623n- compatible as a fallback
to mt2701-.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
v3: no changes
v2:
* Fix subject prefix to use schema filename (Krzysztof Kozlowski)
* Rewrite title and description to describe hardware, not driver
(Krzysztof Kozlowski)
* Clarify in commit message why this is a separate binding from
mediatek,mt2701-audio (Krzysztof Kozlowski)
.../sound/mediatek,mt2701-hdmi-audio.yaml | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt2701-hdmi-audio.yaml
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt2701-hdmi-audio.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt2701-hdmi-audio.yaml
new file mode 100644
index 000000000000..9d5a8166e51f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt2701-hdmi-audio.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mediatek,mt2701-hdmi-audio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT2701/MT7623N HDMI audio output
+
+maintainers:
+ - Daniel Golle <daniel@makrotopia.org>
+
+description:
+ Sound card routing the MT2701/MT7623N Audio Front End HDMI
+ playback path to the on-chip HDMI transmitter. The AFE
+ provides the DMA memif and internal I2S engine; the HDMI
+ transmitter acts as the audio codec on the serialised link.
+
+properties:
+ compatible:
+ oneOf:
+ - const: mediatek,mt2701-hdmi-audio
+ - items:
+ - const: mediatek,mt7623n-hdmi-audio
+ - const: mediatek,mt2701-hdmi-audio
+
+ mediatek,platform:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: Phandle of the MT2701/MT7623N AFE platform node.
+
+ mediatek,audio-codec:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: Phandle of the HDMI transmitter acting as audio codec.
+
+required:
+ - compatible
+ - mediatek,platform
+ - mediatek,audio-codec
+
+additionalProperties: false
+
+examples:
+ - |
+ sound-hdmi {
+ compatible = "mediatek,mt7623n-hdmi-audio",
+ "mediatek,mt2701-hdmi-audio";
+ mediatek,platform = <&afe>;
+ mediatek,audio-codec = <&hdmi0>;
+ };
--
2.54.0
^ permalink raw reply related
* [PATCH v3 1/9] ASoC: dt-bindings: mt2701-afe-pcm: add HDMI audio path clocks
From: Daniel Golle @ 2026-04-24 2:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <cover.1776998727.git.daniel@makrotopia.org>
Document four additional optional clocks feeding the HDMI audio
output path on MT2701: the HADDS2 PLL (root of the HDMI audio
clock tree), the HDMI audio and S/PDIF interface power gates,
and the audio APLL root gate. Older device trees that do not
wire these up remain valid via minItems. MT7622 does not have
HDMI audio hardware, so its compatible is restricted to the
base set of 34 clocks.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
v3: allOf goes before additionalProperties
v2:
* Restrict the four HDMI clocks to mediatek,mt2701-audio only
using an allOf/if/then conditional; MT7622 is capped at 34
clocks (Krzysztof Kozlowski)
.../bindings/sound/mediatek,mt2701-audio.yaml | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt2701-audio.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt2701-audio.yaml
index 45382c4d86aa..30f331366566 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt2701-audio.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt2701-audio.yaml
@@ -32,6 +32,7 @@ properties:
maxItems: 1
clocks:
+ minItems: 34
items:
- description: audio infra sys clock
- description: top audio mux 1
@@ -67,8 +68,13 @@ properties:
- description: top audio a1 sys pd
- description: top audio a2 sys pd
- description: audio merge interface pd
+ - description: HADDS2 PLL 294 MHz (HDMI audio path root)
+ - description: HDMI audio interface pd
+ - description: S/PDIF interface pd
+ - description: audio APLL root pd
clock-names:
+ minItems: 34
items:
- const: infra_sys_audio_clk
- const: top_audio_mux1_sel
@@ -104,6 +110,10 @@ properties:
- const: audio_a1sys_pd
- const: audio_a2sys_pd
- const: audio_mrgif_pd
+ - const: hadds2pll_294m
+ - const: audio_hdmi_pd
+ - const: audio_spdf_pd
+ - const: audio_apll_pd
required:
- compatible
@@ -113,4 +123,17 @@ required:
- clocks
- clock-names
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: mediatek,mt7622-audio
+ then:
+ properties:
+ clocks:
+ maxItems: 34
+ clock-names:
+ maxItems: 34
+
additionalProperties: false
--
2.54.0
^ permalink raw reply related
* [PATCH v3 0/9] ASoC: mediatek: mt2701: HDMI audio support
From: Daniel Golle @ 2026-04-24 2:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Jaroslav Kysela, Takashi Iwai, Cyril Chao, Arnd Bergmann,
Nícolas F. R. A. Prado, Kuninori Morimoto, Daniel Golle,
Eugen Hristev, linux-sound, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
This series wires up on-chip HDMI audio on MT2701 and MT7623N, from the
DRM bridge down through the AFE into a small machine driver that binds
the AFE HDMI BE to the HDMI TX codec already exposed by the
mediatek-drm-hdmi driver. Bindings, DT and a BananaPi R2 board node
are included.
In order to survive vblank or late hotplug of the monitor, the fix
submitted separately [1] is required as well.
Everything here was developed for and tested on a BananaPi R2
(MT7623N), which turns ten years old this year -- a nice occasion to
finally land HDMI audio for a SoC which was truly ahead of its time.
[1]: https://patchwork.kernel.org/project/linux-mediatek/patch/a3e22cbae528c9a38d854a586d1736b860998d41.1776265222.git.daniel@makrotopia.org/
Changes since v2:
* allOf goes before additionalProperties
* remove now unused clk bits
* remove redundant clock un-gating via regmap access
Changes since v1:
* Restrict the four HDMI clocks to mediatek,mt2701-audio only
using an allOf/if/then conditional; MT7622 is capped at 34
clocks (Krzysztof Kozlowski)
* Fix subject prefix to use schema filename (Krzysztof Kozlowski)
* Rewrite title and description to describe hardware, not driver
(Krzysztof Kozlowski)
* Clarify in commit message why this is a separate binding from
mediatek,mt2701-audio (Krzysztof Kozlowski)
* use named masks and explicitly set BIT_WIDTH_16 when
programming AFE_HDMI_OUT_CON0 channel count (Mark Brown)
* add AUDIO_TOP_CON3, AFE_HDMI_OUT_CON0, AFE_HDMI_CONN0,
AFE_8CH_I2S_OUT_CON to suspend/resume backup list
(Mark Brown)
Daniel Golle (9):
ASoC: dt-bindings: mt2701-afe-pcm: add HDMI audio path clocks
ASoC: dt-bindings: mediatek,mt2701-hdmi-audio: add MT2701 HDMI audio
ASoC: mediatek: mt2701: add AFE HDMI register definitions
ASoC: mediatek: mt2701: add optional HDMI audio path clocks
ASoC: mediatek: mt2701: add HDMI audio memif, FE and BE DAIs
ASoC: mediatek: mt2701: add machine driver for on-chip HDMI codec
ARM: dts: mediatek: mt2701: wire HDMI audio path clocks into AFE
ARM: dts: mediatek: mt7623: wire HDMI audio path clocks into AFE
ARM: dts: mediatek: mt7623n-bananapi-bpi-r2: add HDMI audio machine
node
.../bindings/sound/mediatek,mt2701-audio.yaml | 23 ++
.../sound/mediatek,mt2701-hdmi-audio.yaml | 48 +++
arch/arm/boot/dts/mediatek/mt2701.dtsi | 21 +-
arch/arm/boot/dts/mediatek/mt7623.dtsi | 21 +-
.../dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 7 +
sound/soc/mediatek/Kconfig | 10 +
sound/soc/mediatek/mt2701/Makefile | 1 +
.../mediatek/mt2701/mt2701-afe-clock-ctrl.c | 22 ++
sound/soc/mediatek/mt2701/mt2701-afe-common.h | 6 +
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 284 +++++++++++++++++-
sound/soc/mediatek/mt2701/mt2701-hdmi.c | 114 +++++++
sound/soc/mediatek/mt2701/mt2701-reg.h | 29 ++
12 files changed, 575 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt2701-hdmi-audio.yaml
create mode 100644 sound/soc/mediatek/mt2701/mt2701-hdmi.c
--
2.54.0
^ permalink raw reply
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Jinjie Ruan @ 2026-04-24 2:47 UTC (permalink / raw)
To: Catalin Marinas
Cc: Thomas Gleixner, peterz, sudeep.holla, yangyicong,
dietmar.eggemann, Jonathan.Cameron, linux-kernel, James Morse,
linux-arm-kernel
In-Reply-To: <aep85G05D3TM9uj2@arm.com>
On 4/24/2026 4:11 AM, Catalin Marinas wrote:
> On Thu, Apr 23, 2026 at 08:32:34PM +0800, Jinjie Ruan wrote:
>> On 4/23/2026 6:08 PM, Thomas Gleixner wrote:
>>> On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
>>>> Another option would have been to avoid marking such CPUs present but I
>>>> think this will break other things. Yet another option is to register
>>>> all CPU devices even if they never come up (like maxcpus greater than
>>>> actual CPUs).
>>>>
>>>> Opinions? It might be an arm64+ACPI-only thing.
>>>
>>> I think so. The proper thing to do is to apply sane limits:
>>>
>>> 1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
>>>
>>> 2) The maxcpus limit on the command line N_MAXCPUS_CL
>>>
>>> So the actual possible CPUs evaluates to:
>>>
>>> num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
>>>
>>> The evaluation of the firmware should not mark CPUs present which are
>>> actually not. ACPI gives you that information. See:
>>>
>>> 5.2.12.14 GIC CPU Interface (GICC) Structure
>>>
>>> in the ACPI spec. That has two related bits:
>>>
>>> Enabled:
>>>
>>> If this bit is set, the processor is ready for use. If this bit is
>>> clear and the Online Capable bit is set, the system supports enabling
>>> this processor during OS runtime. If this bit is clear and the Online
>>> Capable bit is also clear, this processor is un- usable, and the
>>> operating system support will not attempt to use it.
>>>
>>> Online Capable:
>>>
>>> The information conveyed by this bit depends on the value of the
>>> Enabled bit. If the Enabled bit is set, this bit is reserved and must
>>> be zero. Otherwise, if this bit is set, the system supports enabling
>>> this processor later during OS runtime
>>>
>>> So the combination of those gives you the right answer:
>>>
>>> Enabled Online
>>> Capable
>>> 0 0 Not present, not possible
>>> 0 1 Not present, but possible to "hotplug" layter
>>> 1 0 Present
>>> 1 1 Invalid
>>
>> On x86, it seems that all CPUs with the ACPI_MADT_ENABLED bit set will
>> be marked as present.
>>
>> acpi_parse_x2apic()
>> -> enabled = processor->lapic_flags & ACPI_MADT_ENABLED
>> -> topology_register_apic(enabled)
>> -> topo_register_apic(enabled)
>> -> set_cpu_present(cpu, true)
>
> Yes but arm64 marks all CPUs present even if !ACPI_MADT_ENABLED as we
> don't have the notion of hardware CPU hotplug.
>
> I need to dig some more into the original vCPU hotplug support and why
> we ended up with all CPUs marked as present even if not calling
> register_cpu():
>
> https://lore.kernel.org/linux-arm-kernel/20240529133446.28446-1-Jonathan.Cameron@huawei.com/
>
> What's the MADT GICC provided by qemu with "-smp cpus=4,maxcpus=8"? If
> it says Enabled for the first 4 and Online Capable for the rest, maybe
> we can try something like below:
>
> ----------------------8<-----------------
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 5891f92c2035..681aa2bbc399 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
> return *pcpu;
> }
>
> + set_cpu_present(*pcpu, true);
> return 0;
> }
> EXPORT_SYMBOL(acpi_map_cpu);
>
> int acpi_unmap_cpu(int cpu)
> {
> + set_cpu_present(cpu, false);
> return 0;
> }
> EXPORT_SYMBOL(acpi_unmap_cpu);
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1aa324104afb..6421027669fc 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -566,6 +566,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
> }
> EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
>
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return acpi_cpu_get_madt_gicc(cpu)->flags & ACPI_MADT_ENABLED;
> +}
> +
> /*
> * acpi_map_gic_cpu_interface - parse processor MADT entry
> *
> @@ -670,6 +675,11 @@ static void __init acpi_parse_and_init_cpus(void)
> early_map_cpu_to_node(i, acpi_numa_get_nid(i));
> }
> #else
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return false;
> +}
> +
> #define acpi_parse_and_init_cpus(...) do { } while (0)
> #endif
>
> @@ -808,7 +818,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> if (err)
> continue;
>
> - set_cpu_present(cpu, true);
> + if (acpi_disabled || acpi_cpu_is_present(cpu))
> + set_cpu_present(cpu, true);
Hi, Catalin
It alss passes the test on the local QEMU-KVM environment where the ACPI
issue occurs. And this looks like the cleanest fix.
Best regards,
Jinjie
> numa_store_cpu_info(cpu);
> }
> }
>
^ permalink raw reply
* Re: [PATCH v3 02/11] iommu: Pass in reset result to pci_dev_reset_iommu_done()
From: Nicolin Chen @ 2026-04-24 2:46 UTC (permalink / raw)
To: Baolu Lu
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
Pranjal Shrivastava, Mostafa Saleh, Kevin Tian, linux-arm-kernel,
iommu, linux-kernel, linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <c8c8b482-3781-4d33-9aea-866467d15b69@linux.intel.com>
On Fri, Apr 24, 2026 at 10:38:09AM +0800, Baolu Lu wrote:
> On 4/17/26 07:28, Nicolin Chen wrote:
> > @@ -4083,6 +4093,18 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> > if (WARN_ON(!group->blocking_domain))
> > return;
> > + /*
> > + * A reset failure implies that the device might be unreliable. E.g. its
> > + * device cache might retain stale entries, which potentially results in
> > + * memory corruption. Thus, do not unblock the device until a successful
> > + * reset.
> > + */
> > + if (!reset_succeeds) {
> > + pci_err(pdev,
> > + "Reset failed. Keep it blocked to protect memory\n");
> > + return;
> > + }
>
> Nit: pci_dev_reset_iommu_done() does nothing if reset_succeeds is false.
> Would it be better to handle this in the caller instead? Something like:
>
> if (reset_succeeds)
> pci_dev_reset_iommu_done(dev);
>
> ?
It would also need a print and some duplicated comments. Actually,
that would be my v2, which Kevin suggested this against:
https://lore.kernel.org/all/BN9PR11MB5276706AE4E0BBE86F0F6E158C4EA@BN9PR11MB5276.namprd11.prod.outlook.com/
Though I don't have a strong personal reference here, I do see this
version slightly cleaner than doing in the callers.
Thanks
Nicolin
^ permalink raw reply
* Re: [PATCH v3 04/11] iommu: Add __iommu_group_block_device helper
From: Baolu Lu @ 2026-04-24 2:40 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <5bf2e259f80696c498cb15f40452862e4b43a295.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> Move the RID/PASID blocking routine into a separate helper, which will be
> reused by a new function to quarantine the device but does not bother the
> gdev->reset_depth counter.
>
> No functional changes.
>
> Suggested-by: Kevin Tian<kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> drivers/iommu/iommu.c | 99 ++++++++++++++++++++++++-------------------
> 1 file changed, 56 insertions(+), 43 deletions(-)
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v3 03/11] iommu: Add reset_device_done callback for hardware fault recovery
From: Baolu Lu @ 2026-04-24 2:40 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <c90693e75c0610da38103a683b558d5596bd843b.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> When an IOMMU hardware detects an error due to a faulty device (e.g. an ATS
> invalidation timeout), IOMMU drivers may quarantine the device by disabling
> specific hardware features or dropping translation capabilities.
>
> To recover from these states, the IOMMU driver needs a reliable signal that
> the underlying physical hardware has been cleanly reset (e.g., via PCIe AER
> or a sysfs Function Level Reset) so as to lift the quarantine.
>
> Introduce a reset_device_done callback in struct iommu_ops. Trigger it from
> the existing pci_dev_reset_iommu_done() path to notify the underlying IOMMU
> driver that the device's internal state has been sanitized.
>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> include/linux/iommu.h | 4 ++++
> drivers/iommu/iommu.c | 12 ++++++++++++
> 2 files changed, 16 insertions(+)
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v3 02/11] iommu: Pass in reset result to pci_dev_reset_iommu_done()
From: Baolu Lu @ 2026-04-24 2:38 UTC (permalink / raw)
To: Nicolin Chen, Will Deacon, Robin Murphy, Joerg Roedel,
Bjorn Helgaas, Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Kevin Tian, linux-arm-kernel, iommu, linux-kernel, linux-acpi,
linux-pci, vsethi, Shuai Xue
In-Reply-To: <bf99f11ac9a42b5552ec3367d02840366459ae7b.1776381841.git.nicolinc@nvidia.com>
On 4/17/26 07:28, Nicolin Chen wrote:
> IOMMU drivers handle ATC cache maintenance. They may encounter ATC-related
> errors (e.g., ATC invalidation request timeout), indicating that ATC cache
> might have stale entries that can corrupt the memory. In this case, IOMMU
> driver has no choice but to block the device's ATS function and wait for a
> device recovery.
>
> The pci_dev_reset_iommu_done() called at the end of a reset function could
> serve as a reliable signal to the IOMMU subsystem that the physical device
> cache is completely clean. However, the function is called unconditionally
> even if the reset operation had actually failed, which would re-attach the
> faulty device back to a normal translation domain. And this will leave the
> system highly exposed, creating vulnerabilities for data corruption:
> IOMMU blocks RID/ATS
> pci_reset_function():
> pci_dev_reset_iommu_prepare(); // Block RID/ATS
> __reset(); // Failed (ATC is still stale)
> pci_dev_reset_iommu_done(); // Unblock RID/ATS (ah-ha)
>
> Instead, add a @reset_succeeds parameter to pci_dev_reset_iommu_done() and
> pass the reset result from each caller:
> IOMMU blocks RID/ATS
> pci_reset_function():
> pci_dev_reset_iommu_prepare(); // Block RID/ATS
> rc = __reset();
> pci_dev_reset_iommu_done(!rc); // Unblock or quarantine
>
> On a successful reset, done() restores the device to its RID/PASID domains
> and decrements group->recovery_cnt. On failure, the device remains blocked,
> and concurrent domain attachment will be rejected until a successful reset.
>
> Suggested-by: Kevin Tian<kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen<nicolinc@nvidia.com>
> ---
> include/linux/iommu.h | 5 +++--
> drivers/iommu/iommu.c | 28 +++++++++++++++++++++++++---
> drivers/pci/pci-acpi.c | 2 +-
> drivers/pci/pci.c | 10 +++++-----
> drivers/pci/quirks.c | 2 +-
> 5 files changed, 35 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 54b8b48c762e8..d3685967e960a 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -1191,7 +1191,7 @@ void iommu_free_global_pasid(ioasid_t pasid);
>
> /* PCI device reset functions */
> int pci_dev_reset_iommu_prepare(struct pci_dev *pdev);
> -void pci_dev_reset_iommu_done(struct pci_dev *pdev);
> +void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds);
> #else /* CONFIG_IOMMU_API */
>
> struct iommu_ops {};
> @@ -1521,7 +1521,8 @@ static inline int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
> return 0;
> }
>
> -static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> +static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev,
> + bool reset_succeeds)
> {
> }
> #endif /* CONFIG_IOMMU_API */
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index ff181db687bbf..28d4c1f143a08 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -80,6 +80,7 @@ struct group_device {
> * Device is blocked for a pending recovery while its group->domain is
> * retained. This can happen when:
> * - Device is undergoing a reset
> + * - Device failed the last reset
> */
> bool blocked;
> unsigned int reset_depth;
> @@ -3971,7 +3972,9 @@ EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL");
> * reset is finished, pci_dev_reset_iommu_done() can restore everything.
> *
> * Caller must use pci_dev_reset_iommu_prepare() with pci_dev_reset_iommu_done()
> - * before/after the core-level reset routine, to decrement the recovery_cnt.
> + * before/after the core-level reset routine. On a successful reset, done() will
> + * decrement group->recovery_cnt and restore domains. On a failure, recovery_cnt
> + * is left intact and the device stays blocked.
> *
> * Return: 0 on success or negative error code if the preparation failed.
> *
> @@ -4000,6 +4003,9 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
>
> if (gdev->reset_depth++)
> return 0;
> + /* Device might be already blocked for a quarantine */
> + if (gdev->blocked)
> + return 0;
>
> ret = __iommu_group_alloc_blocking_domain(group);
> if (ret)
> @@ -4047,18 +4053,22 @@ EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_prepare);
> /**
> * pci_dev_reset_iommu_done() - Restore IOMMU after a PCI device reset is done
> * @pdev: PCI device that has finished a reset routine
> + * @reset_succeeds: Whether the PCI device reset is successful or not
> *
> * After a PCIe device finishes a reset routine, it wants to restore its IOMMU
> * activity, including new translation and cache invalidation, by re-attaching
> * all RID/PASID of the device back to the domains retained in the core-level
> * structure.
> *
> - * Caller must pair it with a successful pci_dev_reset_iommu_prepare().
> + * This is a pairing function for pci_dev_reset_iommu_prepare(). Caller should
> + * pass in the reset state via @reset_succeeds. On a failed reset, the device
> + * remains blocked for a quarantine with the group->recovery_cnt intact, so as
> + * to protect system memory until a subsequent successful reset.
> *
> * Note that, although unlikely, there is a risk that re-attaching domains might
> * fail due to some unexpected happening like OOM.
> */
> -void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> +void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
> {
> struct iommu_group *group = pdev->dev.iommu_group;
> struct group_device *gdev;
> @@ -4083,6 +4093,18 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
> if (WARN_ON(!group->blocking_domain))
> return;
>
> + /*
> + * A reset failure implies that the device might be unreliable. E.g. its
> + * device cache might retain stale entries, which potentially results in
> + * memory corruption. Thus, do not unblock the device until a successful
> + * reset.
> + */
> + if (!reset_succeeds) {
> + pci_err(pdev,
> + "Reset failed. Keep it blocked to protect memory\n");
> + return;
> + }
Nit: pci_dev_reset_iommu_done() does nothing if reset_succeeds is false.
Would it be better to handle this in the caller instead? Something like:
if (reset_succeeds)
pci_dev_reset_iommu_done(dev);
?
> +
> /* Re-attach RID domain back to group->domain */
> if (group->domain != group->blocking_domain) {
> WARN_ON(__iommu_attach_device(group->domain, &pdev->dev,
Thanks,
baolu
^ permalink raw reply
* Re: [PATCH v3 06/11] iommu: Defer __iommu_group_free_device() to be outside group->mutex
From: Baolu Lu @ 2026-04-24 2:29 UTC (permalink / raw)
To: Nicolin Chen
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
Pranjal Shrivastava, Mostafa Saleh, Kevin Tian, linux-arm-kernel,
iommu, linux-kernel, linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <aeo/BDwYM9yYHctI@Asurada-Nvidia>
On 4/23/26 23:47, Nicolin Chen wrote:
> On Thu, Apr 23, 2026 at 03:55:02PM +0800, Baolu Lu wrote:
>> On 4/17/26 07:28, Nicolin Chen wrote:
>>> +static void __iommu_group_empty_assert_owner_cnt(struct iommu_group *group)
>>> +{
>>> + lockdep_assert_held(&group->mutex);
>>> + /*
>>> + * If the group has become empty then ownership must have been
>>> + * released, and the current domain must be set back to NULL or
>>> + * the default domain.
>>> + */
>>
>> Nit: this comment doesn't quite match the following code. The code
>> doesn't check "group->domain != NULL". Or perhaps in that case,
>> group->default_domain must be NULL?
>
> This is the original patch from Jason:
> https://lore.kernel.org/r/4-v3-328044aa278c+45e49-iommu_probe_jgg@nvidia.com
>
> I kept the comments as-is, though It might be slightly confusing?
>
> I think it means:
> If group->default_domain == NULL, it does check "set back to NULL".
> If group->default_domain != NULL, it then checks "default domain".
>
> Maybe it could be "must be set back to the default domain (which
> itself can be NULL"?
This is clearer. As I understand it, when the last device leaves the
iommu_group, the group->domain should be one of the static system
domains, either the default domain or the blocking domain.
>
>> Furthermore, if a device is currently quarantined, group->domain will be
>> the blocking_domain. If that quarantined device is then hot-removed and
>> happens to be the last device in the group, will this WARN_ON trigger
>> unnecessarily?
>
> If a device is quarantined, its group->domain is retained to the
> previously attached domain. Its blocking state is logged in the
> gdev->blocked flag. So, I think it can pass the test.
Oh, my mistake. I thought group->domain would point to the blocking
domain when a device is quarantined. It's fine if group->domain remains
set to the previous domain.
> Thanks
> Nicolin
Thanks,
baolu
^ permalink raw reply
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Jinjie Ruan @ 2026-04-24 1:56 UTC (permalink / raw)
To: Catalin Marinas
Cc: Thomas Gleixner, peterz, sudeep.holla, yangyicong,
dietmar.eggemann, Jonathan.Cameron, linux-kernel, James Morse,
linux-arm-kernel
In-Reply-To: <aep85G05D3TM9uj2@arm.com>
On 4/24/2026 4:11 AM, Catalin Marinas wrote:
> On Thu, Apr 23, 2026 at 08:32:34PM +0800, Jinjie Ruan wrote:
>> On 4/23/2026 6:08 PM, Thomas Gleixner wrote:
>>> On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
>>>> Another option would have been to avoid marking such CPUs present but I
>>>> think this will break other things. Yet another option is to register
>>>> all CPU devices even if they never come up (like maxcpus greater than
>>>> actual CPUs).
>>>>
>>>> Opinions? It might be an arm64+ACPI-only thing.
>>>
>>> I think so. The proper thing to do is to apply sane limits:
>>>
>>> 1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
>>>
>>> 2) The maxcpus limit on the command line N_MAXCPUS_CL
>>>
>>> So the actual possible CPUs evaluates to:
>>>
>>> num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
>>>
>>> The evaluation of the firmware should not mark CPUs present which are
>>> actually not. ACPI gives you that information. See:
>>>
>>> 5.2.12.14 GIC CPU Interface (GICC) Structure
>>>
>>> in the ACPI spec. That has two related bits:
>>>
>>> Enabled:
>>>
>>> If this bit is set, the processor is ready for use. If this bit is
>>> clear and the Online Capable bit is set, the system supports enabling
>>> this processor during OS runtime. If this bit is clear and the Online
>>> Capable bit is also clear, this processor is un- usable, and the
>>> operating system support will not attempt to use it.
>>>
>>> Online Capable:
>>>
>>> The information conveyed by this bit depends on the value of the
>>> Enabled bit. If the Enabled bit is set, this bit is reserved and must
>>> be zero. Otherwise, if this bit is set, the system supports enabling
>>> this processor later during OS runtime
>>>
>>> So the combination of those gives you the right answer:
>>>
>>> Enabled Online
>>> Capable
>>> 0 0 Not present, not possible
>>> 0 1 Not present, but possible to "hotplug" layter
>>> 1 0 Present
>>> 1 1 Invalid
>>
>> On x86, it seems that all CPUs with the ACPI_MADT_ENABLED bit set will
>> be marked as present.
>>
>> acpi_parse_x2apic()
>> -> enabled = processor->lapic_flags & ACPI_MADT_ENABLED
>> -> topology_register_apic(enabled)
>> -> topo_register_apic(enabled)
>> -> set_cpu_present(cpu, true)
>
> Yes but arm64 marks all CPUs present even if !ACPI_MADT_ENABLED as we
> don't have the notion of hardware CPU hotplug.
>
> I need to dig some more into the original vCPU hotplug support and why
> we ended up with all CPUs marked as present even if not calling
> register_cpu():
>
> https://lore.kernel.org/linux-arm-kernel/20240529133446.28446-1-Jonathan.Cameron@huawei.com/
>
> What's the MADT GICC provided by qemu with "-smp cpus=4,maxcpus=8"? If
> it says Enabled for the first 4 and Online Capable for the rest, maybe
> we can try something like below:
Yes, you are absolutely right,Enabled for the first 4(with GIC Flags:
0x1, bit0 set) and Online Capable for the rest(with GIC Flags: 0x8, bit3
set). The ACPI MADT disassembly result is as follows:
Link:
https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#gic-cpu-interface-gicc-structure
# cat /sys/firmware/acpi/tables/APIC > madt.bin
# iasl -d madt.bin
[048h 0072 4] CPU Interface Number : 00000000
[030h 0048 4] Local GIC Hardware ID : 00000000
...
[04Ch 0076 4] Processor UID : 00000000
[050h 0080 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[098h 0152 4] CPU Interface Number : 00000001
[09Ch 0156 4] Processor UID : 00000001
[0A0h 0160 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[0E8h 0232 4] CPU Interface Number : 00000002
[0ECh 0236 4] Processor UID : 00000002
[0F0h 0240 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[138h 0312 4] CPU Interface Number : 00000003
[13Ch 0316 4] Processor UID : 00000003
[140h 0320 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[188h 0392 4] CPU Interface Number : 00000004
[18Ch 0396 4] Processor UID : 00000004
[190h 0400 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[1D8h 0472 4] CPU Interface Number : 00000005
[1DCh 0476 4] Processor UID : 00000005
[1E0h 0480 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[228h 0552 4] CPU Interface Number : 00000006
[22Ch 0556 4] Processor UID : 00000006
[230h 0560 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
[278h 0632 4] CPU Interface Number : 00000007
[27Ch 0636 4] Processor UID : 00000007
[280h 0640 4] Flags (decoded below) : 00000008
Processor Enabled : 0
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
...
>
> ----------------------8<-----------------
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index 5891f92c2035..681aa2bbc399 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
> return *pcpu;
> }
>
> + set_cpu_present(*pcpu, true);
> return 0;
> }
> EXPORT_SYMBOL(acpi_map_cpu);
>
> int acpi_unmap_cpu(int cpu)
> {
> + set_cpu_present(cpu, false);
> return 0;
> }
> EXPORT_SYMBOL(acpi_unmap_cpu);
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1aa324104afb..6421027669fc 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -566,6 +566,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
> }
> EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
>
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return acpi_cpu_get_madt_gicc(cpu)->flags & ACPI_MADT_ENABLED;
> +}
> +
> /*
> * acpi_map_gic_cpu_interface - parse processor MADT entry
> *
> @@ -670,6 +675,11 @@ static void __init acpi_parse_and_init_cpus(void)
> early_map_cpu_to_node(i, acpi_numa_get_nid(i));
> }
> #else
> +static bool acpi_cpu_is_present(int cpu)
> +{
> + return false;
> +}
> +
> #define acpi_parse_and_init_cpus(...) do { } while (0)
> #endif
>
> @@ -808,7 +818,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> if (err)
> continue;
>
> - set_cpu_present(cpu, true);
> + if (acpi_disabled || acpi_cpu_is_present(cpu))
> + set_cpu_present(cpu, true);
> numa_store_cpu_info(cpu);
> }
> }
>
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Paul Moore @ 2026-04-24 1:27 UTC (permalink / raw)
To: Mimi Zohar, roberto.sassu
Cc: Yeoreum Yun, Jonathan McDowell, linux-security-module,
linux-kernel, linux-integrity, linux-arm-kernel, kvmarm, jmorris,
serge, dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla,
maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, noodles, sebastianene
In-Reply-To: <aephL3MzYoqFGaT5@e129823.arm.com>
On Thu, Apr 23, 2026 at 2:13 PM Yeoreum Yun <yeoreum.yun@arm.com> wrote:
>
> Sounds good. Once the patch is posted, I’ll review it as well.
> Sorry again for the noise, and thanks for your patience ;)
My apologies for not getting a chance to look at this patchset sooner.
This seems like an obvious, perhaps even stupid, question, but I have
to ask: if IMA can be properly initialized via late_initcall_sync(),
why not simply do the initialization in late_initcall_sync() and drop
the late_initcall() initialization?
Does any IMA functionality suffer if initialization waits until
late_initcall_sync()? If so, it seems non-critical if waiting until
_sync() is acceptable, as it appears in these patches/comments.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v4 35/49] KVM: arm64: GICv3: nv: Plug L1 LR sync into deactivation primitive
From: Darren Hart @ 2026-04-24 0:02 UTC (permalink / raw)
To: Marc Zyngier
Cc: Vishnu Pajjuri, Fuad Tabba, Joey Gouly, Suzuki K Poulose,
Oliver Upton, Zenghui Yu, Christoffer Dall, Mark Brown, kvm,
linux-arm-kernel, kvmarm
In-Reply-To: <86eck71o1v.wl-maz@kernel.org>
On Wed, Apr 22, 2026 at 07:55:56AM +0100, Marc Zyngier wrote:
> [+ Darren]
>
Thanks for the head's up Marc.
> On Tue, 31 Mar 2026 10:42:57 +0100,
> Marc Zyngier <maz@kernel.org> wrote:
> > >
...
> > > Although this behavior is puzzling, it matches the trace I typically
> > > observe on L0. After reverting the patch, I was able to boot L2 guests
> > > successfully.
> >
> > Well, this patch fixes real bugs, so it isn't going anywhere.
Understood.
>
> Have you made progress on this? I can't reproduce it at all despite my
> best effort. I'm perfectly happy to help, but you need to give me
> *something* to go on.
>
I didn't give this the attention it deserved. I've now got Vishnu the
resources he needs to help move this forward. We owe you something
concrete/actionable/reproducible and we'll report back once we have it.
--
Darren Hart
Ampere Computing / Linux Enabling
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Linus Torvalds @ 2026-04-23 23:08 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
Blake Oler
In-Reply-To: <CAHk-=wh=B3fqU9AaBsyViZR=eVTG5qa2CGyN=qxPROVxu9Gctg@mail.gmail.com>
On Thu, 23 Apr 2026 at 14:28, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> This is all 100% on the RSEQ kernel code, not on users who took advantage of it.
Side note: when RSEQ was merged, the *primary* documented use case was
literally user space allocators with percpu caches. That's what I was
told at the time.
Now I think it was jemalloc(), not tcmalloc, but it's not like
tcmalloc is some odd minor use-case.
We are pretty much talking about the raison d'être of the whole rseq
feature, not some odd small corner case.
Linus
^ permalink raw reply
* Re: [PATCH V1 3/3] iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors
From: Jason Gunthorpe @ 2026-04-23 22:45 UTC (permalink / raw)
To: Vidya Sagar
Cc: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
will, catalin.marinas, joro, robin.murphy, nicolinc, praan,
vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
linux-arm-kernel, acpica-devel, iommu, linux-kernel
In-Reply-To: <20260423191417.2031652-4-vidyas@nvidia.com>
On Fri, Apr 24, 2026 at 12:44:17AM +0530, Vidya Sagar wrote:
> The SMMUv3 driver currently calls pci_enable_pasid() for any PCI
> master that exposes a PASID capability, regardless of whether the
> upstream Root Complex actually supports PASID and regardless of the
> RC's declared Max PASID Width. With IORT spec E.c (RC node revision
> >= 4) firmware reports both, so we can do better:
>
> - If the IORT Root Complex node says PASID is not supported
> (Flags bit 0 == 0 at byte offset 36), enabling PASID on the
> endpoint is futile - the RC will not forward the PASID prefix to
> the SMMU - so skip pci_enable_pasid() silently.
>
> - If the IORT Root Complex node reports a Max PASID Width (bits[4:0]
> of PASID Capabilities at offset 33), clamp the endpoint's
> pci_max_pasids() result by 1 << width before computing the SMMU
> SSID width. This prevents master->ssid_bits from exceeding what
> the RC can actually carry.
>
> Both behaviours are gated on iort_pci_rc_pasid_max_width_known(), i.e.
> RC node revision >= 4, so platforms with older IORT firmware see no
> behavioural change and continue to enable PASID purely on the basis
> of the endpoint capability.
>
> Use the new IOMMU_FWSPEC_PCI_RC_PASID fwspec flag (set by IORT) for
> the support check, and call iort_pci_rc_pasid_max_width_for_dev() for
> the width clamp; both pieces are wired up in
> iort_iommu_configure_id() by the previous patch.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++++++++++++---
> 1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index e8d7dbe495f0..2b269307fd33 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3071,16 +3071,28 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
>
> static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
> {
> - int ret;
> - int features;
> - int num_pasids;
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
> struct pci_dev *pdev;
> + int features, num_pasids, ret, rc_width;
Don't reformat the code like this.
Otherwise the series broadly makes sense to me
Jason
^ permalink raw reply
* Re: [PATCH V1 1/3] ACPICA: IORT: Add Root Complex PASID Flags field
From: Jason Gunthorpe @ 2026-04-23 22:43 UTC (permalink / raw)
To: Vidya Sagar
Cc: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
will, catalin.marinas, joro, robin.murphy, nicolinc, praan,
vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
linux-arm-kernel, acpica-devel, iommu, linux-kernel
In-Reply-To: <20260423191417.2031652-2-vidyas@nvidia.com>
On Fri, Apr 24, 2026 at 12:44:15AM +0530, Vidya Sagar wrote:
> The IORT spec, Issue E.c (ARM DEN 0049E.c, January 2022), bumps the
> Root Complex Node to revision 4 and adds two PASID descriptors:
>
> - PASID Capabilities at byte offset 33 (2 bytes), bits[4:0] of which
> report the Max PASID Width supported by the Root Complex.
> - Flags at byte offset 36 (4 bytes), bit 0 of which reports whether
> the Root Complex itself supports PASID. This is distinct from the
> existing ATS Attribute bit 2 (at offset 24) that only reports
> whether the RC forwards PASID information on translated
> transactions.
>
> The ACPICA struct in include/acpi/actbl2.h was updated for the E.c
> PASID Capabilities descriptor (offset 33) but stops short with a
> trailing 'u8 reserved[]' flexible array, so the new Flags field at
> offset 36 is unreachable and the existing ACPI_IORT_PASID_*
> definitions have no consumer.
>
> Replace the trailing flexible array with a fixed 'u8 reserved[1]'
> followed by 'u32 flags' so the struct fully covers RC node revision 4,
> and add the ACPI_IORT_RC_PASID_SUPPORTED mask for bit 0 of the new
> field. With #pragma pack(1) in effect for actbl2.h, this lands the new
> field at the spec-mandated absolute offset 36.
>
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> include/acpi/actbl2.h | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
There is a whole process to change this file, I went through it once
for canwbs..
https://lore.kernel.org/acpica-devel/2-v3-e2e16cd7467f+2a6a1-smmuv3_nesting_jgg@nvidia.com/
You have to make a pull request here:
https://github.com/acpica/acpica/pulls
And then use the
generate/linux/make-patches.sh -u <commit-id>
Script to make this patch for linux in the perscribed format.
I think, something like that
Jason
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Jason Gunthorpe @ 2026-04-23 22:37 UTC (permalink / raw)
To: Will Deacon
Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel, Nicolin Chen,
Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <aepRy7Gp7Ng85Zr7@willie-the-truck>
On Thu, Apr 23, 2026 at 06:07:23PM +0100, Will Deacon wrote:
> I don't think it's that odd given that the STE/CD entries are bigger
> than PTEs and the SMMU permits a lot more relaxations about how they are
> accessed and cached compared to the PTW.
Well I'm not sure bigger really matters, but I wasn't aware there was
a spec relaxation here that would make the cachable path not viable
for STE but not PTW...
> Having said that, the page-table code looks broken to me even in the
> coherent case:
>
> ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);
>
> as the compiler can theoretically make a right mess of that.
Heh, great. The iommupt stuff does better.. It does a 64 bit cmpxchg
to store a table pointer and a 64 bit WRITE_ONCE to store the pte,
then a CMO through the DMA API.
DMA API has to guarentee the right ordering, so we only have the
question below:
> > STE/CD is pretty simple now, there is only one place to put the CMO
> > and the ordering is all handled with that shared code. We no longer
> > care about ordering beyond all the writes must be visible to HW before
> > issuing the CMDQ invalidation command - which is the same environment
> > as the pagetable.
>
> You presumably rely on 64-bit single-copy atomicity for hitless updates,
> no?
Yes, just like the page table does..
I hope that's not a problem or we have a issue with the PTW :)
> > I also don't like this "lot of systems thing". I don't want these
> > powerful capabilities locked up in some giant CSP's proprietary
> > kernel. I want all the companies in the cloud market to have access
> > to the same feature set. That's what open source is supposed to be
> > driving toward. I have several interesting use cases for this
> > functionality already.
>
> Sorry, the point here was definitely _not_ about keeping this out of
> tree, nor was I trying to say that this stuff isn't important. But the
> mobile world doesn't give a hoot about KHO and _does_ tend to care about
> the impact of CMO, so we have to find a way to balance the two worlds.
Yes, that make sense.
My argument is that the CMO on STE/CD shouldn't bother mobile, you
could even view it as an micro-optimization because we do occasionally
read-back the STE/CD fields.
But if you say the SMM STE/CD fetch doesn't have to follow the single
copy rules and PTW does, then ok..
And if Samiullah can tackle dma_alloc_coherent then maybe the whole
question is moot.
Jason
^ permalink raw reply
* Re: [PATCH 2/5] drm/panel-edp: Add support for Samsung LTL101DL02-002 panel
From: Doug Anderson @ 2026-04-23 21:49 UTC (permalink / raw)
To: Lukas Timmermann
Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Alim Akhtar, Michael Turquette, Stephen Boyd, dri-devel,
devicetree, linux-kernel, linux-samsung-soc, linux-clk,
linux-arm-kernel, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-2-196f80c5673a@timmermann.space>
Hi,
On Thu, Apr 23, 2026 at 2:15 PM Lukas Timmermann <linux@timmermann.space> wrote:
>
> From: Alexandre Marquet <tb@a-marquet.fr>
>
> Add a panel entry for the Samsung LTL101DL02-002 panel, as found in
> Samsung Manta (Google Nexus 10).
>
> Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
> Signed-off-by: Lukas Timmermann <linux@timmermann.space>
> ---
> drivers/gpu/drm/panel/panel-edp.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
Adding new panels like this is discouraged these days. Is there a
reason you can't use the generic "edp-panel" compatible? I know that
the exynos5 driver is pretty old, but a quick glance shows that it's
based on the same analogix-dp core that "rockchip,analogix-dp" is, and
that seems to have support for aux-bus...
-Doug
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Linus Torvalds @ 2026-04-23 21:28 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
Blake Oler
In-Reply-To: <874il11jac.ffs@tglx>
On Thu, 23 Apr 2026 at 14:03, Thomas Gleixner <tglx@kernel.org> wrote:
>
> Feel free to enforce it, but be aware that you thereby set a
> precedence that a single abuser can then rightfully own a general
> shared interface of the kernel forever and force everybody else to
> give up.
That's not a new precedent. That is *literally* the rule we have always had.
This is why system calls and ABI's need to have hard rules that they
actually check, because if they don't, they are stuck with the
semantics that people assume.
And no, "documented behavior" is BS. It has absolutely no relevance.
All that matters is hard harsh reality.
Yes, this has led to issues before.
Most new system calls have learnt their lesson, and they check for
unused bits in flags etc, and error out on bits that the lernel
doesn't really care about being randomly set - so that one day we
*can* extend on things and start caring about them.
But they do it because we've been burnt so many times before because
we haven't checked those bits, and then we were forced to just live
with the fact that people passed in random values.
> // Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.
>
> Do you seriously want to proliferate that?
Absolutely.
That's how clever hacks work - they take advantage of things past
their design parameters. "If it works, it's not stupid".
We don't then turn around and say "you were clever, and we did
something stupid, so now we'll hurt you".
This is all 100% on the RSEQ kernel code, not on users who took advantage of it.
Linus
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox