* [PATCH v7 2/6] media: mediatek: encoder: Add new platform data members
From: Irui Wang @ 2026-06-05 9:35 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Matthias Brugger, Krzysztof Kozlowski, angelogioacchino.delregno,
nicolas.dufresne, Tiffany Lin, kyrie wu
Cc: Yunfei Dong, Maoguang Meng, Longfei Wang, Irui Wang,
Project_Global_Chrome_Upstream_Group, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260605093519.13695-1-irui.wang@mediatek.com>
Add new platform data members to support different encoder ICs:
- venc_model_num: encoder model number
- fw_type: firmware type (VPU, SCP, or VCP)
- fw_init: firmware-specific initialization callback
- ipi_id: IPI ID for encoder communication
This centralizes all static platform configuration in the platform
data structure, eliminating the need for runtime device tree parsing
and the per-device fw_init callback pointer. Each platform's pdata
now directly specifies its firmware initialization function.
Changes:
1. Add venc_model_num to pdata and remove mtk_vcodec_enc_get_chip_name()
2. Add fw_type to pdata for each platform (VPU or SCP)
3. Add ipi_id field declaration to pdata
4. Remove device tree parsing for fw_type
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
.../mediatek/vcodec/common/mtk_vcodec_fw.c | 3 +-
.../mediatek/vcodec/encoder/mtk_vcodec_enc.c | 22 +---------
.../vcodec/encoder/mtk_vcodec_enc_drv.c | 40 +++++++++++--------
.../vcodec/encoder/mtk_vcodec_enc_drv.h | 10 ++++-
4 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
index a2e6a01272b2..9df64200d933 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
@@ -23,8 +23,9 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type t
{
if (fw_use == ENCODER) {
struct mtk_vcodec_enc_dev *enc_dev = priv;
+ const struct mtk_vcodec_enc_pdata *pdata = enc_dev->venc_pdata;
- return enc_dev->fw_init(priv, fw_use);
+ return pdata->fw_init(priv, fw_use);
}
if (fw_use == DECODER) {
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
index 48cb5dded70a..fcf0e4f90429 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
@@ -198,33 +198,15 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
pdata->num_output_formats);
}
-static int mtk_vcodec_enc_get_chip_name(struct mtk_vcodec_enc_ctx *ctx)
-{
- struct device *dev = &ctx->dev->plat_dev->dev;
-
- if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-enc"))
- return 8173;
- else if (of_device_is_compatible(dev->of_node, "mediatek,mt8183-vcodec-enc"))
- return 8183;
- else if (of_device_is_compatible(dev->of_node, "mediatek,mt8192-vcodec-enc"))
- return 8192;
- else if (of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-enc"))
- return 8195;
- else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-enc"))
- return 8188;
- else
- return 8173;
-}
-
static int vidioc_venc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
+ const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
struct device *dev = &ctx->dev->plat_dev->dev;
- int platform_name = mtk_vcodec_enc_get_chip_name(ctx);
strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
- snprintf(cap->card, sizeof(cap->card), "MT%d video encoder", platform_name);
+ snprintf(cap->card, sizeof(cap->card), "MT%d video encoder", pdata->venc_model_num);
return 0;
}
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
index dc54d445d98d..5f1feb3b07a6 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
@@ -245,8 +245,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
{
struct mtk_vcodec_enc_dev *dev;
struct video_device *vfd_enc;
- phandle rproc_phandle;
- enum mtk_vcodec_fw_type fw_type;
int ret;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -256,25 +254,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&dev->ctx_list);
dev->plat_dev = pdev;
- if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
- &rproc_phandle)) {
- fw_type = VPU;
- dev->fw_init = mtk_vcodec_fw_vpu_init;
- } else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
- &rproc_phandle)) {
- fw_type = SCP;
- dev->fw_init = mtk_vcodec_fw_scp_init;
- } else {
- dev_err(&pdev->dev, "[MTK VCODEC] Could not get venc IPI device");
+ dev->venc_pdata = of_device_get_match_data(&pdev->dev);
+ if (!dev->venc_pdata) {
+ dev_err(&pdev->dev, "Failed to get match data");
return -ENODEV;
}
- dma_set_max_seg_size(&pdev->dev, UINT_MAX);
-
- dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER);
+ dev->fw_handler = mtk_vcodec_fw_select(dev, dev->venc_pdata->fw_type, ENCODER);
if (IS_ERR(dev->fw_handler))
return PTR_ERR(dev->fw_handler);
- dev->venc_pdata = of_device_get_match_data(&pdev->dev);
+ dma_set_max_seg_size(&pdev->dev, UINT_MAX);
+
ret = mtk_vcodec_init_enc_clk(dev);
if (ret < 0) {
dev_err(&pdev->dev, "[MTK VCODEC] Failed to get mtk vcodec clock source!");
@@ -389,6 +379,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
}
static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
+ .venc_model_num = 8173,
.capture_formats = mtk_video_formats_capture_h264,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
.output_formats = mtk_video_formats_output,
@@ -396,9 +387,12 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
.min_bitrate = 64,
.max_bitrate = 60000000,
.core_id = VENC_SYS,
+ .fw_type = VPU,
+ .fw_init = mtk_vcodec_fw_vpu_init,
};
static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
+ .venc_model_num = 8173,
.capture_formats = mtk_video_formats_capture_vp8,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_vp8),
.output_formats = mtk_video_formats_output,
@@ -406,9 +400,12 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
.min_bitrate = 64,
.max_bitrate = 9000000,
.core_id = VENC_LT_SYS,
+ .fw_type = VPU,
+ .fw_init = mtk_vcodec_fw_vpu_init,
};
static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
+ .venc_model_num = 8183,
.uses_ext = true,
.capture_formats = mtk_video_formats_capture_h264,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -417,9 +414,12 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
.min_bitrate = 64,
.max_bitrate = 40000000,
.core_id = VENC_SYS,
+ .fw_type = SCP,
+ .fw_init = mtk_vcodec_fw_scp_init,
};
static const struct mtk_vcodec_enc_pdata mt8188_pdata = {
+ .venc_model_num = 8188,
.uses_ext = true,
.capture_formats = mtk_video_formats_capture_h264,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -429,9 +429,12 @@ static const struct mtk_vcodec_enc_pdata mt8188_pdata = {
.max_bitrate = 50000000,
.core_id = VENC_SYS,
.uses_34bit = true,
+ .fw_type = SCP,
+ .fw_init = mtk_vcodec_fw_scp_init,
};
static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
+ .venc_model_num = 8192,
.uses_ext = true,
.capture_formats = mtk_video_formats_capture_h264,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -440,9 +443,12 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
.min_bitrate = 64,
.max_bitrate = 100000000,
.core_id = VENC_SYS,
+ .fw_type = SCP,
+ .fw_init = mtk_vcodec_fw_scp_init,
};
static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
+ .venc_model_num = 8195,
.uses_ext = true,
.capture_formats = mtk_video_formats_capture_h264,
.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -451,6 +457,8 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
.min_bitrate = 64,
.max_bitrate = 100000000,
.core_id = VENC_SYS,
+ .fw_type = SCP,
+ .fw_init = mtk_vcodec_fw_scp_init,
};
static const struct of_device_id mtk_vcodec_enc_match[] = {
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
index 934ff648125d..6c7e8da6d8ee 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
@@ -20,6 +20,7 @@
/**
* struct mtk_vcodec_enc_pdata - compatible data for each IC
*
+ * @venc_model_num: encoder model number
* @uses_ext: whether the encoder uses the extended firmware messaging format
* @min_bitrate: minimum supported encoding bitrate
* @max_bitrate: maximum supported encoding bitrate
@@ -29,8 +30,12 @@
* @num_output_formats: number of entries in output_formats
* @core_id: stand for h264 or vp8 encode index
* @uses_34bit: whether the encoder uses 34-bit iova
+ * @fw_type: firmware type (VPU, SCP, or VCP)
+ * @fw_init: firmware-specific initialization callback
+ * @ipi_id: IPI ID for encoder communication with firmware
*/
struct mtk_vcodec_enc_pdata {
+ u16 venc_model_num;
bool uses_ext;
u64 min_bitrate;
u64 max_bitrate;
@@ -40,6 +45,9 @@ struct mtk_vcodec_enc_pdata {
size_t num_output_formats;
u8 core_id;
bool uses_34bit;
+ enum mtk_vcodec_fw_type fw_type;
+ struct mtk_vcodec_fw *(*fw_init)(void *priv, enum mtk_vcodec_fw_use fw_use);
+ int ipi_id;
};
/*
@@ -174,7 +182,6 @@ struct mtk_vcodec_enc_ctx {
* @venc_pdata: encoder IC-specific data
*
* @fw_handler: used to communicate with the firmware.
- * @fw_init: firmware-specific init callback selected at probe time
* @id_counter: used to identify current opened instance
*
* @enc_mutex: encoder hardware lock.
@@ -202,7 +209,6 @@ struct mtk_vcodec_enc_dev {
const struct mtk_vcodec_enc_pdata *venc_pdata;
struct mtk_vcodec_fw *fw_handler;
- struct mtk_vcodec_fw *(*fw_init)(void *priv, enum mtk_vcodec_fw_use fw_use);
u64 id_counter;
/* encoder hardware mutex lock */
--
2.45.2
^ permalink raw reply related
* [PATCH v7 1/6] media: dt-bindings: mediatek,vcodec-encoder: Add MT8196
From: Irui Wang @ 2026-06-05 9:35 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Matthias Brugger, Krzysztof Kozlowski, angelogioacchino.delregno,
nicolas.dufresne, Tiffany Lin, kyrie wu
Cc: Yunfei Dong, Maoguang Meng, Longfei Wang, Irui Wang,
Project_Global_Chrome_Upstream_Group, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek, Rob Herring (Arm)
In-Reply-To: <20260605093519.13695-1-irui.wang@mediatek.com>
Add support for MT8196 video encoder which uses VCP (Video Co-Processor)
for firmware management. Unlike previous platforms that use SCP/VPU, MT8196
requires VCP to load and execute the video encoding firmware, with the
encoder communicating through VCP to perform encoding operations.
Add the "mediatek,mt8196-vcodec-enc" compatible string and introduce
the "mediatek,vcp" property to reference the VCP device, which is
required for MT8196 encoder operation.
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../media/mediatek,vcodec-encoder.yaml | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index ebc615584f92..72698456374a 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -24,6 +24,7 @@ properties:
- mediatek,mt8188-vcodec-enc
- mediatek,mt8192-vcodec-enc
- mediatek,mt8195-vcodec-enc
+ - mediatek,mt8196-vcodec-enc
- items:
- const: mediatek,mt8186-vcodec-enc
- const: mediatek,mt8183-vcodec-enc
@@ -58,6 +59,13 @@ properties:
description:
Describes point to scp.
+ mediatek,vcp:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Reference to the VCP (Video Co-Processor) device that loads and executes
+ the video encoding firmware. The encoder communicates with the firmware
+ through VCP to perform encoding operations.
+
power-domains:
maxItems: 1
@@ -76,6 +84,20 @@ required:
- iommus
allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8196-vcodec-enc
+
+ then:
+ required:
+ - mediatek,vcp
+ else:
+ properties:
+ mediatek,vcp: false
+
- if:
properties:
compatible:
--
2.45.2
^ permalink raw reply related
* [PATCH v7 4/6] media: mediatek: encoder: Add support for common firmware interface
From: Irui Wang @ 2026-06-05 9:35 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Matthias Brugger, Krzysztof Kozlowski, angelogioacchino.delregno,
nicolas.dufresne, Tiffany Lin, kyrie wu
Cc: Yunfei Dong, Maoguang Meng, Longfei Wang, Irui Wang,
Project_Global_Chrome_Upstream_Group, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260605093519.13695-1-irui.wang@mediatek.com>
The existing encoder firmware interface implied just one type of codec:
H.264. Future encoders may support additional codecs; however adding
entire sets of interfaces for them is not scalable.
Instead, a new "common" firmware interface is defined for non codec
specific messages. The new messages encapsulate the old ones for
backward compatibility.
This patch adds support for these new messages.
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../vcodec/encoder/mtk_vcodec_enc_drv.h | 3 ++
.../mediatek/vcodec/encoder/venc_drv_if.c | 3 +-
.../mediatek/vcodec/encoder/venc_ipi_msg.h | 26 +++++++++++++++
.../mediatek/vcodec/encoder/venc_vpu_if.c | 33 ++++++++++++-------
4 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
index 029133e48073..8a69168c350e 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
@@ -16,6 +16,7 @@
#define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
#define MTK_ENC_IOVA_IS_34BIT(ctx) ((ctx)->dev->venc_pdata->uses_34bit)
+#define MTK_ENC_DRV_IS_COMM(ctx) (((ctx)->dev->venc_pdata->uses_common_fw_iface))
/**
* struct mtk_vcodec_enc_pdata - compatible data for each IC
@@ -30,6 +31,7 @@
* @num_output_formats: number of entries in output_formats
* @core_id: stand for h264 or vp8 encode index
* @uses_34bit: whether the encoder uses 34-bit iova
+ * @uses_common_fw_iface: whether the encoder uses common driver interface
* @fw_type: firmware type (VPU, SCP, or VCP)
* @fw_init: firmware-specific initialization callback
* @ipi_id: IPI ID for encoder communication with firmware
@@ -45,6 +47,7 @@ struct mtk_vcodec_enc_pdata {
size_t num_output_formats;
u8 core_id;
bool uses_34bit;
+ bool uses_common_fw_iface;
enum mtk_vcodec_fw_type fw_type;
struct mtk_vcodec_fw *(*fw_init)(void *priv, enum mtk_vcodec_fw_use fw_use);
int ipi_id;
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c
index e83747b8d69a..f8c9349c18c0 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c
@@ -19,13 +19,14 @@
int venc_if_init(struct mtk_vcodec_enc_ctx *ctx, unsigned int fourcc)
{
int ret = 0;
+ const bool uses_common_fw_iface = MTK_ENC_DRV_IS_COMM(ctx);
switch (fourcc) {
case V4L2_PIX_FMT_VP8:
ctx->enc_if = &venc_vp8_if;
break;
case V4L2_PIX_FMT_H264:
- ctx->enc_if = &venc_h264_if;
+ ctx->enc_if = uses_common_fw_iface ? &venc_if : &venc_h264_if;
break;
default:
return -EINVAL;
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h
index bb16d96a7f57..ce3c2c8059fb 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_ipi_msg.h
@@ -45,6 +45,20 @@ struct venc_ap_ipi_msg_init {
uint64_t venc_inst;
};
+/**
+ * struct venc_ap_ipi_msg_init_comm - AP to VPU init cmd structure
+ * @base: AP to VPU init cmd structure
+ * @codec_type: encoder type
+ * @reserved: reserved field
+ * @shared_iova: shared iova
+ */
+struct venc_ap_ipi_msg_init_comm {
+ struct venc_ap_ipi_msg_init base;
+ u32 codec_type;
+ u32 reserved;
+ u64 shared_iova;
+};
+
/**
* struct venc_ap_ipi_msg_set_param - AP to VPU set_param cmd structure
* @msg_id: message id (AP_IPIMSG_XXX_ENC_SET_PARAM)
@@ -175,6 +189,18 @@ struct venc_vpu_ipi_msg_init {
uint32_t venc_abi_version;
};
+/**
+ * struct venc_vpu_ipi_msg_init_comm - VPU ack AP init cmd structure
+ * @init_ack: AP init cmd structure
+ * @vpu_vsi_addr: VSI address from VPU
+ * @reserved: reserved field
+ */
+struct venc_vpu_ipi_msg_init_comm {
+ struct venc_vpu_ipi_msg_init init_ack;
+ u32 vpu_vsi_addr;
+ u32 reserved;
+};
+
/**
* struct venc_vpu_ipi_msg_set_param - VPU ack AP set_param cmd structure
* @msg_id: message id (VPU_IPIMSG_XXX_ENC_SET_PARAM_DONE)
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
index 0c825aa7224d..7772b8442ebc 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
@@ -10,24 +10,25 @@
static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
{
- const struct venc_vpu_ipi_msg_init *msg = data;
+ const struct venc_vpu_ipi_msg_init_comm *msg = data;
+ struct mtk_vcodec_fw *fw = vpu->ctx->dev->fw_handler;
- vpu->inst_addr = msg->vpu_inst_addr;
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
- msg->vpu_inst_addr);
+ vpu->inst_addr = msg->init_ack.vpu_inst_addr;
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, vpu->inst_addr);
/* Firmware version field value is unspecified on MT8173. */
- if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
+ if (mtk_vcodec_fw_get_type(fw) == VPU)
return;
/* Check firmware version. */
- mtk_venc_debug(vpu->ctx, "firmware version: 0x%x\n", msg->venc_abi_version);
- switch (msg->venc_abi_version) {
+ mtk_venc_debug(vpu->ctx, "firmware version: 0x%x\n",
+ msg->init_ack.venc_abi_version);
+ switch (msg->init_ack.venc_abi_version) {
case 1:
break;
default:
mtk_venc_err(vpu->ctx, "unhandled firmware version 0x%x\n",
- msg->venc_abi_version);
+ msg->init_ack.venc_abi_version);
vpu->failure = 1;
break;
}
@@ -133,7 +134,8 @@ static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg,
int vpu_enc_init(struct venc_vpu_inst *vpu)
{
int status;
- struct venc_ap_ipi_msg_init out = { };
+ size_t msg_size;
+ struct venc_ap_ipi_msg_init_comm out = { };
init_waitqueue_head(&vpu->wq_hd);
vpu->signaled = 0;
@@ -149,9 +151,16 @@ int vpu_enc_init(struct venc_vpu_inst *vpu)
return -EINVAL;
}
- out.msg_id = AP_IPIMSG_ENC_INIT;
- out.venc_inst = (unsigned long)vpu;
- if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
+ out.base.msg_id = AP_IPIMSG_ENC_INIT;
+ out.base.venc_inst = (unsigned long)vpu;
+ if (MTK_ENC_DRV_IS_COMM(vpu->ctx)) {
+ out.codec_type = vpu->ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
+ msg_size = sizeof(struct venc_ap_ipi_msg_init_comm);
+ } else {
+ msg_size = sizeof(struct venc_ap_ipi_msg_init);
+ }
+
+ if (vpu_enc_send_msg(vpu, &out, msg_size)) {
mtk_venc_err(vpu->ctx, "AP_IPIMSG_ENC_INIT fail");
return -EINVAL;
}
--
2.45.2
^ permalink raw reply related
* [PATCH v7 0/6] Add support for MT8196 video encoder
From: Irui Wang @ 2026-06-05 9:35 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Matthias Brugger, Krzysztof Kozlowski, angelogioacchino.delregno,
nicolas.dufresne, Tiffany Lin, kyrie wu
Cc: Yunfei Dong, Maoguang Meng, Longfei Wang, Irui Wang,
Project_Global_Chrome_Upstream_Group, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
This patch series add support for MT8196 video encoder.
patch 1: Add dt-bindings.
patch 2: Add new encoder driver platform data.
patch 3~5: Add a new encoder driver interface for new VCP firmware.
patch 6: Add compatible data.
About adding new driver support, the v4l2-compliance report shows:
"Total for mtk-vcodec-enc device /dev/video3: 47, Succeeded: 46, Failed: 1, Warnings: 0"
The 1 Failed case is not caused by current patch set:
fail: v4l2-test-controls.cpp(1171): node->codec_mask & STATEFUL_ENCODER
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL
This patch set depends on "media: mediatek: vcodec: support video decoder in mt8196"[1]
[1] https://patchwork.linuxtv.org/project/linux-media/list/?series=25981
Change in v7:
- patch 2: New pdata members for remove if-else device tree parsing statement.
- Rebase patch onto decoder's patch set.
- Link to v6: https://patchwork.linuxtv.org/project/linux-media/cover/20260423073345.27402-1-irui.wang@mediatek.com/
Change in v6:
- Move dt-bindings to patch 1.
- Rebase patch onto decoder's patch set.
- Link to v5: https://patchwork.linuxtv.org/project/linux-media/cover/20260302035244.8994-1-irui.wang@mediatek.com/
Change in v5:
- Rewrite patch5 commit subject.
- Add else statement in patch5.
- Link to v4: https://patchwork.linuxtv.org/project/linux-media/list/?series=21757
Change in v4:
- Rework patch3 commit message.
- Rework patch5 commit with more details.
- Rebase patch onto decoder's patch set.
- Link to v3: https://patchwork.linuxtv.org/project/linux-media/cover/20250814085642.17343-1-kyrie.wu@mediatek.com/
Change in v3:
- Add venc rc buffer alloc failure error handling.
- Add mediatek,vcp property definition in dt-bindning.
Change in v2:
- Add support for VCP encode process.
- Add MT8196 encoder driver platform data.
- Rebase encoder patch onto decoder's patch set.
- Fix some review comments in v1.
Irui Wang (6):
media: dt-bindings: mediatek,vcodec-encoder: Add MT8196
media: mediatek: encoder: Add new platform data members
media: mediatek: encoder: Add a new encoder driver interface
media: mediatek: encoder: Add support for common firmware interface
media: mediatek: encoder: Add support for VCP encode process
media: mediatek: encoder: Add MT8196 encoder compatible data
.../media/mediatek,vcodec-encoder.yaml | 22 +
.../mediatek/vcodec/common/mtk_vcodec_fw.c | 9 +-
.../mediatek/vcodec/common/mtk_vcodec_fw.h | 1 +
.../vcodec/common/mtk_vcodec_fw_priv.h | 1 +
.../vcodec/common/mtk_vcodec_fw_vcp.c | 6 +
.../platform/mediatek/vcodec/encoder/Makefile | 1 +
.../mediatek/vcodec/encoder/mtk_vcodec_enc.c | 36 +-
.../vcodec/encoder/mtk_vcodec_enc_drv.c | 62 +-
.../vcodec/encoder/mtk_vcodec_enc_drv.h | 23 +-
.../vcodec/encoder/venc/venc_common_if.c | 684 ++++++++++++++++++
.../vcodec/encoder/venc/venc_h264_if.c | 8 +-
.../mediatek/vcodec/encoder/venc_drv_if.c | 3 +-
.../mediatek/vcodec/encoder/venc_drv_if.h | 11 +-
.../mediatek/vcodec/encoder/venc_ipi_msg.h | 26 +
.../mediatek/vcodec/encoder/venc_vpu_if.c | 47 +-
15 files changed, 869 insertions(+), 71 deletions(-)
create mode 100644 drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
--
2.45.2
^ permalink raw reply
* Re: [PATCH v1] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Vladimir Murzin @ 2026-06-05 9:26 UTC (permalink / raw)
To: Shanker Donthineni, Catalin Marinas, Will Deacon,
linux-arm-kernel
Cc: Mark Rutland, linux-kernel, linux-doc, Vikram Sethi,
Jason Sequeira
In-Reply-To: <20260604231254.1904988-1-sdonthineni@nvidia.com>
On 6/5/26 00:12, Shanker Donthineni wrote:
> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
> observed by a peripheral before an older, non-overlapping Device-nGnR*
> store to the same peripheral. This breaks the program-order guarantee
> that software expects for Device-nGnR* accesses and can leave a
> peripheral in an incorrect state, as a load is observed before an
> earlier store takes effect.
>
> The erratum can occur only when all of the following apply:
>
> - A PE executes a Device-nGnR* store followed by a younger
> Device-nGnR* load.
> - The store is not a store-release.
> - The accesses target the same peripheral and do not overlap in bytes.
> - There is at most one intervening Device-nGnR* store in program
> order, and there are no intervening Device-nGnR* loads.
> - There is no DSB, and no DMB that orders loads, between the store and
> the load.
> - Specific micro-architectural and timing conditions occur.
>
> Two ways to restore ordering: insert a barrier (any DSB, or a DMB that
> orders loads) between the store and the load, or make the store a
> store-release. A load-acquire on the load side would not help, because
> acquire semantics do not prevent a load from being observed ahead of an
> older store; only the store side (release or a barrier) closes the
> window.
>
> Promote the raw MMIO store helpers (__raw_writeb/w/l/q) from plain str*
> to stlr* (Store-Release), which removes the "store is not a
> store-release" condition for every device write the kernel issues.
> Because writel() and writel_relaxed() are both built on __raw_writel()
> in asm-generic/io.h, patching the raw variants covers both the
> non-relaxed and relaxed APIs without touching the higher layers. Note
> that writel()'s own barrier sits before the store, so it does not order
> the store against a subsequent readl(); the store-release promotion is
> what provides that ordering.
>
> Like ARM64_ERRATUM_832075 on the load side, the change is gated on a new
> ARM64_WORKAROUND_DEVICE_STORE_RELEASE capability and only activated on
> parts that match MIDR_NVIDIA_OLYMPUS, so unaffected CPUs continue to use
> the plain str* sequence.
>
> Co-developed-by: Vikram Sethi <vsethi@nvidia.com>
> Signed-off-by: Vikram Sethi <vsethi@nvidia.com>
> Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
> ---
> Documentation/arch/arm64/silicon-errata.rst | 2 ++
> arch/arm64/Kconfig | 23 ++++++++++++++++++++
> arch/arm64/include/asm/io.h | 24 ++++++++++++++-------
> arch/arm64/kernel/cpu_errata.c | 8 +++++++
> arch/arm64/tools/cpucaps | 1 +
> 5 files changed, 50 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index 211119ce7adc..899bed3908bb 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -256,6 +256,8 @@ stable kernels.
> +----------------+-----------------+-----------------+-----------------------------+
> | NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
> +----------------+-----------------+-----------------+-----------------------------+
> +| NVIDIA | Olympus core | T410-OLY-1027 | NVIDIA_OLYMPUS_1027_ERRATUM |
> ++----------------+-----------------+-----------------+-----------------------------+
> | NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
> +----------------+-----------------+-----------------+-----------------------------+
> | NVIDIA | T241 MPAM | T241-MPAM-1 | N/A |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fe60738e5943..a6bac84b05a1 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -564,6 +564,29 @@ config ARM64_ERRATUM_832075
>
> If unsure, say Y.
>
> +config NVIDIA_OLYMPUS_1027_ERRATUM
> + bool "NVIDIA Olympus: device store/load ordering erratum"
> + default y
> + help
> + This option adds an alternative code sequence to work around an
> + NVIDIA Olympus core erratum where a Device-nGnR* store can be
> + observed by a peripheral after a younger Device-nGnR* load to the
> + same peripheral. This breaks the program order that drivers rely
> + on for MMIO and can leave a device in an incorrect state.
> +
> + The workaround promotes the raw MMIO store helpers
> + (__raw_writeb/w/l/q) to Store-Release (STLR), which restores the
> + required ordering. Because writel() and writel_relaxed() are built
> + on __raw_writel(), both are covered without changes to the higher
> + layers.
> +
> + The fix is applied through the alternatives framework, so enabling
> + this option does not by itself activate the workaround: it is
> + patched in only when an affected CPU is detected, and is a no-op on
> + unaffected CPUs.
> +
> + If unsure, say Y.
> +
> config ARM64_ERRATUM_834220
> bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
> depends on KVM
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 8cbd1e96fd50..b6d7966e9c19 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -25,29 +25,37 @@
> #define __raw_writeb __raw_writeb
> static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
> {
> - volatile u8 __iomem *ptr = addr;
> - asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));
> + asm volatile(ALTERNATIVE("strb %w0, [%1]",
> + "stlrb %w0, [%1]",
> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
> + : : "rZ" (val), "r" (addr));
> }
>
Nitpick:
The change has the side effect of undoing d044d6ba6f02 ("arm64:
io: permit offset addressing"), since stlr* do not support
offset addressing. Unaffected CPUs would continue to use str*,
but would lose the benefit of offset addressing :(
Not sure if this needs to be mentioned in the commit message...
Cheers
Vladimir
> #define __raw_writew __raw_writew
> static __always_inline void __raw_writew(u16 val, volatile void __iomem *addr)
> {
> - volatile u16 __iomem *ptr = addr;
> - asm volatile("strh %w0, %1" : : "rZ" (val), "Qo" (*ptr));
> + asm volatile(ALTERNATIVE("strh %w0, [%1]",
> + "stlrh %w0, [%1]",
> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
> + : : "rZ" (val), "r" (addr));
> }
>
> #define __raw_writel __raw_writel
> static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr)
> {
> - volatile u32 __iomem *ptr = addr;
> - asm volatile("str %w0, %1" : : "rZ" (val), "Qo" (*ptr));
> + asm volatile(ALTERNATIVE("str %w0, [%1]",
> + "stlr %w0, [%1]",
> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
> + : : "rZ" (val), "r" (addr));
> }
>
> #define __raw_writeq __raw_writeq
> static __always_inline void __raw_writeq(u64 val, volatile void __iomem *addr)
> {
> - volatile u64 __iomem *ptr = addr;
> - asm volatile("str %x0, %1" : : "rZ" (val), "Qo" (*ptr));
> + asm volatile(ALTERNATIVE("str %x0, [%1]",
> + "stlr %x0, [%1]",
> + ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
> + : : "rZ" (val), "r" (addr));
> }
>
> #define __raw_readb __raw_readb
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 5377e4c2eba2..958d7f16bfeb 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -809,6 +809,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL),
> },
> #endif
> +#ifdef CONFIG_NVIDIA_OLYMPUS_1027_ERRATUM
> + {
> + /* NVIDIA Olympus core */
> + .desc = "NVIDIA Olympus device load/store ordering erratum",
> + .capability = ARM64_WORKAROUND_DEVICE_STORE_RELEASE,
> + ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_OLYMPUS),
> + },
> +#endif
> #ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> {
> /*
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 811c2479e82d..d367257bf770 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -120,6 +120,7 @@ WORKAROUND_CAVIUM_TX2_219_PRFM
> WORKAROUND_CAVIUM_TX2_219_TVM
> WORKAROUND_CLEAN_CACHE
> WORKAROUND_DEVICE_LOAD_ACQUIRE
> +WORKAROUND_DEVICE_STORE_RELEASE
> WORKAROUND_NVIDIA_CARMEL_CNP
> WORKAROUND_PMUV3_IMPDEF_TRAPS
> WORKAROUND_QCOM_FALKOR_E1003
> -- 2.43.0
>
^ permalink raw reply
* Re: [PATCH v2 3/5] dt-bindings: clock: cix,sky1-audss-clock: add audss clock controller
From: Krzysztof Kozlowski @ 2026-06-05 9:24 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt,
p.zabel, gary.yang
Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260605032225.523669-4-joakim.zhang@cixtech.com>
On 05/06/2026 05:22, joakim.zhang@cixtech.com wrote:
> +description: |
> + Clock provider for the Cix Sky1 audio subsystem (AUDSS).
> +
> + This node is a child of a cix,sky1-audss-system-control MFD/syscon node
> + (see cix,sky1-system-control.yaml). It does not have a reg property; clock
> + mux, divider and gate fields are accessed through the parent register block.
> +
> + Software reset lines for AUDSS blocks are exposed on the parent syscon via
> + #reset-cells. Reset indices are defined in
> + include/dt-bindings/reset/cix,sky1-audss-system-control.h.
> +
> + Six SoC-level reference clocks listed in clocks/clock-names feed the AUDSS
> + clock tree. The provider exposes the internal AUDSS clocks to other devices
> + via #clock-cells; indices are defined in cix,sky1-audss.h.
> +
> +properties:
> + compatible:
> + const: cix,sky1-audss-clock
> +
> + '#clock-cells':
> + const: 1
> + description:
> + Clock indices are defined in include/dt-bindings/clock/cix,sky1-audss.h.
> +
> + clocks:
> + minItems: 6
Drop
> + maxItems: 6
> + description:
> + Six SoC-level audio reference clocks that feed the audio subsystem,
> + in the same order as clock-names.
> +
> + clock-names:
> + items:
> + - const: audio_clk0
> + - const: audio_clk1
> + - const: audio_clk2
> + - const: audio_clk3
> + - const: audio_clk4
> + - const: audio_clk5
Pretty pointless names. Names matching indexes have no benefits, drop
all of them and instead list items in "clocks" with description.
> +
> + resets:
> + maxItems: 1
> + description: Audio subsystem NoC (or bus) reset line.
> +
> + power-domains:
> + maxItems: 1
> + description: Audio subsystem power domain.
So the clock part has power domain but reset part does not? This is odd.
Especially that parent is audss (right?) and here you describe that this
is audss poer domain.
Same question about resets.
> +
> +required:
> + - compatible
> + - '#clock-cells'
> + - clocks
> + - clock-names
> + - resets
> + - power-domains
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/cix,sky1.h>
> + #include <dt-bindings/reset/cix,sky1-audss-system-control.h>
> + #include <dt-bindings/reset/cix,sky1-s5-system-control.h>
> +
> + audss_syscon: system-controller@7110000 {
> + compatible = "cix,sky1-audss-system-control", "simple-mfd", "syscon";
> + reg = <0x7110000 0x10000>;
> + #reset-cells = <1>;
Drop parent node.
> +
> + audss_clk: clock-controller {
> + compatible = "cix,sky1-audss-clock";
> + power-domains = <&smc_devpd 0>;
> + #clock-cells = <1>;
> + clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, <&scmi_clk CLK_TREE_AUDIO_CLK1>,
> + <&scmi_clk CLK_TREE_AUDIO_CLK2>, <&scmi_clk CLK_TREE_AUDIO_CLK3>,
> + <&scmi_clk CLK_TREE_AUDIO_CLK4>, <&scmi_clk CLK_TREE_AUDIO_CLK5>;
> + clock-names = "audio_clk0", "audio_clk1", "audio_clk2",
> + "audio_clk3", "audio_clk4", "audio_clk5";
> + resets = <&src SKY1_AUDIO_HIFI5_NOC_RESET_N>;
> + };
> + };
> +#define CLK_MCLK4 40
> +
> +#define AUDSS_MAX_CLKS 41
Drop
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 1/5] dt-bindings: soc: cix,sky1-system-control: add audss system control
From: Krzysztof Kozlowski @ 2026-06-05 9:21 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt,
p.zabel, gary.yang
Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <17528d9a-738c-48fe-ac24-b8d90875a74f@kernel.org>
On 05/06/2026 11:18, Krzysztof Kozlowski wrote:
> On 05/06/2026 05:22, joakim.zhang@cixtech.com wrote:
>> compatible:
>> - items:
>> - - enum:
>> - - cix,sky1-system-control
>> - - cix,sky1-s5-system-control
>> - - const: syscon
>> + oneOf:
>> + - items:
>> + - enum:
>> + - cix,sky1-system-control
>> + - cix,sky1-s5-system-control
>> + - const: syscon
>> + - items:
>> + - const: cix,sky1-audss-system-control
>> + - const: simple-mfd
>> + - const: syscon
>>
>> reg:
>> maxItems: 1
>> @@ -27,6 +32,11 @@ properties:
>> '#reset-cells':
>> const: 1
>>
>> + clock-controller:
>> + $ref: /schemas/clock/cix,sky1-audss-clock.yaml#
>> + description:
>> + AUDSS internal clock provider (cix,sky1-audss-system-control only).
>
> Are you sure this patch builds? Your cover letter should explain merging
I am sure it does not...
I recommend switching to compatible-style of defining subnodes in parent
schema which would decouple patches.
example:
https://elixir.bootlin.com/linux/v7.1-rc6/source/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml#L41
> dependencies/strategy/constraints in the first chapter. You start with
> THE MOST important information.
>
> You need to disallow node for other variants.
>
>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 1/5] dt-bindings: soc: cix,sky1-system-control: add audss system control
From: Krzysztof Kozlowski @ 2026-06-05 9:18 UTC (permalink / raw)
To: joakim.zhang, mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt,
p.zabel, gary.yang
Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260605032225.523669-2-joakim.zhang@cixtech.com>
On 05/06/2026 05:22, joakim.zhang@cixtech.com wrote:
> compatible:
> - items:
> - - enum:
> - - cix,sky1-system-control
> - - cix,sky1-s5-system-control
> - - const: syscon
> + oneOf:
> + - items:
> + - enum:
> + - cix,sky1-system-control
> + - cix,sky1-s5-system-control
> + - const: syscon
> + - items:
> + - const: cix,sky1-audss-system-control
> + - const: simple-mfd
> + - const: syscon
>
> reg:
> maxItems: 1
> @@ -27,6 +32,11 @@ properties:
> '#reset-cells':
> const: 1
>
> + clock-controller:
> + $ref: /schemas/clock/cix,sky1-audss-clock.yaml#
> + description:
> + AUDSS internal clock provider (cix,sky1-audss-system-control only).
Are you sure this patch builds? Your cover letter should explain merging
dependencies/strategy/constraints in the first chapter. You start with
THE MOST important information.
You need to disallow node for other variants.
> +
> required:
> - compatible
> - reg
> @@ -40,3 +50,22 @@ examples:
> reg = <0x4160000 0x100>;
> #reset-cells = <1>;
> };
> + - |
> + #include <dt-bindings/reset/cix,sky1-audss-system-control.h>
> +
> + audss_syscon: system-controller@7110000 {
> + compatible = "cix,sky1-audss-system-control", "simple-mfd", "syscon";
> + reg = <0x7110000 0x10000>;
> + #reset-cells = <1>;
> +
> + clock-controller {
> + compatible = "cix,sky1-audss-clock";
> + power-domains = <&smc_devpd 0>;
> + #clock-cells = <1>;
> + clocks = <&scmi_clk 0>, <&scmi_clk 1>, <&scmi_clk 2>,
> + <&scmi_clk 3>, <&scmi_clk 4>, <&scmi_clk 5>;
> + clock-names = "audio_clk0", "audio_clk1", "audio_clk2",
> + "audio_clk3", "audio_clk4", "audio_clk5";
> + resets = <&src 0>;
> + };
> + };
> diff --git a/include/dt-bindings/reset/cix,sky1-audss-system-control.h b/include/dt-bindings/reset/cix,sky1-audss-system-control.h
> new file mode 100644
> index 000000000000..2ebc5c4f10cd
> --- /dev/null
> +++ b/include/dt-bindings/reset/cix,sky1-audss-system-control.h
> @@ -0,0 +1,27 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright 2026 Cix Technology Group Co., Ltd.
> + */
> +#ifndef DT_BINDING_RESET_CIX_SKY1_AUDSS_SYSTEM_CONTROL_H
> +#define DT_BINDING_RESET_CIX_SKY1_AUDSS_SYSTEM_CONTROL_H
> +
> +#define AUDSS_I2S0_SW_RST_N 0
Most likely _N is redundant here. Consumers will ignore it completely
and this is binding used by consumers, not by reset controller.
> +#define AUDSS_I2S1_SW_RST_N 1
> +#define AUDSS_I2S2_SW_RST_N 2
> +#define AUDSS_I2S3_SW_RST_N 3
> +#define AUDSS_I2S4_SW_RST_N 4
> +#define AUDSS_I2S5_SW_RST_N 5
> +#define AUDSS_I2S6_SW_RST_N 6
> +#define AUDSS_I2S7_SW_RST_N 7
> +#define AUDSS_I2S8_SW_RST_N 8
> +#define AUDSS_I2S9_SW_RST_N 9
> +#define AUDSS_WDT_SW_RST_N 10
> +#define AUDSS_TIMER_SW_RST_N 11
> +#define AUDSS_MB0_SW_RST_N 12
> +#define AUDSS_MB1_SW_RST_N 13
> +#define AUDSS_HDA_SW_RST_N 14
> +#define AUDSS_DMAC_SW_RST_N 15
> +
> +#define SKY1_AUDSS_SW_RESET_NUM 16
Drop, not a binding.
> +
> +#endif
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 2/5] dt-bindings: connector: Add fsl,io-connector binding
From: Krzysztof Kozlowski @ 2026-06-05 9:11 UTC (permalink / raw)
To: Frank Li
Cc: Chancel Liu (OSS), Chancel Liu, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, s.hauer@pengutronix.de,
festevam@gmail.com, mturquette@baylibre.com, sboyd@kernel.org,
kernel@pengutronix.de, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org
In-Reply-To: <ah9WzQmwPrP4yWTC@lizhi-Precision-Tower-5810>
On 03/06/2026 00:18, Frank Li wrote:
> On Mon, May 25, 2026 at 02:28:32PM +0200, Krzysztof Kozlowski wrote:
>> On 25/05/2026 08:26, Chancel Liu (OSS) wrote:
>>>>>>>>>>>>> +description:
>>>>>>>>>>>>> + The NXP I/O connector represents a physically present I/O
>>>>>>>>>>>>> +connector on the
>>>>>>>>>>>>> + base board. It acts as a nexus that exposes a constrained
>>>>>>>>>>>>> +set
>>>>>>>> of
>>>>>>>>>>>>> +I/O
>>>>>>>>>>>>> + resources, such as GPIOs, clocks, PWMs and interrupts,
>>>>>>>>>>>>> +through fixed
>>>>>>>>>>>>> + electrical wiring. All actual hardware providers reside on
>>>>>>>>>>>>> +the
>>>>>>>> base
>>>>>>>>>> board.
>>>>>>>>>>>>> + The connector node only defines index-based mappings to
>>>>>>>>>>>>> + those
>>>>>>>>>>>> providers.
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +properties:
>>>>>>>>>>>>> + compatible:
>>>>>>>>>>>>> + const: fsl,io-connector
>>>>>>>>>>>>
>>>>>>>>>>>> Everything is IO. Everything is connector, so your compatible
>>>>>>>>>>>> does not match requirements from writing bindings.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, this compatible is too generic. I will rename the
>>>>>>>>>>> compatible to fsl,aud-io-connector.
>>>>>>>>>>
>>>>>>>>>> aud is not much better. Which boards have it? What's the pinout?
>>>>>>>> What's
>>>>>>>>>> standard? Is it described anywhere? If so, provide reference to
>>>>>>>> spec/docs.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This is not an industry standard electrical interface. This
>>>>>>>>> connector
>>>>>>>>
>>>>>>>> Then if you do not have standard, then you have board specific
>>>>>>>> layouts thus you need board-specific compatibles. You can use
>>>>>>>> fallbacks. Generic fallback could work, but both io-connector and
>>>>>>>> aud-io-connector are just too generic. Every connector is
>>>>>>>> "connector" and "io", thus absolutely anything can be
>>>>>>>> "io-connector". "aud" improves it only a bit, thus honestly I would
>>>> go with board specific fallback as well.
>>>>>>>>
>>>>>>>
>>>>>>> How about board specific + common fallback compatible like this:
>>>>>>> compatible:
>>>>>>> items:
>>>>>>> - enum:
>>>>>>> - fsl,imx95-19x19-evk-aud-io-connector
>>>>>>> - fsl,imx952-evk-aud-io-connector
>>>>>>> - const: fsl,imx-aud-io-connector Since the daughter board is
>>>>>>> named “IMX-AUD-IO” in publicly available
>>>>>>
>>>>>> I don't think it is named like that.
>>>>>>
>>>>>> git grep -i imx-aud-io
>>>>>>
>>>>>>> documentation, common compatible clearly indicates that this
>>>>>>> connector is intended for that.
>>>>>>>
>>>>>>> Also, I want to talk about the topic of generic connector. It's a
>>>>>>> common design that daughter board is connected to base board through
>>>>>>> a connector. This connector more often acts as a nexus that exposes
>>>>>>> a constrained subset of GPIO, clock, PWM and interrupt resources to
>>>>>>> the daughter board. Can we document this kind of connector as a
>>>>>>> generic binding?
>>>>>>
>>>>>> So this binding is the connector between carrier and some addon? Then
>>>>>> you don't get a compatible for that at all, because it is not
>>>>>> necessary, not useful and NEVER used. Do you see socket LGA "connector"
>>>> bindings? No.
>>>>>
>>>>> Not exactly. Any connector connects a carrier board with an add-on
>>>> board.
>>>>> The key point here is that this connector type is reused across
>>>>> different boards, even though it is not an industry-standard
>>>>> connector. Both the signal definitions and the mechanical layout are
>>>> defined.
>>>>>
>>>>> The same add-on boards can therefore be reused across different base
>>>>> boards that use this type of connector.
>>>>>
>>>>> There are also GPIO mappings involved. For example, pin 1 on the
>>>>> connector may represent reset-gpios, but it could be connected to
>>>>> GPIO0 on board A and GPIO1 on board B.
>>>>>
>>>>> Without a connector definition layer, this would create an N × M
>>>>> combination problem. The Nexus node discussion already covered this
>>>> topic:
>>>>> https://osseu2025.sched.com/event/25Vrw
>>>>>
>>>>> An LGA socket is a CPU socket, where the signals are completely
>>>>> transparent to software, so it is not a good comparison. A PCIe M.2
>>>>> Key-M/E connector would be a more appropriate comparison.
>>>>>
>>>>
>>>> So the terminology of daughter and carrier boards was confusing. If this
>>>> is a hat, mezzanine or other addon, it's fine.
>>>>
>>>
>>> The IMX-AUD-IO is an add-on board that attaches to the base board. To
>>> make it clearer, I will replace "daughter board" with "add-on board"
>>> throughout descriptions.
>>>
>>>> I still insist on board specific compatibles - fallback and specific.
>>>>
>>>
>>> The base board has a slot component that is mechanically compatible
>>> with a PCIe x8 connector. However, it carries no PCIe signals and the
>>> pins are repurposed to carry fixed board-level audio I/O related
>>> signals.
>>>
>>> I think we can name a compatible reflects a standard mechanical form
>>> factor.
>>> For the compatibles (specific + fallback) I propose:
>>> - enum:
>>> - fsl,imx95-19x19-evk-aud-io-pcie-x8-slot
>>> - fsl,imx952-evk-aud-io-pcie-x8-slot
>>> - const: fsl,aud-io-pcie-x8-slot
>>
>> Does not solve my request, so I won't ack it. Maybe you will get ack
>> from other DT maintainer then.
>
> Krzysztof:
> Thank you for your support. This type header/slot is difficult to
> name it.
>
> After read again previous comments
>
> "Then if you do not have standard, then you have board specific layouts
> thus you need board-specific compatibles. You can use fallbacks. Generic
> fallback could work, but both io-connector and aud-io-connector are just
> too generic. Every connector is "connector" and "io", thus absolutely
> anything can be "io-connector". "aud" improves it only a bit, thus
> honestly I would go with board specific fallback as well."
>
> Do you means
> oneOf
> - items:
> - enum:
> - fsl,imx943-evk-aud-io-pcie-x8-slot
> - fsl,imx952-evk-aud-io-pcie-x8-slot
> - const: fsl,imx95-19x19-evk-aud-io-pcie-x8-slot
> - const: fsl,imx95-19x19-evk-aud-io-pcie-x8-slot
Yes, could be a bit shorter like fsl,imx95-19x19-evk-aud-io-slot or even
without slot because prefixing it with board compatible makes it very
specific.
>
> Frank
>
>>
>> Best regards,
>> Krzysztof
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v1] EDAC/synopsys: Fix cleanup on injection sysfs failure
From: Michal Simek @ 2026-06-05 9:03 UTC (permalink / raw)
To: Yuho Choi, Borislav Petkov, Tony Luck
Cc: linux-edac, linux-arm-kernel, linux-kernel
In-Reply-To: <20260603204721.2200819-1-dbgh9129@gmail.com>
On 6/3/26 22:47, Yuho Choi wrote:
> edac_create_sysfs_attributes() creates inject_data_error before
> inject_data_poison. If the second file creation fails, the first file is
> left behind.
>
> The same failure path runs after edac_mc_add_mc() has registered the
> memory controller with the EDAC core. Jumping directly to edac_mc_free()
> skips edac_mc_del_mc() and leaves the registered controller state
> unwound incorrectly.
>
> Remove inject_data_error when inject_data_poison creation fails, and
> route the probe failure through edac_mc_del_mc() before freeing mci.
>
> Fixes: 1a81361f75d8 ("EDAC, synopsys: Add Error Injection support for ZynqMP DDR controller")
> Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
> ---
> drivers/edac/synopsys_edac.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
> index 51143b3257de..c395a1e97a36 100644
> --- a/drivers/edac/synopsys_edac.c
> +++ b/drivers/edac/synopsys_edac.c
> @@ -1120,8 +1120,10 @@ static int edac_create_sysfs_attributes(struct mem_ctl_info *mci)
> if (rc < 0)
> return rc;
> rc = device_create_file(&mci->dev, &dev_attr_inject_data_poison);
> - if (rc < 0)
> + if (rc < 0) {
> + device_remove_file(&mci->dev, &dev_attr_inject_data_error);
> return rc;
> + }
> return 0;
> }
>
> @@ -1431,7 +1433,7 @@ static int mc_probe(struct platform_device *pdev)
> if (rc) {
> edac_printk(KERN_ERR, EDAC_MC,
> "Failed to create sysfs entries\n");
> - goto free_edac_mc;
> + goto del_mc;
> }
> }
>
> @@ -1448,6 +1450,10 @@ static int mc_probe(struct platform_device *pdev)
>
> return rc;
>
> +#ifdef CONFIG_EDAC_DEBUG
I don't think this is nice way how to do it. I would do it above to avoid using
ifdefs here.
like this
if (rc) {
edac_printk(KERN_ERR, EDAC_MC,
"Failed to create sysfs entries\n");
edac_mc_del_mc(&pdev->dev);
goto free_edac_mc;
}
}
The patch itself is correct.
Thanks,
Michal
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx93-11x11-frdm: enable additional devices
From: Joseph Guo @ 2026-06-05 8:59 UTC (permalink / raw)
To: Francesco Valla
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Daniel Baluta, devicetree, imx, linux-arm-kernel, linux-kernel,
steven.yang
In-Reply-To: <20260115-imx93_devices-v1-1-b2c840cafa2e@valla.it>
On Thu, Jan 15, 2026 at 06:11:34PM +0100, Francesco Valla wrote:
> Enable additional devices on the i.MX93 FRDM board:
>
> - CAN port and associated transceiver
> - Bluetooth portion of the IW612 chipset
> - WiFi SDIO port
> - user buttons
>
> The WiFi portion of the on-board IW612 chipset is still not supported
> upstream, but since SDIO is a discoverable bus it will be probed once it
> is.
>
> Signed-off-by: Francesco Valla <francesco@valla.it>
> ---
> Applies on top of [0].
>
> WiFi was tested using the nxpwifi driver proposed in [1].
>
> [0] https://lore.kernel.org/all/20260113075002.561453-1-daniel.baluta@nxp.com/
> [1] https://lore.kernel.org/all/20251205065545.3325032-1-jeff.chen_1@nxp.com/
>
> Reagrds,
> Francesco
> ---
> arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts | 152 +++++++++++++++++++++
> 1 file changed, 152 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> index 5bb6ae0d154a655283295b6902fc29bf6f744d5c..bd14ba28690c081817111aaabef12fb56a7c56a4 100644
> --- a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> @@ -9,6 +9,7 @@ / {
> model = "NXP i.MX93 11X11 FRDM board";
>
> aliases {
> + can0 = &flexcan2;
> ethernet0 = &fec;
> ethernet1 = &eqos;
> i2c0 = &lpi2c1;
> @@ -18,12 +19,40 @@ aliases {
> mmc1 = &usdhc2; /* uSD */
> rtc0 = &pcf2131;
> serial0 = &lpuart1;
> + serial4 = &lpuart5;
> };
>
> chosen {
> stdout-path = &lpuart1;
> };
>
> + flexcan2_phy: can-phy {
> + compatible = "nxp,tja1051";
> + #phy-cells = <0>;
> + max-bitrate = <5000000>;
> + silent-gpios = <&pcal6524 23 GPIO_ACTIVE_HIGH>;
> + };
> +
> + gpio-keys {
> + compatible = "gpio-keys";
> +
> + button-k2 {
> + label = "Button K2";
> + linux,code = <BTN_1>;
> + gpios = <&pcal6524 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
> + interrupt-parent = <&pcal6524>;
> + interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
> + };
> +
> + button-k3 {
> + label = "Button K3";
> + linux,code = <BTN_2>;
> + gpios = <&pcal6524 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
> + interrupt-parent = <&pcal6524>;
> + interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
> + };
> + };
> +
> reg_usdhc2_vmmc: regulator-usdhc2 {
> compatible = "regulator-fixed";
> off-on-delay-us = <12000>;
> @@ -37,6 +66,16 @@ reg_usdhc2_vmmc: regulator-usdhc2 {
> enable-active-high;
> };
>
> + reg_usdhc3_vmmc: regulator-usdhc3 {
> + compatible = "regulator-fixed";
> + regulator-name = "VPCIe_3V3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + startup-delay-us = <20000>;
> + gpio = <&pcal6524 13 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> +
> reserved-memory {
> ranges;
> #address-cells = <2>;
> @@ -88,6 +127,11 @@ sound-mqs {
> audio-cpu = <&sai1>;
> audio-codec = <&mqs1>;
> };
> +
> + usdhc3_pwrseq: mmc-pwrseq {
> + compatible = "mmc-pwrseq-simple";
> + reset-gpios = <&pcal6524 12 GPIO_ACTIVE_LOW>;
> + };
> };
>
> &adc1 {
> @@ -157,11 +201,27 @@ ethphy2: ethernet-phy@2 {
> };
> };
>
> +&flexcan2 {
> + phys = <&flexcan2_phy>;
> + pinctrl-0 = <&pinctrl_flexcan2>;
> + pinctrl-1 = <&pinctrl_flexcan2_sleep>;
> + pinctrl-names = "default", "sleep";
> + status = "okay";
> +};
> +
> &lpi2c1 {
> clock-frequency = <400000>;
> pinctrl-0 = <&pinctrl_lpi2c1>;
> pinctrl-names = "default";
> status = "okay";
> +
> + pcal6408: gpio@20 {
> + compatible = "nxp,pcal6408";
> + reg = <0x20>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + reset-gpios = <&pcal6524 20 GPIO_ACTIVE_LOW>;
> + };
> };
>
> &lpi2c2 {
> @@ -322,6 +382,21 @@ &lpuart1 { /* console */
> status = "okay";
> };
>
> +&lpuart5 {
> + pinctrl-0 = <&pinctrl_uart5>;
> + pinctrl-names = "default";
> + status = "okay";
> +
> + uart-has-rtscts;
> +
> + bluetooth {
> + compatible = "nxp,88w8987-bt";
> + device-wakeup-gpios = <&pcal6408 3 GPIO_ACTIVE_HIGH>;
> + reset-gpios = <&pcal6524 19 GPIO_ACTIVE_LOW>;
> + vcc-supply = <®_usdhc3_vmmc>;
> + };
> +};
Hi Francesco,
Do you ever tried bluetooth feature? The bluetooth failed to scan with 'device-wakeup-gpios' property.
Regards,
Joseph
> +
> &mqs1 {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_mqs1>;
> @@ -394,6 +469,20 @@ &usdhc2 {
> status = "okay";
> };
>
> +&usdhc3 {
> + bus-width = <4>;
> + keep-power-in-suspend;
> + mmc-pwrseq = <&usdhc3_pwrseq>;
> + non-removable;
> + pinctrl-0 = <&pinctrl_usdhc3>;
> + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
> + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
> + pinctrl-3 = <&pinctrl_usdhc3_sleep>;
> + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
> + vmmc-supply = <®_usdhc3_vmmc>;
> + status = "okay";
> +};
> +
> &wdog3 {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_wdog>;
> @@ -486,6 +575,13 @@ MX93_PAD_GPIO_IO27__CAN2_RX 0x139e
> >;
> };
>
> + pinctrl_flexcan2_sleep: flexcan2sleepgrp {
> + fsl,pins = <
> + MX93_PAD_GPIO_IO25__GPIO2_IO25 0x31e
> + MX93_PAD_GPIO_IO27__GPIO2_IO27 0x31e
> + >;
> + };
> +
> pinctrl_lpi2c1: lpi2c1grp {
> fsl,pins = <
> MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e
> @@ -533,6 +629,15 @@ MX93_PAD_UART1_TXD__LPUART1_TX 0x31e
> >;
> };
>
> + pinctrl_uart5: uart5grp {
> + fsl,pins = <
> + MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e
> + MX93_PAD_DAP_TDI__LPUART5_RX 0x31e
> + MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e
> + MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e
> + >;
> + };
> +
> /* need to config the SION for data and cmd pad, refer to ERR052021 */
> pinctrl_usdhc1: usdhc1grp {
> fsl,pins = <
> @@ -647,6 +752,53 @@ MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e
> >;
> };
>
> + /* need to config the SION for data and cmd pad, refer to ERR052021 */
> + pinctrl_usdhc3: usdhc3grp {
> + fsl,pins = <
> + MX93_PAD_SD3_CLK__USDHC3_CLK 0x1582
> + MX93_PAD_SD3_CMD__USDHC3_CMD 0x40001382
> + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x40001382
> + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x40001382
> + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x40001382
> + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x40001382
> + >;
> + };
> +
> + /* need to config the SION for data and cmd pad, refer to ERR052021 */
> + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
> + fsl,pins = <
> + MX93_PAD_SD3_CLK__USDHC3_CLK 0x158e
> + MX93_PAD_SD3_CMD__USDHC3_CMD 0x4000138e
> + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x4000138e
> + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x4000138e
> + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x4000138e
> + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x4000138e
> + >;
> + };
> +
> + /* need to config the SION for data and cmd pad, refer to ERR052021 */
> + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
> + fsl,pins = <
> + MX93_PAD_SD3_CLK__USDHC3_CLK 0x15fe
> + MX93_PAD_SD3_CMD__USDHC3_CMD 0x400013fe
> + MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe
> + MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe
> + MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe
> + MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe
> + >;
> + };
> +
> + pinctrl_usdhc3_sleep: usdhc3grpsleepgrp {
> + fsl,pins = <
> + MX93_PAD_SD3_CLK__GPIO3_IO20 0x31e
> + MX93_PAD_SD3_CMD__GPIO3_IO21 0x31e
> + MX93_PAD_SD3_DATA0__GPIO3_IO22 0x31e
> + MX93_PAD_SD3_DATA1__GPIO3_IO23 0x31e
> + MX93_PAD_SD3_DATA2__GPIO3_IO24 0x31e
> + MX93_PAD_SD3_DATA3__GPIO3_IO25 0x31e
> + >;
> + };
> +
> pinctrl_wdog: wdoggrp {
> fsl,pins = <
> MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e
>
> ---
> base-commit: 8ce368ca61310f425012fea4549d2b6ad0c5c54c
> change-id: 20260114-imx93_devices-a98e116463b3
>
> Best regards,
> --
> Francesco Valla <francesco@valla.it>
>
^ permalink raw reply
* Re: [PATCH v2 2/2] KVM: arm64: Bound used_lrs when flushing the pKVM hyp vCPU
From: Marc Zyngier @ 2026-06-05 8:58 UTC (permalink / raw)
To: Hyunwoo Kim
Cc: tabba, oupton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, linux-arm-kernel, kvmarm
In-Reply-To: <20260604151210.1304051-3-imv4bel@gmail.com>
On Thu, 04 Jun 2026 16:12:03 +0100,
Hyunwoo Kim <imv4bel@gmail.com> wrote:
>
> flush_hyp_vcpu() copies the host vGIC state into the hyp's private vCPU
> on every run. The vGIC list register save and restore use used_lrs as
> their loop bound and expect it to stay within the number of implemented
> list registers. While this is generally the case, flush_hyp_vcpu()
> copies vgic_v3 verbatim and does not enforce this, so a value provided
> by the host is used at EL2 to index vgic_lr[] and access ICH_LR<n>_EL2
> (host -> EL2).
>
> Fix by clamping used_lrs to the number of implemented list registers
> after the copy, as the trusted path already does in
> vgic_flush_lr_state().
>
> Fixes: be66e67f1750 ("KVM: arm64: Use the pKVM hyp vCPU structure in handle___kvm_vcpu_run()")
> Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
> ---
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 02c5d6e5abcbf..cd807fdb11ba8 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -7,6 +7,7 @@
> #include <hyp/adjust_pc.h>
> #include <hyp/switch.h>
>
> +#include <asm/arch_gicv3.h>
> #include <asm/pgtable-types.h>
> #include <asm/kvm_asm.h>
> #include <asm/kvm_emulate.h>
> @@ -142,6 +143,13 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>
> hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3 = host_vcpu->arch.vgic_cpu.vgic_v3;
>
> + /* Bound used_lrs by the number of implemented list registers. */
> + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
There is no pKVM support without a GICv3 CPU interface, and absolutely
everything already assumes it. Why do we need this extra check?
> + hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3.used_lrs =
> + min_t(unsigned int,
> + hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3.used_lrs,
> + (read_gicreg(ICH_VTR_EL2) & 0xf) + 1);
> +
Reading ICH_VTR_EL2 on each entry is going to cause some really heavy
trapping under NV, and we should avoid this.
kvm_vgic_global_state.nr_lr contains this information, and it should
only be a matter of replicating it (or compute it once) at init time.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH] KVM: arm64: vgic: Check the interrupt is still ours before migrating it
From: Oliver Upton @ 2026-06-05 8:43 UTC (permalink / raw)
To: Marc Zyngier
Cc: Hyunwoo Kim, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, Sascha.Bischoff, jic23, timothy.hayes,
eric.auger, christoffer.dall, andre.przywara, linux-arm-kernel,
kvmarm
In-Reply-To: <87ecila0w3.wl-maz@kernel.org>
On Fri, Jun 05, 2026 at 08:42:52AM +0100, Marc Zyngier wrote:
> On Fri, 05 Jun 2026 07:00:37 +0100,
> Oliver Upton <oupton@kernel.org> wrote:
> >
> > On Fri, Jun 05, 2026 at 05:59:15AM +0900, Hyunwoo Kim wrote:
> > > vgic_prune_ap_list() drops both ap_list_lock and irq_lock while migrating
> > > an interrupt to another vCPU. After reacquiring the locks it only checks
> > > that the affinity is unchanged (target_vcpu == vgic_target_oracle(irq))
> > > before moving the interrupt, which assumes that an interrupt whose affinity
> > > is preserved is still queued on this vCPU's ap_list.
> > >
> > > That assumption no longer holds if the interrupt is taken off the ap_list
> > > while the locks are dropped. vgic_flush_pending_lpis() removes the
> > > interrupt from the list and sets irq->vcpu to NULL, but leaves
> > > enabled/pending/target_vcpu untouched. As the interrupt is still enabled
> > > and pending, vgic_target_oracle() returns the same target_vcpu, so the
> > > affinity check passes and list_del() is run a second time on an entry that
> > > has already been removed.
> > >
> > > Also check that the interrupt is still assigned to this vCPU
> > > (irq->vcpu == vcpu) before moving it.
> > >
> > > Fixes: 0919e84c0fc1 ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
> > > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
> >
> > Looking at this and the other VGIC patch you sent (which should've been
> > a combined series), are you trying to deal with a vCPU writing to
> > another vCPU's redistributor? I.e. vCPU B setting GICR_CTLR.EnableLPIs=0
> > behind the back of vCPU A?
> >
> > That is extremely relevant information as the off-the-cuff reaction is
> > that no race exists. But since the GIC architecture is awesome and
> > allows for this sort of insanity, it obviously does....
> >
> > Anyway, for LPIs resident on a particular RD, there's zero expectation
> > that the pending state is preserved when EnableLPIs=0. So I'd rather
> > vgic_flush_pending_lpis() just invalidate the pending state.
>
> Just clearing the pending state introduces a potential problem as we
> now have an interrupt that is neither active nor pending on the AP
> list. It is not impossible to solve (we now have similar behaviours
> with SPI deactivation from another vcpu), but that requires posting a
> KVM_REQ_VGIC_PROCESS_UPDATE to the target vcpu.
Right, I was suggesting that in addition to deleting the LPI from the AP
list we actually invalidate the pending state so that someone sitting on
a pointer to a to-be-freed LPI sees vgic_target_oracle() returning
NULL
> > Beyond that, I see two other fixes for lifetime issues around the
> > vgic_irq in the middle of migration. I'd like to see explicit RCU
> > protection around the release && reacquire of the ap_list_lock rather
> > than depending on the precondition that IRQs are disabled.
>
> I'm not sure I follow. Are you suggesting turning the AP list into an
> RCU protected list?
No, sorry, I should expand a little.
We store a reference on the vgic_irq struct in the AP list, which is
stable so long as the ap_list_lock is held. It should be possible for
the refcount to drop to 0 between releasing the ap_list_lock and
reacquiring it.
So either vgic_prune_ap_list() takes an additional reference on the
vgic_irq before dropping the ap_list_lock or rely on RCU to protect
vgic_irq structs observed with a non-zero refcount.
Thanks,
Oliver
^ permalink raw reply
* [GIT,PULL] arm64: dts: hisilicon dts updates for v7.2
From: Wei Xu @ 2026-06-05 8:35 UTC (permalink / raw)
To: soc, arm
Cc: linux-arm-kernel, Arnd Bergmann, xuwei5, zhangyi.ac,
Wuliebao (Joab, Turing Solution), Shenqingchun(DanielShen),
huangdaode, liguozhu, Zengtao (B), Akash Sukhavasi
Hi ARM SoC maintainers,
Please consider to pull the following changes.
Thanks!
Best Regards,
Wei
---
The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
are available in the Git repository at:
https://github.com/hisilicon/linux-hisi.git tags/hisi-arm64-dt-for-7.2
for you to fetch changes up to b54fcf7a2df1124a21195afde508369e47067a1f:
arm64: dts: hisilicon: hi3660-hikey960: move role-switch endpoint into connector (2026-06-04 15:23:27 +0800)
----------------------------------------------------------------
ARM64: DT: HiSilicon ARM64 DT updates for v7.2
- Move role-switch endpoint into connector on hi3660-hikey960
----------------------------------------------------------------
Akash Sukhavasi (1):
arm64: dts: hisilicon: hi3660-hikey960: move role-switch endpoint into connector
arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
^ permalink raw reply
* Re: [PATCH v3 3/5] KVM: arm64: Add support for FEAT_HDBSS
From: Tian Zheng @ 2026-06-05 8:29 UTC (permalink / raw)
To: Inochi Amaoto, Marc Zyngier
Cc: oupton, catalin.marinas, corbet, pbonzini, will, yuzenghui,
wangzhou1, liuyonglong, Jonathan.Cameron, yezhenyu2, linuxarm,
joey.gouly, kvmarm, kvm, linux-arm-kernel, linux-doc,
linux-kernel, skhan, suzuki.poulose, leo.bras
In-Reply-To: <ah1KLrpYBXSMM91H@inochi.infowork>
On 6/1/2026 5:05 PM, Inochi Amaoto wrote:
> On Mon, Jun 01, 2026 at 09:58:49AM +0100, Marc Zyngier wrote:
>> On Mon, 01 Jun 2026 01:50:22 +0100,
>> Inochi Amaoto <inochiama@gmail.com> wrote:
>>> On Wed, Feb 25, 2026 at 12:04:19PM +0800, Tian Zheng wrote:
>>>> From: eillon <yezhenyu2@huawei.com>
>>>>
>>>> Armv9.5 introduces the Hardware Dirty Bit State Structure (HDBSS) feature,
>>>> indicated by ID_AA64MMFR1_EL1.HAFDBS == 0b0100. A CPU capability is added
>>>> to notify the user of the feature.
>>>>
>>>> Add KVM_CAP_ARM_HW_DIRTY_STATE_TRACK ioctl and basic framework for
>>>> ARM64 HDBSS support. Since the HDBSS buffer size is configurable and
>>>> cannot be determined at KVM initialization, an IOCTL interface is
>>>> required.
>>>>
>>>> Actually exposing the new capability to user space happens in a later
>>>> patch.
>>>>
>>>> Signed-off-by: eillon <yezhenyu2@huawei.com>
>>>> Signed-off-by: Tian Zheng <zhengtian10@huawei.com>
>>>> ---
>>>> arch/arm64/include/asm/cpufeature.h | 5 +++++
>>>> arch/arm64/kernel/cpufeature.c | 12 ++++++++++++
>>>> arch/arm64/tools/cpucaps | 1 +
>>>> include/uapi/linux/kvm.h | 1 +
>>>> tools/include/uapi/linux/kvm.h | 1 +
>>>> 5 files changed, 20 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
>>>> index 4de51f8d92cb..dcc2e2cad5ad 100644
>>>> --- a/arch/arm64/include/asm/cpufeature.h
>>>> +++ b/arch/arm64/include/asm/cpufeature.h
>>>> @@ -856,6 +856,11 @@ static inline bool system_supports_haft(void)
>>>> return cpus_have_final_cap(ARM64_HAFT);
>>>> }
>>>>
>>>> +static inline bool system_supports_hdbss(void)
>>>> +{
>>>> + return cpus_have_final_cap(ARM64_HAS_HDBSS);
>>>> +}
>>>> +
>>>> static __always_inline bool system_supports_mpam(void)
>>>> {
>>>> return alternative_has_cap_unlikely(ARM64_MPAM);
>>>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>>>> index c31f8e17732a..348b0afffc3e 100644
>>>> --- a/arch/arm64/kernel/cpufeature.c
>>>> +++ b/arch/arm64/kernel/cpufeature.c
>>>> @@ -2124,6 +2124,11 @@ static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
>>>> return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
>>>> }
>>>>
>>>> +static bool has_vhe_hdbss(const struct arm64_cpu_capabilities *entry, int cope)
>>>> +{
>>>> + return is_kernel_in_hyp_mode() && has_cpuid_feature(entry, cope);
>>>> +}
>>>> +
>>>> bool cpu_supports_bbml2_noabort(void)
>>>> {
>>>> /*
>>>> @@ -2759,6 +2764,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>>>> ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
>>>> },
>>>> #endif
>>>> + {
>>>> + .desc = "Hardware Dirty state tracking structure (HDBSS)",
>>>> + .type = ARM64_CPUCAP_SYSTEM_FEATURE,
>>>> + .capability = ARM64_HAS_HDBSS,
>>>> + .matches = has_vhe_hdbss,
>>>> + ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HDBSS)
>>>> + },
>>>> {
>>>> .desc = "CRC32 instructions",
>>>> .capability = ARM64_HAS_CRC32,
>>>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>>>> index 7261553b644b..f6ece5b85532 100644
>>>> --- a/arch/arm64/tools/cpucaps
>>>> +++ b/arch/arm64/tools/cpucaps
>>>> @@ -68,6 +68,7 @@ HAS_VA52
>>>> HAS_VIRT_HOST_EXTN
>>>> HAS_WFXT
>>>> HAS_XNX
>>>> +HAS_HDBSS
>>>> HAFT
>>>> HW_DBM
>>>> KVM_HVHE
>>>
>>>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>>>> index 65500f5db379..15ee42cdbd51 100644
>>>> --- a/include/uapi/linux/kvm.h
>>>> +++ b/include/uapi/linux/kvm.h
>>>> @@ -985,6 +985,7 @@ struct kvm_enable_cap {
>>>> #define KVM_CAP_ARM_SEA_TO_USER 245
>>>> #define KVM_CAP_S390_USER_OPEREXEC 246
>>>> #define KVM_CAP_S390_KEYOP 247
>>>> +#define KVM_CAP_ARM_HW_DIRTY_STATE_TRACK 248
>>>>
>>>> struct kvm_irq_routing_irqchip {
>>>> __u32 irqchip;
>>>> diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
>>>> index dddb781b0507..93e0a1e14dc7 100644
>>>> --- a/tools/include/uapi/linux/kvm.h
>>>> +++ b/tools/include/uapi/linux/kvm.h
>>>> @@ -974,6 +974,7 @@ struct kvm_enable_cap {
>>>> #define KVM_CAP_GUEST_MEMFD_FLAGS 244
>>>> #define KVM_CAP_ARM_SEA_TO_USER 245
>>>> #define KVM_CAP_S390_USER_OPEREXEC 246
>>>> +#define KVM_CAP_ARM_HW_DIRTY_STATE_TRACK 248
>>>>
>>>> struct kvm_irq_routing_irqchip {
>>>> __u32 irqchip;
>>>> --
>>>> 2.33.0
>>>>
>>> Instead of having these architecture specific capability, I wonder if
>>> we can add a generic capability like "KVM_CAP_HW_DIRTY_STATE", so
>>> other architecture supports similar things can reuse this capability,
>> What of the existing stuff doing the same thing? x86's PML, to start
>> with?
>>
> In fact I think the HDBSS is the first one with non-fixed size.
> Although there is a in process RISC-V extension for it, there will
> be a long story to make it ratified.
>
>>> For this generic thing I suggest, the getter returns the max support
>>> entry count (or the buffer size) it supports like the dirty ring
>>> capability. And the setter just let the architecture set the parameters
>>> based on the user request.
>> This looks wrong on a number of levels.
>>
>> - If you want something generic, there is the existing dirty
>> log/bitmap. How this stuff is populated is none of the user's
>> business (trapping write accesses, dirty bit collection from the
>> PTs, or HW-generated log), and we don't need an extra feature for
>> it. Performance will obviously suck, but that's what you pay for
>> something abstracted and cross-architecture.
>>
>> - If you want something architecture specific, then it can't be
>> generic, by definition. You get the raw speed and compatibility with
>> other arch-specific extensions.
>>
> OK, I agree, it is better to keep this thing arch-specific. Doing a
> generic thing does not benefit too much, I have made a mistake on
> it. Thanks for your kindly explanation.
Awesome. Thanks for the review.
I agree with Marc—keeping this ARM-specific is the right approach.
Also, in v4 we're removing the ioctl interface entirely. HDBSS will be
auto-enabled during migration setup and auto-disabled when migration
completes, so the capability naming issue becomes moot.
I plan to post v4 with the updated approach soon.
>>> This should do no harm to this implement, as everything still depends
>>> on the architecture behavior, and leave room for other architecture
>>> to reuse this.
>> Again, the generic framework exists, you just have to implement the
>> backend you want.
>>
>> M.
>>
>> --
>> Without deviation from the norm, progress is not possible.
> Regards,
> Inochi
^ permalink raw reply
* [PATCH v6 3/4] media: uapi: mediatek: Add MT8188 AIE control definitions
From: Sarang Chaudhari @ 2026-06-05 8:29 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
Add AIE (AI Engine) UAPI control definitions and register the
V4L2_META_FMT_MTFD_RESULT metadata format for the MediaTek face
detection hardware accelerator.
This patch adds:
- include/uapi/linux/mtk_aie_v4l2_controls.h: Custom V4L2 control IDs
for AIE initialization and per-frame parameters.
- V4L2_META_FMT_MTFD_RESULT format in videodev2.h for face detection
result metadata output.
- Format description in v4l2-ioctl.c.
Signed-off-by: Sarang Chaudhari <sarang.chaudhari@mediatek.com>
---
Changes in v6:
- Simplify UAPI header to contain only control ID definitions. Full
structures kept in kernel-internal header for now, pending UAPI
structure redesign per CK Hu's feedback.
- Drop V4L2_CTRL_TYPE_AIE_INIT and V4L2_CTRL_TYPE_AIE_PARAM from
v4l2_ctrl_type enum (use V4L2_CTRL_TYPE_U32 compound control instead).
- Address CK Hu's review feedback: remove freq_level, improve
feature_threshold docs, clarify pyramid multi-scale detection, clarify
FLD mode uses FD results via Binary Tree Traversal.
Changes in v5:
- Add an introduction for feature_threshold.
- Rename v4l2_aie_roi to aie_roi_coordinate.
- Rename v4l2_aie_padding to aie_padding_size.
- Explain en_padding and the three modes of fd_mode.
- Move structures from mtk_aie.h to the uapi directory.
Changes in v4:
- Document the detail of V4L2_META_FMT_MTFD_RESULT.
- Add the introduction of related variables.
Changes in v3: None
Changes in v2:
- Fix coding style.
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
include/uapi/linux/mtk_aie_v4l2_controls.h | 23 ++++++++++++++++++++++
include/uapi/linux/videodev2.h | 1 +
3 files changed, 25 insertions(+)
create mode 100644 include/uapi/linux/mtk_aie_v4l2_controls.h
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index e50e517..8754098 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -11,6 +11,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_META_FMT_GENERIC_CSI2_16: descr = "8-bit Generic Meta, 16b CSI-2"; break;
case V4L2_META_FMT_GENERIC_CSI2_20: descr = "8-bit Generic Meta, 20b CSI-2"; break;
case V4L2_META_FMT_GENERIC_CSI2_24: descr = "8-bit Generic Meta, 24b CSI-2"; break;
+ case V4L2_META_FMT_MTFD_RESULT: descr = "Mediatek Face Detect Result"; break;
default:
/* Compressed formats */
diff --git a/include/uapi/linux/mtk_aie_v4l2_controls.h b/include/uapi/linux/mtk_aie_v4l2_controls.h
new file mode 100644
index 0000000..a8b2927
--- /dev/null
+++ b/include/uapi/linux/mtk_aie_v4l2_controls.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * MediaTek AI Engine (AIE) V4L2 control definitions
+ *
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Fish Wu <fish.wu@mediatek.com>
+ */
+
+#ifndef __UAPI_MTK_AIE_V4L2_CONTROLS_H__
+#define __UAPI_MTK_AIE_V4L2_CONTROLS_H__
+
+#include <linux/videodev2.h>
+
+/*
+ * The base for the MediaTek AIE driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_MTK_FD_BASE (V4L2_CID_USER_BASE + 0x1fd0)
+
+#define V4L2_CID_MTK_AIE_INIT (V4L2_CID_USER_MTK_FD_BASE + 1)
+#define V4L2_CID_MTK_AIE_PARAM (V4L2_CID_USER_MTK_FD_BASE + 2)
+
+#endif /* __UAPI_MTK_AIE_V4L2_CONTROLS_H__ */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 7668201..6d6866d 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -10,6 +10,7 @@ struct v4l2_pix_format {
#define V4L2_META_FMT_GENERIC_CSI2_16 v4l2_fourcc('M', 'C', '1', 'G') /* 16-bit CSI-2 packed 8-bit metadata */
#define V4L2_META_FMT_GENERIC_CSI2_20 v4l2_fourcc('M', 'C', '1', 'K') /* 20-bit CSI-2 packed 8-bit metadata */
#define V4L2_META_FMT_GENERIC_CSI2_24 v4l2_fourcc('M', 'C', '1', 'O') /* 24-bit CSI-2 packed 8-bit metadata */
+#define V4L2_META_FMT_MTFD_RESULT v4l2_fourcc('M', 'T', 'f', 'd') /* Mediatek face detection result */
#endif
/* priv field value to indicates that subsequent fields are valid. */
--
2.45.2
^ permalink raw reply related
* [PATCH v6 2/4] arm64: dts: mediatek: mt8188: Add AIE face detection node
From: Sarang Chaudhari @ 2026-06-05 8:29 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
Add the AI Engine (AIE) device tree node for the MT8188 SoC. The AIE
hardware provides face detection, facial landmark detection, and face
attribute analysis capabilities.
Signed-off-by: Sarang Chaudhari <sarang.chaudhari@mediatek.com>
---
Changes in v6:
- Remove iommus and mediatek,larb properties (made optional).
- Remove larb12 node (not required when IOMMU is not used).
- Update IRQ number to correct hardware value.
Changes in v5:
- Modify the name of clock, change _ to -.
Changes in v4: None
Changes in v3:
- Remove dts non-MMIO nodes.
Changes in v2:
- Add AIE node and related node.
arch/arm64/boot/dts/mediatek/mt8188.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index ee833c3..29d11d8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -12,6 +12,19 @@
#reset-cells = <1>;
};
+ aie@15310000 {
+ compatible = "mediatek,mt8188-aie";
+ reg = <0 0x15310000 0 0x1000>;
+ interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&imgsys CLK_IMGSYS_MAIN_IPE>,
+ <&ipesys CLK_IPE_FDVT>,
+ <&ipesys CLK_IPE_SMI_LARB12>,
+ <&ipesys CLK_IPESYS_TOP>;
+ clock-names = "img-ipe", "ipe-fdvt",
+ "ipe-smi-larb12", "ipe-top";
+ power-domains = <&spm MT8188_POWER_DOMAIN_IPE>;
+ };
+
ipesys: clock-controller@15330000 {
compatible = "mediatek,mt8188-ipesys";
reg = <0 0x15330000 0 0x1000>;
--
2.45.2
^ permalink raw reply related
* [PATCH v6 1/4] media: dt-bindings: mediatek: Add AIE face detection support for MT8188
From: Sarang Chaudhari @ 2026-06-05 8:28 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
Add YAML device tree bindings for the MediaTek AI Engine (AIE) hardware
accelerator found in MT8188 SoCs. The AIE provides hardware-accelerated
face detection, facial landmark detection, and face attribute analysis
capabilities.
Add a MAINTAINERS entry covering the binding, the UAPI header and the
driver directory.
Signed-off-by: Sarang Chaudhari <sarang.chaudhari@mediatek.com>
---
Changes in v6:
- Add ipe-smi-larb12 clock to the binding (was missing in v5 binding
but present in v5 dtsi).
- Remove iommus from required properties (made optional for platforms
that can operate without IOMMU).
- Add mediatek,larb as an optional property.
- Improve description text.
Changes in v5:
- Modify the description to make it more concise.
- Delete the description of reg.
- Modify the description of iommus and delete the maxItems of iommus.
- Delete all mediatek,larb.
- Modify the name of clock, change _ to -.
Changes in v4:
- Remove address-cells and size-cells.
- Remove larb12 related content.
- Update id content.
Changes in v3: None
Changes in v2:
- Fix coding style.
.../bindings/media/mediatek,mt8188-aie.yaml | 85 +++++++++++++++++++
MAINTAINERS | 10 +++
2 files changed, 95 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
diff --git a/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml b/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
new file mode 100644
index 0000000..ab888f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mt8188-aie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek AI Engine (AIE) for Face Detection
+
+maintainers:
+ - Fish Wu <fish.wu@mediatek.com>
+ - Bo Kong <bo.kong@mediatek.com>
+
+description: |
+ The MediaTek AI Engine (AIE) provides hardware-accelerated face detection,
+ facial landmark detection, and face attribute analysis. It is found in the
+ IPE (Image Processing Engine) subsystem of MediaTek SoCs.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8188-aie
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: clock for imgsys main ipe
+ - description: clock for ipe fdvt
+ - description: clock for ipe smi larb12
+ - description: clock for ipe top
+
+ clock-names:
+ items:
+ - const: img-ipe
+ - const: ipe-fdvt
+ - const: ipe-smi-larb12
+ - const: ipe-top
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 1
+
+ mediatek,larb:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle to the local arbiter (LARB) node
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mediatek,mt8188-clk.h>
+ #include <dt-bindings/power/mediatek,mt8188-power.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aie@15310000 {
+ compatible = "mediatek,mt8188-aie";
+ reg = <0 0x15310000 0 0x1000>;
+ interrupts = <GIC_SPI 600 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&imgsys CLK_IMGSYS_MAIN_IPE>,
+ <&ipesys CLK_IPE_FDVT>,
+ <&ipesys CLK_IPE_SMI_LARB12>,
+ <&ipesys CLK_IPESYS_TOP>;
+ clock-names = "img-ipe", "ipe-fdvt",
+ "ipe-smi-larb12", "ipe-top";
+ power-domains = <&spm MT8188_POWER_DOMAIN_IPE>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index afb7487..fa631d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3,6 +3,16 @@ M: Felix Fietkau <nbd@nbd.name>
S: Maintained
F: drivers/net/ethernet/mediatek/
+MEDIATEK MT8188 AIE DRIVER
+M: Fish Wu <fish.wu@mediatek.com>
+M: Bo Kong <bo.kong@mediatek.com>
+L: linux-media@vger.kernel.org
+L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
+F: drivers/media/platform/mediatek/aie/
+F: include/uapi/linux/mtk_aie_v4l2_controls.h
+
MEDIATEK MDP DRIVER
M: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
S: Supported
--
2.45.2
^ permalink raw reply related
* [PATCH v6 0/4] Add MT8188 AIE driver
From: Sarang Chaudhari @ 2026-06-05 8:20 UTC (permalink / raw)
To: Rob Herring, AngeloGioacchino Del Regno, Mauro Carvalho Chehab,
linux-kernel, linux-arm-kernel, linux-mediatek
Cc: zhaoyuan.chen, Teddy.Chen, Project_Global_Chrome_Upstream_Group,
Sarang Chaudhari
AIE (AI Engine) is one of the units in MT8188 ISP which provides
hardware-accelerated face detection function. It can detect different
sizes of faces in a raw image using pyramid-based multi-scale detection.
The AIE supports three operation modes:
- Face Detection (FD): Multi-scale face detection using 3-level pyramid
(640x480 base, 2x downscale per level).
- Attribute Analysis: Age, gender, and race classification.
- Facial Landmark Detection (FLD): 11-point landmark localization using
Binary Tree Traversal on FD results.
Changes in v6:
- DT binding: Add ipe-smi-larb12 clock, remove iommus from required
properties, add mediatek,larb as optional, improve description.
- DTS: Remove iommus and mediatek,larb properties, fix IRQ number.
- UAPI: Simplify header to control ID definitions only, drop custom
V4L2_CTRL_TYPE (use V4L2_CTRL_TYPE_U32 compound controls instead).
- Driver: Fix NULL pointer check inversion, fix resource leaks on error
path, remove debugfs return value checks, update clock names to hyphen
convention, remove freq_level per CK Hu's feedback.
Changes in v5:
- DT binding: Use hyphens in clock names, remove mediatek,larb.
- UAPI: Add feature_threshold docs, rename structures, move structures
from mtk_aie.h to uapi header.
- Driver: Update clock names, improve error handling in probe.
Changes in v4:
- DT binding: Remove address-cells/size-cells, remove larb12 content.
- UAPI: Add V4L2_META_FMT_MTFD_RESULT documentation.
- Driver: Remove larb12 related content.
Changes in v3:
- DTS: Remove non-MMIO nodes.
Changes in v2:
- Fix coding style issues throughout.
Sarang Chaudhari (4):
media: dt-bindings: mediatek: Add AIE face detection support for
MT8188
arm64: dts: mediatek: mt8188: Add AIE face detection node
media: uapi: mediatek: Add MT8188 AIE control definitions
media: platform: mediatek: Add MT8188 AIE driver
.../bindings/media/mediatek,mt8188-aie.yaml | 85 +
MAINTAINERS | 10 +
arch/arm64/boot/dts/mediatek/mt8188.dtsi | 13 +
drivers/media/platform/mediatek/Kconfig | 1 +
drivers/media/platform/mediatek/Makefile | 1 +
drivers/media/platform/mediatek/aie/Kconfig | 20 +
drivers/media/platform/mediatek/aie/Makefile | 5 +
drivers/media/platform/mediatek/aie/mtk_aie.h | 1045 +++++++++++
.../platform/mediatek/aie/mtk_aie_drv.c | 3667 +++++++++++++++++
.../platform/mediatek/aie/mtk_aie_v4l2.c | 1907 +++++++++
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
include/uapi/linux/mtk_aie_v4l2_controls.h | 23 +
include/uapi/linux/videodev2.h | 1 +
13 files changed, 6779 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt8188-aie.yaml
create mode 100644 drivers/media/platform/mediatek/aie/Kconfig
create mode 100644 drivers/media/platform/mediatek/aie/Makefile
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie.h
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie_drv.c
create mode 100644 drivers/media/platform/mediatek/aie/mtk_aie_v4l2.c
create mode 100644 include/uapi/linux/mtk_aie_v4l2_controls.h
--
2.45.2
^ permalink raw reply
* [PATCH v2] KVM: arm64: Reassign nested_mmus array behind mmu_lock
From: Hyunwoo Kim @ 2026-06-05 8:27 UTC (permalink / raw)
To: maz, oupton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, christoffer.dall
Cc: linux-arm-kernel, kvmarm, imv4bel
kvm->arch.nested_mmus[] is walked under kvm->mmu_lock, including from the
MMU notifier path (kvm_unmap_gfn_range() -> kvm_nested_s2_unmap()), which
can run at any time. kvm_vcpu_init_nested() reallocates the array and frees
the old buffer while holding only kvm->arch.config_lock, so such a walker
can reference the freed array.
Allocate the new array outside of mmu_lock, as the allocation can sleep.
Under the lock, copy the existing entries, fix up the back pointers and
reassign the array. Free the old buffer after dropping the lock, as
kvfree() can sleep as well.
Fixes: 4f128f8e1aaac ("KVM: arm64: nv: Support multiple nested Stage-2 mmu structures")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Reviewed-by: Oliver Upton <oupton@kernel.org>
---
Changes in v2:
- reword shortlog and changelog per review
(diff unchanged; kept Oliver's Reviewed-by)
- v1: https://lore.kernel.org/all/aiHEKOeZMVwsRlvP@v4bel/
---
arch/arm64/kvm/nested.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 38f672e94087..6f7bc9a9992e 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -89,21 +89,28 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
* again, and there is no reason to affect the whole VM for this.
*/
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
- tmp = kvrealloc(kvm->arch.nested_mmus,
- size_mul(sizeof(*kvm->arch.nested_mmus), num_mmus),
- GFP_KERNEL_ACCOUNT | __GFP_ZERO);
- if (!tmp)
- return -ENOMEM;
- swap(kvm->arch.nested_mmus, tmp);
+ if (num_mmus > kvm->arch.nested_mmus_size) {
+ tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
+ if (!tmp)
+ return -ENOMEM;
- /*
- * If we went through a realocation, adjust the MMU back-pointers in
- * the previously initialised kvm_pgtable structures.
- */
- if (kvm->arch.nested_mmus != tmp)
- for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
- kvm->arch.nested_mmus[i].pgt->mmu = &kvm->arch.nested_mmus[i];
+ write_lock(&kvm->mmu_lock);
+
+ if (kvm->arch.nested_mmus_size) {
+ memcpy(tmp, kvm->arch.nested_mmus,
+ size_mul(sizeof(*tmp), kvm->arch.nested_mmus_size));
+
+ for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
+ tmp[i].pgt->mmu = &tmp[i];
+ }
+
+ swap(kvm->arch.nested_mmus, tmp);
+
+ write_unlock(&kvm->mmu_lock);
+
+ kvfree(tmp);
+ }
for (int i = kvm->arch.nested_mmus_size; !ret && i < num_mmus; i++)
ret = init_nested_s2_mmu(kvm, &kvm->arch.nested_mmus[i]);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] KVM: arm64: vgic: Use list_del_rcu() when flushing pending LPIs
From: Marc Zyngier @ 2026-06-05 8:17 UTC (permalink / raw)
To: Oliver Upton
Cc: Hyunwoo Kim, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, Sascha.Bischoff, jic23, linux-arm-kernel,
kvmarm
In-Reply-To: <aiJi5a3JJ-TbWL-s@kernel.org>
On Fri, 05 Jun 2026 06:47:17 +0100,
Oliver Upton <oupton@kernel.org> wrote:
>
> Hi Hyunwoo,
>
> On Fri, Jun 05, 2026 at 06:16:08AM +0900, Hyunwoo Kim wrote:
> > vgic_v3_fold_lr_state() walks the ap_list from last_lr_irq without holding
> > the ap_list_lock, relying on vgic_irq being freed via kfree_rcu() and on
> > interrupts being disabled. vgic_flush_pending_lpis() removes entries with
> > list_del(), which clobbers a node's next pointer, so when another vCPU
> > disables LPIs via GICR_CTLR the walk can follow the clobbered next pointer
> > from a removed node, or from the node that last_lr_irq points to.
> >
> > Remove entries with list_del_rcu() so that the next pointer stays valid
> > until the walk completes.
> >
> > Fixes: 3cfd59f81e0f ("KVM: arm64: GICv3: Handle LR overflow when EOImode==0")
> > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
>
> Changing only one of the writer paths to use the rculist helpers does
> not make the ap_list an rculist. Insertions are not RCU-safe, nor are
> deleations from vgic_prune_ap_list().
>
> And TBH, the real bug here is the fact that vgic_v3_fold_lr_state() isn't
> taking the ap_list_lock.
Yup, that'd be more sensible. I need to convince myself that there is
no possible path from vgic_v*_fold_lr() to vgic_irq_queue_unlock(),
because that one does actually acquire that lock.
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v14 29/44] arm64: RMI: Runtime faulting of memory
From: Gavin Shan @ 2026-06-05 8:11 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Steven Price, kvm, kvmarm, Catalin Marinas, Marc Zyngier,
Will Deacon, James Morse, Oliver Upton, Suzuki K Poulose,
Zenghui Yu, linux-arm-kernel, linux-kernel, Joey Gouly,
Alexandru Elisei, Christoffer Dall, Fuad Tabba, linux-coco,
Ganapatrao Kulkarni, Shanker Donthineni, Alper Gun,
Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve, WeiLin.Chang,
Lorenzo.Pieralisi2
In-Reply-To: <aiJ6u83O0nVUtPyv@lpieralisi>
On 6/5/26 5:28 PM, Lorenzo Pieralisi wrote:
> On Fri, Jun 05, 2026 at 04:23:15PM +1000, Gavin Shan wrote:
>
> [...]
>
>>> +static int realm_map_ipa(struct kvm *kvm, phys_addr_t ipa,
>>> + kvm_pfn_t pfn, unsigned long map_size,
>>> + enum kvm_pgtable_prot prot,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + struct realm *realm = &kvm->arch.realm;
>>> +
>>> + /*
>>> + * Write permission is required for now even though it's possible to
>>> + * map unprotected pages (granules) as read-only. It's impossible to
>>> + * map protected pages (granules) as read-only.
>>> + */
>>> + if (WARN_ON(!(prot & KVM_PGTABLE_PROT_W)))
>>> + return -EFAULT;
>>> +
>>
>> I'm a bit concerned with this. We don't have KVM_PGTABLE_PROT_W set in @prot
>> if the stage2 fault is raised due to memory read. With -EFAULT returned to VMM
>> (e.g. QEMU), the vCPU continuous execution is stopped and system won't be
>> working any more.
>>
>>> + ipa = ALIGN_DOWN(ipa, PAGE_SIZE);
>>> + if (!kvm_realm_is_private_address(realm, ipa))
>>> + return realm_map_non_secure(realm, ipa, pfn, map_size, prot,
>>> + memcache);
>>> +
>>> + return realm_map_protected(kvm, ipa, pfn, map_size, memcache);
>>> +}
>>> +
>>> static bool kvm_vma_is_cacheable(struct vm_area_struct *vma)
>>> {
>>> switch (FIELD_GET(PTE_ATTRINDX_MASK, pgprot_val(vma->vm_page_prot))) {
>>> @@ -1604,27 +1641,52 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> bool write_fault, exec_fault;
>>> enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
>>> enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
>>> - struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
>>> + struct kvm_vcpu *vcpu = s2fd->vcpu;
>>> + struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
>>> + gpa_t gpa = kvm_gpa_from_fault(vcpu->kvm, s2fd->fault_ipa);
>>> unsigned long mmu_seq;
>>> struct page *page;
>>> - struct kvm *kvm = s2fd->vcpu->kvm;
>>> + struct kvm *kvm = vcpu->kvm;
>>> void *memcache;
>>> kvm_pfn_t pfn;
>>> gfn_t gfn;
>>> int ret;
>>> - memcache = get_mmu_memcache(s2fd->vcpu);
>>> - ret = topup_mmu_memcache(s2fd->vcpu, memcache);
>>> + if (kvm_is_realm(vcpu->kvm)) {
>>> + /* check for memory attribute mismatch */
>>> + bool is_priv_gfn = kvm_mem_is_private(kvm, gpa >> PAGE_SHIFT);
>>> + /*
>>> + * For Realms, the shared address is an alias of the private
>>> + * PA with the top bit set. Thus if the fault address matches
>>> + * the GPA then it is the private alias.
>>> + */
>>> + bool is_priv_fault = (gpa == s2fd->fault_ipa);
>>> +
>>> + if (is_priv_gfn != is_priv_fault) {
>>> + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
>>> + kvm_is_write_fault(vcpu),
>>> + false,
>>> + is_priv_fault);
>>> + /*
>>> + * KVM_EXIT_MEMORY_FAULT requires an return code of
>>> + * -EFAULT, see the API documentation
>>> + */
>>> + return -EFAULT;
>>> + }
>>> + }
>>> +
>>> + memcache = get_mmu_memcache(vcpu);
>>> + ret = topup_mmu_memcache(vcpu, memcache);
>>> if (ret)
>>> return ret;
>>> if (s2fd->nested)
>>> gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
>>> else
>>> - gfn = s2fd->fault_ipa >> PAGE_SHIFT;
>>> + gfn = gpa >> PAGE_SHIFT;
>>> - write_fault = kvm_is_write_fault(s2fd->vcpu);
>>> - exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu);
>>> + write_fault = kvm_is_write_fault(vcpu);
>>> + exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
>>> VM_WARN_ON_ONCE(write_fault && exec_fault);
>>> @@ -1634,7 +1696,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, gfn, &pfn, &page, NULL);
>>> if (ret) {
>>> - kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
>>> + kvm_prepare_memory_fault_exit(vcpu, gpa, PAGE_SIZE,
>>> write_fault, exec_fault, false);
>>> return ret;
>>> }
>>> @@ -1654,14 +1716,20 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>>> kvm_fault_lock(kvm);
>>> if (mmu_invalidate_retry(kvm, mmu_seq)) {
>>> ret = -EAGAIN;
>>> - goto out_unlock;
>>> + goto out_release_page;
>>> + }
>>> +
>>> + if (kvm_is_realm(kvm)) {
>>> + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn,
>>> + PAGE_SIZE, KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W, memcache);
>>> + goto out_release_page;
>>> }
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
>>> __pfn_to_phys(pfn), prot,
>>> memcache, flags);
>>> -out_unlock:
>>> +out_release_page:
>>> kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
>>> kvm_fault_unlock(kvm);
>>> @@ -1847,7 +1915,7 @@ static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
>>> * mapping size to ensure we find the right PFN and lay down the
>>> * mapping in the right place.
>>> */
>>> - s2vi->gfn = ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize) >> PAGE_SHIFT;
>>> + s2vi->gfn = kvm_gpa_from_fault(kvm, ALIGN_DOWN(s2fd->fault_ipa, s2vi->vma_pagesize)) >> PAGE_SHIFT;
>>> s2vi->mte_allowed = kvm_vma_mte_allowed(vma);
>>> @@ -2056,6 +2124,9 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
>>> prot &= ~KVM_NV_GUEST_MAP_SZ;
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(gfn),
>>> prot, flags);
>>> + } else if (kvm_is_realm(kvm)) {
>>> + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn, mapping_size,
>>> + prot, memcache);
>>> } else {
>>> ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), mapping_size,
>>> __pfn_to_phys(pfn), prot,
>>
>> For the case kvm_is_realm(), need we adjust 's2fd->fault_ipa' for the sake of
>> huge pages. In kvm_s2_fault_map(), @gfn and @pfn may have been adjusted by
>> transparent_hugepage_adjust() to be aligned with huge page size. If the
>> adjustment happened in transparent_hugepage_adjust(), we need to align
>> s2fd->fault_ipa down to the huge page size either.
>
> All of the above + some RMM changes are needed to get QEmu VMM going
> with anon pages guest memory backing - currently testing various
> configurations in the background.
>
I tried to rebase Jean's latest QEMU series [1] to upstream QEMU, and found
that memory slots backed by THP are broken. With THP disabled on the host and
other fixes (mentioned in my prevous replies) applied on the top of this (v14)
series, I'm able to boot a realm guest with rebased QEMU series [2], plus more
fxies on the top.
[1] https://git.codelinaro.org/linaro/dcap/qemu.git (branch: cca/latest)
[2] https://git.qemu.org/git/qemu.git (branch: cca/gavin)
Lorenzo, You may be saying there is someone making QEMU to support ARM/CCA?
If so, I'm not sure if there is a QEMU repository for me to try?
Thanks,
Gavin
> Thanks,
> Lorenzo
>
>>> @@ -2214,6 +2285,13 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
>>> return 0;
>>> }
>>> +static bool shared_ipa_fault(struct kvm *kvm, phys_addr_t fault_ipa)
>>> +{
>>> + gpa_t gpa = kvm_gpa_from_fault(kvm, fault_ipa);
>>> +
>>> + return (gpa != fault_ipa);
>>> +}
>>> +
>>> /**
>>> * kvm_handle_guest_abort - handles all 2nd stage aborts
>>> * @vcpu: the VCPU pointer
>>> @@ -2324,8 +2402,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> nested = &nested_trans;
>>> }
>>> - gfn = ipa >> PAGE_SHIFT;
>>> + gfn = kvm_gpa_from_fault(vcpu->kvm, ipa) >> PAGE_SHIFT;
>>> memslot = gfn_to_memslot(vcpu->kvm, gfn);
>>> +
>>> hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
>>> write_fault = kvm_is_write_fault(vcpu);
>>> if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
>>> @@ -2368,7 +2447,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> * of the page size.
>>> */
>>> ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
>>> - ret = io_mem_abort(vcpu, ipa);
>>> + ret = io_mem_abort(vcpu, kvm_gpa_from_fault(vcpu->kvm, ipa));
>>> goto out_unlock;
>>> }
>>> @@ -2396,7 +2475,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>>> !write_fault &&
>>> !kvm_vcpu_trap_is_exec_fault(vcpu));
>>> - if (kvm_slot_has_gmem(memslot))
>>> + if (kvm_slot_has_gmem(memslot) && !shared_ipa_fault(vcpu->kvm, fault_ipa))
>>> ret = gmem_abort(&s2fd);
>>> else
>>> ret = user_mem_abort(&s2fd);
>>> @@ -2433,6 +2512,10 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>>> if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
>>> return false;
>>> + /* We don't support aging for Realms */
>>> + if (kvm_is_realm(kvm))
>>> + return true;
>>> +
>>> return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
>>> range->start << PAGE_SHIFT,
>>> size, true);
>>> @@ -2449,6 +2532,10 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
>>> if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
>>> return false;
>>> + /* We don't support aging for Realms */
>>> + if (kvm_is_realm(kvm))
>>> + return true;
>>> +
>>> return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt,
>>> range->start << PAGE_SHIFT,
>>> size, false);
>>> @@ -2628,10 +2715,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
>>> return -EFAULT;
>>> /*
>>> - * Only support guest_memfd backed memslots with mappable memory, since
>>> - * there aren't any CoCo VMs that support only private memory on arm64.
>>> + * Only support guest_memfd backed memslots with mappable memory,
>>> + * unless the guest is a CCA realm guest.
>>> */
>>> - if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new))
>>> + if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new) &&
>>> + !kvm_is_realm(kvm))
>>> return -EINVAL;
>>> hva = new->userspace_addr;
>>> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
>>> index cae29fd3353c..761b38a4071c 100644
>>> --- a/arch/arm64/kvm/rmi.c
>>> +++ b/arch/arm64/kvm/rmi.c
>>> @@ -597,6 +597,179 @@ static int realm_data_map_init(struct kvm *kvm, unsigned long ipa,
>>> return ret;
>>> }
>>> +static unsigned long addr_range_desc(unsigned long phys, unsigned long size)
>>> +{
>>> + unsigned long out = 0;
>>> +
>>> + switch (size) {
>>> + case P4D_SIZE:
>>> + out = 3 | (1 << 2);
>>> + break;
>>> + case PUD_SIZE:
>>> + out = 2 | (1 << 2);
>>> + break;
>>> + case PMD_SIZE:
>>> + out = 1 | (1 << 2);
>>> + break;
>>> + case PAGE_SIZE:
>>> + out = 0 | (1 << 2);
>>> + break;
>>> + default:
>>> + /*
>>> + * Only support mapping at the page level granulatity when
>>> + * it's an unusual length. This should get us back onto a larger
>>> + * block size for the subsequent mappings.
>>> + */
>>> + out = 0 | ((MIN(size >> PAGE_SHIFT, PTRS_PER_PTE - 1)) << 2);
>>> + break;
>>> + }
>>> +
>>> + WARN_ON(phys & ~PAGE_MASK);
>>> +
>>> + out |= phys & PAGE_MASK;
>>> +
>>> + return out;
>>> +}
>>> +
>>> +int realm_map_protected(struct kvm *kvm,
>>> + unsigned long ipa,
>>> + kvm_pfn_t pfn,
>>> + unsigned long map_size,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + struct realm *realm = &kvm->arch.realm;
>>> + phys_addr_t phys = __pfn_to_phys(pfn);
>>> + phys_addr_t base_phys = phys;
>>> + phys_addr_t rd = virt_to_phys(realm->rd);
>>> + unsigned long base_ipa = ipa;
>>> + unsigned long ipa_top = ipa + map_size;
>>> + int ret = 0;
>>> +
>>> + if (WARN_ON(!IS_ALIGNED(map_size, PAGE_SIZE) ||
>>> + !IS_ALIGNED(ipa, map_size)))
>>> + return -EINVAL;
>>> +
>>> + if (rmi_delegate_range(phys, map_size)) {
>>> + /*
>>> + * It's likely we raced with another VCPU on the same
>>> + * fault. Assume the other VCPU has handled the fault
>>> + * and return to the guest.
>>> + */
>>> + return 0;
>>> + }
>>> +
>>> + while (ipa < ipa_top) {
>>> + unsigned long flags = RMI_ADDR_TYPE_SINGLE;
>>> + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
>>> + unsigned long out_top;
>>> +
>>> + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags, range_desc,
>>> + &out_top);
>>> +
>>> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
>>> + /* Create missing RTTs and retry */
>>> + int level = RMI_RETURN_INDEX(ret);
>>> +
>>> + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
>>> + ret = realm_create_rtt_levels(realm, ipa, level,
>>> + KVM_PGTABLE_LAST_LEVEL,
>>> + memcache);
>>> + if (ret)
>>> + goto err_undelegate;
>>> +
>>> + ret = rmi_rtt_data_map(rd, ipa, ipa_top, flags,
>>> + range_desc, &out_top);
>>> + }
>>> +
>>> + if (WARN_ON(ret))
>>> + goto err_undelegate;
>>> +
>>> + phys += out_top - ipa;
>>> + ipa = out_top;
>>> + }
>>> +
>>> + return 0;
>>> +
>>> +err_undelegate:
>>> + realm_unmap_private_range(kvm, base_ipa, ipa, true);
>>> + if (WARN_ON(rmi_undelegate_range(base_phys, map_size))) {
>>> + /* Page can't be returned to NS world so is lost */
>>> + get_page(phys_to_page(base_phys));
>>> + }
>>> + return -ENXIO;
>>> +}
>>> +
>>> +int realm_map_non_secure(struct realm *realm,
>>> + unsigned long ipa,
>>> + kvm_pfn_t pfn,
>>> + unsigned long size,
>>> + enum kvm_pgtable_prot prot,
>>> + struct kvm_mmu_memory_cache *memcache)
>>> +{
>>> + unsigned long attr, flags = 0;
>>> + phys_addr_t rd = virt_to_phys(realm->rd);
>>> + phys_addr_t phys = __pfn_to_phys(pfn);
>>> + unsigned long ipa_top = ipa + size;
>>> + int ret;
>>> +
>>> + if (WARN_ON(!IS_ALIGNED(size, PAGE_SIZE) ||
>>> + !IS_ALIGNED(ipa, size)))
>>> + return -EINVAL;
>>> +
>>> + switch (prot & (KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC)) {
>>> + case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
>>> + return -EINVAL;
>>> + case KVM_PGTABLE_PROT_DEVICE:
>>> + attr = MT_S2_FWB_DEVICE_nGnRE;
>>> + break;
>>> + case KVM_PGTABLE_PROT_NORMAL_NC:
>>> + attr = MT_S2_FWB_NORMAL_NC;
>>> + break;
>>> + default:
>>> + attr = MT_S2_FWB_NORMAL;
>>> + }
>>> +
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_MEMATTR, attr);
>>> +
>>> + if (prot & KVM_PGTABLE_PROT_R)
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_READ);
>>> + if (prot & KVM_PGTABLE_PROT_W)
>>> + flags |= FIELD_PREP(RMI_RTT_UNPROT_MAP_FLAGS_S2AP, RMI_S2AP_DIRECT_WRITE);
>>> +
>>> + flags |= RMI_ADDR_TYPE_SINGLE;
>>> +
>>> + while (ipa < ipa_top) {
>>> + unsigned long range_desc = addr_range_desc(phys, ipa_top - ipa);
>>> + unsigned long out_top;
>>> +
>>> + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags, range_desc,
>>> + &out_top);
>>> +
>>> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
>>> + /* Create missing RTTs and retry */
>>> + int level = RMI_RETURN_INDEX(ret);
>>> +
>>> + WARN_ON(level == KVM_PGTABLE_LAST_LEVEL);
>>> + ret = realm_create_rtt_levels(realm, ipa, level,
>>> + KVM_PGTABLE_LAST_LEVEL,
>>> + memcache);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + ret = rmi_rtt_unprot_map(rd, ipa, ipa_top, flags,
>>> + range_desc, &out_top);
>>> + }
>>> +
>>> + if (WARN_ON(ret))
>>> + return ret;
>>> +
>>> + phys += out_top - ipa;
>>> + ipa = out_top;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> static int populate_region_cb(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
>>> struct page *src_page, void *opaque)
>>> {
>>
>> Thanks,
>> Gavin
>>
>
^ permalink raw reply
* Re: [PATCH v1] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Catalin Marinas @ 2026-06-05 8:01 UTC (permalink / raw)
To: Shanker Donthineni
Cc: Will Deacon, linux-arm-kernel, Mark Rutland, linux-kernel,
linux-doc, Vikram Sethi, Jason Sequeira
In-Reply-To: <20260604231254.1904988-1-sdonthineni@nvidia.com>
On Thu, Jun 04, 2026 at 06:12:54PM -0500, Shanker Donthineni wrote:
> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
> observed by a peripheral before an older, non-overlapping Device-nGnR*
> store to the same peripheral. This breaks the program-order guarantee
> that software expects for Device-nGnR* accesses and can leave a
> peripheral in an incorrect state, as a load is observed before an
> earlier store takes effect.
>
> The erratum can occur only when all of the following apply:
>
> - A PE executes a Device-nGnR* store followed by a younger
> Device-nGnR* load.
> - The store is not a store-release.
> - The accesses target the same peripheral and do not overlap in bytes.
> - There is at most one intervening Device-nGnR* store in program
> order, and there are no intervening Device-nGnR* loads.
> - There is no DSB, and no DMB that orders loads, between the store and
> the load.
> - Specific micro-architectural and timing conditions occur.
>
> Two ways to restore ordering: insert a barrier (any DSB, or a DMB that
> orders loads) between the store and the load, or make the store a
> store-release. A load-acquire on the load side would not help, because
> acquire semantics do not prevent a load from being observed ahead of an
> older store; only the store side (release or a barrier) closes the
> window.
Ignoring Device-nGnR*, a store-release followed by a load (not
load-acquire) would not guarantee any ordering. I assume the
store-release behaviour is specific to this erratum - part of the
preconditions.
The patch looks fine to me.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH] net: stmmac: prevent kernel panic during XDP program and XSK pool transitions
From: Carlos Fangmeier @ 2026-06-05 7:56 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, David S. Miller,
Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend,
Stanislav Fomichev, Andrew Lunn, Eric Dumazet, Paolo Abeni,
Maxime Coquelin, Alexandre Torgue, Ong Boon Leong
Cc: netdev, bpf, linux-stm32, linux-arm-kernel, linux-kernel,
Carlos Fangmeier
stmmac_xdp_set_prog() tears down and rebuilds all DMA channels via
stmmac_xdp_release()/stmmac_xdp_open() without pausing the netdev
TX path. Similarly, stmmac_xdp_enable_pool() and
stmmac_xdp_disable_pool() reconfigure individual queue DMA rings
while TX remains active.
If the kernel transmits a frame during these windows — for example an
MLD report queued by the IPv6 stack — stmmac_xmit() calls
dwmac4_set_addr() against an MMIO register whose mapping has been
torn down, triggering a level-3 translation fault:
Unable to handle kernel paging request at virtual address ffff8000840ec000
pc : dwmac4_set_addr+0x8/0x18
lr : stmmac_xmit+0x64c/0xb60
Call trace:
dwmac4_set_addr+0x8/0x18
dev_hard_start_xmit+0xb0/0x220
sch_direct_xmit+0x108/0x3f0
__dev_queue_xmit+0x844/0xd00
ip6_finish_output2+0x2d8/0x610
mld_sendpack+0x180/0x2e0
mld_ifc_work+0x1dc/0x480
The existing netif_tx_disable() in stmmac_xdp_release() is not
sufficient because stmmac_xdp_open() re-enables TX via
netif_tx_start_all_queues() before the caller regains control, leaving
a window where the freshly rebuilt rings can race with pending TX work.
Fix this by wrapping each reconfiguration path with
netif_tx_disable()/netif_tx_wake_all_queues():
- stmmac_xdp_set_prog(): hold TX disabled across the full
stmmac_xdp_release() + stmmac_xdp_open() sequence, only waking
TX after stmmac_xdp_open() returns.
- stmmac_xdp_enable_pool(): disable TX before tearing down the
queue, re-enable after the queue is rebuilt and NAPI is active.
- stmmac_xdp_disable_pool(): same pattern around the pool teardown
and queue rebuild.
Tested on Cortex-A55 (stmmac/dwmac4, kernel 6.6.60) with AF_XDP
zero-copy and IPv6 active — no panics observed across repeated
XDP attach/detach and XSK pool setup/teardown cycles.
Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
Signed-off-by: Carlos Fangmeier <carlos.fangmeier@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
index d7e4db7224b0..a6611aee687f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
@@ -34,6 +34,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
if (need_update) {
+ netif_tx_disable(priv->dev);
napi_disable(&ch->rx_napi);
napi_disable(&ch->tx_napi);
stmmac_disable_rx_queue(priv, queue);
@@ -46,6 +47,7 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
stmmac_enable_rx_queue(priv, queue);
stmmac_enable_tx_queue(priv, queue);
napi_enable(&ch->rxtx_napi);
+ netif_tx_wake_all_queues(priv->dev);
err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
if (err)
@@ -72,6 +74,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
if (need_update) {
+ netif_tx_disable(priv->dev);
napi_disable(&ch->rxtx_napi);
stmmac_disable_rx_queue(priv, queue);
stmmac_disable_tx_queue(priv, queue);
@@ -87,6 +90,7 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
stmmac_enable_tx_queue(priv, queue);
napi_enable(&ch->rx_napi);
napi_enable(&ch->tx_napi);
+ netif_tx_wake_all_queues(priv->dev);
}
return 0;
@@ -121,8 +125,10 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
xdp_features_clear_redirect_target(dev);
need_update = !!priv->xdp_prog != !!prog;
- if (if_running && need_update)
+ if (if_running && need_update) {
+ netif_tx_disable(dev);
stmmac_xdp_release(dev);
+ }
old_prog = xchg(&priv->xdp_prog, prog);
if (old_prog)
@@ -131,8 +137,10 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
/* Disable RX SPH for XDP operation */
priv->sph_active = priv->sph_capable && !stmmac_xdp_is_enabled(priv);
- if (if_running && need_update)
+ if (if_running && need_update) {
stmmac_xdp_open(dev);
+ netif_tx_wake_all_queues(dev);
+ }
if (prog)
xdp_features_set_redirect_target(dev, false);
---
base-commit: 4aacf509e537a711fa71bca9f234e5eb6968850e
change-id: 20260604-main-f69f9564a74b
Best regards,
--
Carlos Fangmeier <carlos.fangmeier@gmail.com>
^ permalink raw reply related
* Re: [Linux-stm32] [PATCH v3 13/14] arm64: dts: st: support Engicam MicroGEA-STM32MP257-RMM board
From: Amelie Delaunay @ 2026-06-05 7:55 UTC (permalink / raw)
To: Dario Binacchi, linux-kernel
Cc: Rob Herring, Conor Dooley, devicetree, francesco.utel,
domenico.acri, Maxime Coquelin, Krzysztof Kozlowski, michael,
linux-amarula, linux-stm32, linux-arm-kernel
In-Reply-To: <20260605062900.368376-14-dario.binacchi@amarulasolutions.com>
Hi Dario,
On 6/5/26 08:27, Dario Binacchi wrote:
> Support for Engicam MicroGEA-STM32MP257-RMM board with:
>
> - 8 GB eMMC Flash
> - 2 GB LPDDR4 DRAM
> - CAN
> - LEDs
> - LCD panel with touchscreen
> - Micro SD card connector
> - Audio codec
> - Buzzer
>
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Drop the clocks property from the sai1 node in stm32mp257-engicam-microgea-rmm.dts
> to avoid overriding the peripheral bus clock reference defined in the base
> SoC device tree. Suggested by Sashiko.
> - Reference the existing labeled nodes directly at the root level using
> &sai1a and &sai1b in stm32mp257-engicam-microgea-rmm.dts instead of
> redefining the entire node structure and redeclaring the labels. Suggested by Sashiko.
> - Drop the #clock-cells property from sai1a and remove the reference to sai1a from
> the clocks array in sai1b, relying strictly on the st,sync property to handle
> internal synchronization.
>
> arch/arm64/boot/dts/st/Makefile | 1 +
> .../st/stm32mp257-engicam-microgea-rmm.dts | 319 ++++++++++++++++++
> 2 files changed, 320 insertions(+)
> create mode 100644 arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
>
> diff --git a/arch/arm64/boot/dts/st/Makefile b/arch/arm64/boot/dts/st/Makefile
> index 63908113ae36..386eca593c54 100644
> --- a/arch/arm64/boot/dts/st/Makefile
> +++ b/arch/arm64/boot/dts/st/Makefile
> @@ -2,5 +2,6 @@
> dtb-$(CONFIG_ARCH_STM32) += \
> stm32mp215f-dk.dtb \
> stm32mp235f-dk.dtb \
> + stm32mp257-engicam-microgea-rmm.dtb \
> stm32mp257f-dk.dtb \
> stm32mp257f-ev1.dtb
> diff --git a/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
> new file mode 100644
> index 000000000000..0212c03aae1a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea-rmm.dts
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com>
> + * Copyright (C) 2026 Engicam srl
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +
> +#include "stm32mp257-engicam-microgea.dtsi"
> +
> +/ {
> + model = "Engicam MicroGEA STM32MP257D RMM Board";
If the SoC is an STM32MP257D, as mentionned in the board model,
stm32mp25xf.dtsi should not be included in
stm32mp257-engicam-microgea.dtsi (in PATCH 12).
Unless the SoM can be fitted with any STM32MP257, in which case, when
stm32mp25xf.dtsi is populated, you will need to add /delete-node/
statements on the board side, to remove the HW crypto support.
Regards,
Amelie
> + compatible = "engicam,microgea-stm32mp257-rmm",
> + "engicam,microgea-stm32mp257", "st,stm32mp257";
> +
> + aliases {
> + mmc0 = &sdmmc1;
> + mmc1 = &sdmmc2;
> + serial0 = &usart2;
> + serial1 = &usart1;
> + };
> +
> + backlight: backlight {
> + compatible = "pwm-backlight";
> + brightness-levels = <0 100>;
> + num-interpolated-steps = <100>;
> + default-brightness-level = <85>;
> + pwms = <&pwm2 0 100000 0>;
> + };
> +
> + buzzer {
> + compatible = "pwm-beeper";
> + pwms = <&pwm4 0 1000000 0>;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + framebuffer {
> + compatible = "simple-framebuffer";
> + clocks = <&rcc CK_BUS_LTDC>, <&rcc CK_KER_LTDC>;
> + lcd-supply = <®_3v3>;
> + status = "disabled";
> + };
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> +
> + led-0 {
> + gpios = <&gpioh 2 GPIO_ACTIVE_HIGH>;
> + default-state = "off";
> + status = "okay";
> + };
> +
> + led-1 {
> + gpios = <&gpioh 6 GPIO_ACTIVE_HIGH>;
> + default-state = "off";
> + status = "okay";
> + };
> + };
> +
> + mclk: clock-mclk {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <24000000>;
> + };
> +
> + reg_1v8: regulator-1v8 {
> + compatible = "regulator-fixed";
> + regulator-name = "1v8";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + reg_3v3: regulator-3v3 {
> + compatible = "regulator-fixed";
> + regulator-name = "3v3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + reg_ext_pwr: regulator-ext-pwr {
> + compatible = "regulator-fixed";
> + regulator-name = "ext-pwr";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + gpio = <&gpiog 0 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + regulator-always-on;
> + };
> +
> + sound {
> + compatible = "audio-graph-card";
> + label = "STM32MP25-RMM";
> + widgets = "Headphone", "Headphone Jack",
> + "Microphone", "Microphone Jack";
> + routing = "Headphone Jack", "HP_OUT",
> + "MIC_IN", "Microphone Jack",
> + "Microphone Jack", "Mic Bias";
> + dais = <&sai1a_port &sai1b_port>;
> + status = "okay";
> + };
> +};
> +
> +&arm_wdt {
> + timeout-sec = <32>;
> + status = "okay";
> +};
> +
> +&i2c1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&i2c1_pins_a>;
> + pinctrl-1 = <&i2c1_sleep_pins_a>;
> + i2c-scl-rising-time-ns = <185>;
> + i2c-scl-falling-time-ns = <20>;
> + status = "okay";
> + /* spare dmas for other usage */
> + /delete-property/dmas;
> + /delete-property/dma-names;
> +
> + touchscreen@38 {
> + compatible = "edt,edt-ft5306";
> + reg = <0x38>;
> + interrupt-parent = <&gpiob>;
> + interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
> + reset-gpios = <&gpiod 1 GPIO_ACTIVE_LOW>;
> + touchscreen-size-x = <1280>;
> + touchscreen-size-y = <800>;
> + };
> +};
> +
> +&i2c2 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&i2c2_pins_a>;
> + pinctrl-1 = <&i2c2_sleep_pins_a>;
> + i2c-scl-rising-time-ns = <185>;
> + i2c-scl-falling-time-ns = <20>;
> + status = "okay";
> + /* spare dmas for other usage */
> + /delete-property/dmas;
> + /delete-property/dma-names;
> +
> + sgtl5000: codec@a {
> + compatible = "fsl,sgtl5000";
> + reg = <0x0a>;
> + #sound-dai-cells = <0>;
> + clocks = <&mclk>;
> +
> + VDDA-supply = <®_3v3>;
> + VDDIO-supply = <®_3v3>;
> + VDDD-supply = <®_1v8>;
> +
> + sgtl5000_port: port {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + sgtl5000_tx_endpoint: endpoint@0 {
> + reg = <0>;
> + remote-endpoint = <&sai1a_endpoint>;
> + frame-master = <&sgtl5000_tx_endpoint>;
> + bitclock-master = <&sgtl5000_tx_endpoint>;
> + };
> +
> + sgtl5000_rx_endpoint: endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&sai1b_endpoint>;
> + frame-master = <&sgtl5000_rx_endpoint>;
> + bitclock-master = <&sgtl5000_rx_endpoint>;
> + };
> + };
> + };
> +};
> +
> +<dc {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <<dc_pins_a>;
> + pinctrl-1 = <<dc_sleep_pins_a>;
> + status = "okay";
> +
> + port {
> + ltdc_out: endpoint {
> + remote-endpoint = <&panel_in>;
> + };
> + };
> +};
> +
> +&m_can1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&m_can1_pins_a>;
> + pinctrl-1 = <&m_can1_sleep_pins_a>;
> + status = "okay";
> +};
> +
> +&sai1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&sai1a_pins_a>, <&sai1b_pins_a>;
> + pinctrl-1 = <&sai1a_sleep_pins_a>, <&sai1b_sleep_pins_a>;
> + status = "okay";
> +};
> +
> +&sai1a {
> + dma-names = "tx";
> + status = "okay";
> +
> + sai1a_port: port {
> + sai1a_endpoint: endpoint {
> + remote-endpoint = <&sgtl5000_tx_endpoint>;
> + dai-format = "i2s";
> + mclk-fs = <512>;
> + };
> + };
> +};
> +
> +&sai1b {
> + dma-names = "rx";
> + st,sync = <&sai1a 2>;
> + clocks = <&rcc CK_KER_SAI1>;
> + clock-names = "sai_ck";
> + status = "okay";
> +
> + sai1b_port: port {
> + sai1b_endpoint: endpoint {
> + remote-endpoint = <&sgtl5000_rx_endpoint>;
> + dai-format = "i2s";
> + mclk-fs = <512>;
> + };
> + };
> +};
> +
> +/* MicroSD */
> +&sdmmc1 {
> + pinctrl-names = "default", "opendrain", "sleep";
> + pinctrl-0 = <&sdmmc1_b4_pins_a>;
> + pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
> + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
> + broken-cd;
> + disable-wp;
> + st,neg-edge;
> + bus-width = <4>;
> + vmmc-supply = <&scmi_v3v3>;
> + vqmmc-supply = <&scmi_vddio1>;
> + no-1-8-v;
> + status = "okay";
> +};
> +
> +&spi1 {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&spi1_pins_a>;
> + pinctrl-1 = <&spi1_sleep_pins_a>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + cs-gpios = <&gpioh 8 GPIO_ACTIVE_HIGH>, <&gpioh 3 GPIO_ACTIVE_HIGH>;
> + status = "okay";
> +
> + display: display@0 {
> + compatible = "rocktech,rk050hr345-ct106a", "ilitek,ili9806e";
> + reg = <0>;
> + vdd-supply = <®_3v3>;
> + spi-max-frequency = <10000000>;
> + reset-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>;
> + backlight = <&backlight>;
> +
> + port {
> + panel_in: endpoint {
> + remote-endpoint = <<dc_out>;
> + };
> + };
> + };
> +};
> +
> +&timers2 {
> + status = "okay";
> +
> + pwm2: pwm {
> + pinctrl-0 = <&pwm2_pins_a>;
> + pinctrl-1 = <&pwm2_sleep_pins_a>;
> + pinctrl-names = "default", "sleep";
> + status = "okay";
> + };
> +};
> +
> +&timers4 {
> + status = "okay";
> +
> + pwm4: pwm {
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&pwm4_pins_a>;
> + pinctrl-1 = <&pwm4_sleep_pins_a>;
> + status = "okay";
> + };
> +};
> +
> +&usart1 {
> + pinctrl-names = "default", "idle", "sleep";
> + pinctrl-0 = <&usart1_pins_b>;
> + pinctrl-1 = <&usart1_idle_pins_b>;
> + pinctrl-2 = <&usart1_sleep_pins_b>;
> + /delete-property/ dmas;
> + /delete-property/ dma-names;
> + status = "okay";
> +};
> +
> +&usart2 {
> + pinctrl-names = "default", "idle", "sleep";
> + pinctrl-0 = <&usart2_pins_a>;
> + pinctrl-1 = <&usart2_idle_pins_a>;
> + pinctrl-2 = <&usart2_sleep_pins_a>;
> + /delete-property/ dmas;
> + /delete-property/ dma-names;
> + status = "okay";
> +};
^ 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