* [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 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 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
* 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
* [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] 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
* 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] 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 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 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 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 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 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 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
* [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
* [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 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 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 3/6] media: mediatek: encoder: Add a new encoder driver 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>
Introduce a new encoder kernel driver interface to ensure compatibility
with the updated encoder software driver running in firmware.
The new driver interface is expected to support more encoder formats,
share more encode parameters between kernel and firmware.
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../platform/mediatek/vcodec/encoder/Makefile | 1 +
.../mediatek/vcodec/encoder/mtk_vcodec_enc.c | 14 +-
.../vcodec/encoder/mtk_vcodec_enc_drv.h | 8 +-
.../vcodec/encoder/venc/venc_common_if.c | 674 ++++++++++++++++++
.../vcodec/encoder/venc/venc_h264_if.c | 8 +-
.../mediatek/vcodec/encoder/venc_drv_if.h | 11 +-
6 files changed, 698 insertions(+), 18 deletions(-)
create mode 100644 drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/Makefile b/drivers/media/platform/mediatek/vcodec/encoder/Makefile
index e621b5b7e5e6..9d3229d56e39 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/Makefile
+++ b/drivers/media/platform/mediatek/vcodec/encoder/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-enc.o
mtk-vcodec-enc-y := venc/venc_vp8_if.o \
venc/venc_h264_if.o \
+ venc/venc_common_if.o \
mtk_vcodec_enc.o \
mtk_vcodec_enc_drv.o \
mtk_vcodec_enc_pm.o \
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 fcf0e4f90429..b2f911746c01 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
@@ -81,11 +81,11 @@ static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d", ctrl->val);
- p->h264_profile = ctrl->val;
+ p->profile = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d", ctrl->val);
- p->h264_level = ctrl->val;
+ p->level = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
mtk_v4l2_venc_dbg(2, ctx, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d", ctrl->val);
@@ -367,8 +367,8 @@ static void mtk_venc_set_param(struct mtk_vcodec_enc_ctx *ctx,
mtk_v4l2_venc_err(ctx, "Unsupported fourcc =%d", q_data_src->fmt->fourcc);
break;
}
- param->h264_profile = enc_params->h264_profile;
- param->h264_level = enc_params->h264_level;
+ param->profile = enc_params->profile;
+ param->level = enc_params->level;
/* Config visible resolution */
param->width = q_data_src->visible_width;
@@ -384,8 +384,8 @@ static void mtk_venc_set_param(struct mtk_vcodec_enc_ctx *ctx,
mtk_v4l2_venc_dbg(0, ctx,
"fmt 0x%x, P/L %d/%d w/h %d/%d buf %d/%d fps/bps %d/%d gop %d i_per %d",
- param->input_yuv_fmt, param->h264_profile,
- param->h264_level, param->width, param->height,
+ param->input_yuv_fmt, param->profile,
+ param->level, param->width, param->height,
param->buf_width, param->buf_height,
param->frm_rate, param->bitrate,
param->gop_size, param->intra_period);
@@ -1139,6 +1139,8 @@ static void mtk_venc_worker(struct work_struct *work)
frm_buf.fb_addr[i].size =
(size_t)src_buf->vb2_buf.planes[i].length;
}
+ frm_buf.num_planes = src_buf->vb2_buf.num_planes;
+
bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
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 6c7e8da6d8ee..029133e48073 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
@@ -77,8 +77,8 @@ enum mtk_encode_param {
* @framerate_denom: frame rate denominator. ex: framerate_num=30 and
* framerate_denom=1 means FPS is 30
* @h264_max_qp: Max value for H.264 quantization parameter
- * @h264_profile: V4L2 defined H.264 profile
- * @h264_level: V4L2 defined H.264 level
+ * @profile: V4L2 defined profile
+ * @level: V4L2 defined level
* @force_intra: force/insert intra frame
*/
struct mtk_enc_params {
@@ -92,8 +92,8 @@ struct mtk_enc_params {
unsigned int framerate_num;
unsigned int framerate_denom;
unsigned int h264_max_qp;
- unsigned int h264_profile;
- unsigned int h264_level;
+ unsigned int profile;
+ unsigned int level;
unsigned int force_intra;
};
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
new file mode 100644
index 000000000000..0efb13aef8d6
--- /dev/null
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
@@ -0,0 +1,674 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ */
+
+#include "../mtk_vcodec_enc.h"
+#include "../mtk_vcodec_enc_drv.h"
+#include "../venc_drv_base.h"
+#include "../venc_drv_if.h"
+#include "../venc_vpu_if.h"
+#include "../../common/mtk_vcodec_intr.h"
+#include "../../common/mtk_vcodec_util.h"
+
+#define SEQ_HEADER_SIZE 1024
+#define PPS_SIZE 128
+#define MAX_DPB_SIZE 16
+#define MAX_VENC_CORE 3
+#define VENC_CONFIG_LENGTH 115
+#define VENC_CONFIG_DATA 128
+#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+
+/**
+ * enum venc_bs_mode - encode bitstream mode
+ * @VENC_BS_MODE_SPS: encode sps
+ * @VENC_BS_MODE_PPS: encode pps
+ * @VENC_BS_MODE_VPS: encode vps
+ * @VENC_BS_MODE_SEQ_HDR: encode sequence header
+ * @VENC_BS_MODE_FRAME: encode frame
+ * @VENC_BS_MODE_FRAME_FINAL: encode final frame
+ * @VENC_BS_MODE_MAX: max value
+ */
+enum venc_bs_mode {
+ VENC_BS_MODE_SPS = 0,
+ VENC_BS_MODE_PPS,
+ VENC_BS_MODE_VPS,
+ VENC_BS_MODE_SEQ_HDR,
+ VENC_BS_MODE_FRAME,
+ VENC_BS_MODE_FRAME_FINAL,
+ VENC_BS_MODE_MAX
+};
+
+/**
+ * struct venc_config - Structure for encoder configuration
+ * AP-W/R : AP is writer/reader on this item
+ * MCU-W/R: MCU is write/reader on this item
+ * @input_fourcc: input format fourcc
+ * @bitrate: target bitrate (in bps)
+ * @pic_w: visible width of resolution
+ * @pic_h: visible height of resolution
+ * @buf_w: buffer alignment width of resolution
+ * @buf_h: buffer alignment height of resolution
+ * @gop_size: group of picture size (IDR frame period)
+ * @intra_period: I frame period
+ * @framerate: frame rate in fps
+ * @profile: profile_idc in SPS
+ * @level: level_idc in SPS
+ * @core_num: encoder core num
+ * @dpb_size: encode dpb size
+ * @reserved: reserved fields config
+ */
+struct venc_config {
+ __u32 input_fourcc;
+ __u32 bitrate;
+ __u32 pic_w;
+ __u32 pic_h;
+ __u32 buf_w;
+ __u32 buf_h;
+ __u32 gop_size;
+ __u32 intra_period;
+ __u32 framerate;
+ __u32 profile;
+ __u32 level;
+ __u32 core_num;
+ __u32 dpb_size;
+ __u32 reserved[VENC_CONFIG_LENGTH];
+};
+
+/**
+ * struct venc_config_data - Structure for configuration data
+ * @config_data: extended configuration data besides the basic configuration
+ */
+struct venc_config_data {
+ unsigned int config_data[VENC_CONFIG_DATA];
+};
+
+/**
+ * struct venc_work_buf - Structure for working buffer information
+ * AP-W/R : AP is writer/reader on this item
+ * MCU-W/R: MCU is write/reader on this item
+ * @iova: IO virtual address
+ * @pa: physical address
+ * @pa_64: for 64bit pa padding
+ * @va: virtual address
+ * @va_padding: for 64bit va padding
+ * @size: buffer size
+ * @size_padding: for 64bit size padding
+ */
+struct venc_work_buf {
+ unsigned long long iova;
+ union {
+ unsigned int pa;
+ unsigned long long pa_64;
+ };
+ union {
+ void *va;
+ unsigned long long va_padding;
+ };
+ union {
+ unsigned int size;
+ unsigned long long size_padding;
+ };
+};
+
+/**
+ * struct venc_work_buf_list - Structure for encode working buffer list
+ * @rc_code: RC code buffer
+ * @rc_info: RC info buffer
+ * @luma: luma buffer
+ * @chroma: chroma buffer
+ * @sub_luma: sub luma buffer
+ * @sub_write: sub write buffer
+ * @col_mv: col_mv buffer
+ * @wpp: wpp buffer
+ * @wpp_nbm: wpp nbm buffer
+ * @skip_frame: skip frame buffer
+ */
+struct venc_work_buf_list {
+ struct venc_work_buf rc_code;
+ struct venc_work_buf rc_info[MAX_VENC_CORE];
+ struct venc_work_buf luma[MAX_DPB_SIZE];
+ struct venc_work_buf chroma[MAX_DPB_SIZE];
+ struct venc_work_buf sub_luma[MAX_DPB_SIZE];
+ struct venc_work_buf sub_write[MAX_DPB_SIZE];
+ struct venc_work_buf col_mv[MAX_DPB_SIZE];
+ struct venc_work_buf wpp[MAX_VENC_CORE];
+ struct venc_work_buf wpp_nbm[MAX_VENC_CORE];
+ struct venc_work_buf skip_frame;
+};
+
+/**
+ * struct venc_info - Structure for encode frame and bs information
+ * @fb_addr: frame buffer address array
+ * @fb_size: frame buffer size array
+ * @bs_addr: bitstream buffer address
+ * @bs_size: bitstream buffer size
+ */
+struct venc_info {
+ unsigned long long fb_addr[VIDEO_MAX_PLANES];
+ unsigned int fb_size[VIDEO_MAX_PLANES];
+ unsigned long long bs_addr;
+ unsigned long long bs_size;
+};
+
+/**
+ * struct venc_vsi - Structure for VCP driver control and info share
+ * AP-W/R : AP is writer/reader on this item
+ * VCP-W/R: VCP is write/reader on this item
+ * @config: encoder configuration
+ * @data: encoder configuration data
+ * @bufs: encoder working buffers
+ * @venc: encoder information
+ */
+struct venc_vsi {
+ struct venc_config config;
+ struct venc_config_data data;
+ struct venc_work_buf_list bufs;
+ struct venc_info venc;
+};
+
+/**
+ * struct venc_inst - Structure for encoder instance
+ * @hw_base: hardware io address
+ * @pps_buf: PPS buffer
+ * @seq_buf: sequence header buffer
+ * @work_buf_allocated: work buffer allocated or not
+ * @frm_cnt: encoded frame count
+ * @skip_frm_cnt: encoded skip frame count
+ * @prepend_hdr: prepend header flag
+ * @vpu_inst: vpu instance
+ * @vsi: encode vsi
+ * @ctx: encoder context
+ */
+struct venc_inst {
+ void __iomem *hw_base;
+ struct mtk_vcodec_mem pps_buf;
+ struct mtk_vcodec_mem seq_buf;
+ bool work_buf_allocated;
+ unsigned int frm_cnt;
+ unsigned int skip_frm_cnt;
+ unsigned int prepend_hdr;
+ struct venc_vpu_inst vpu_inst;
+ struct venc_vsi *vsi;
+ struct mtk_vcodec_enc_ctx *ctx;
+};
+
+static int venc_init(struct mtk_vcodec_enc_ctx *ctx)
+{
+ int ret = 0;
+ struct venc_inst *inst;
+
+ inst = kzalloc_obj(*inst, GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->ctx = ctx;
+ inst->vpu_inst.ctx = ctx;
+ inst->vpu_inst.id = ctx->dev->venc_pdata->ipi_id;
+ inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS);
+
+ ret = vpu_enc_init(&inst->vpu_inst);
+ inst->vsi = (struct venc_vsi *)inst->vpu_inst.vsi;
+
+ if (ret) {
+ kfree(inst);
+ return ret;
+ }
+
+ ctx->drv_handle = inst;
+
+ return 0;
+}
+
+static inline u32 venc_read_reg(struct venc_inst *inst, u32 addr)
+{
+ return readl(inst->hw_base + addr);
+}
+
+static unsigned int venc_wait_encode_done(struct venc_inst *inst)
+{
+ unsigned int irq_status = 0;
+ struct mtk_vcodec_enc_ctx *ctx = (struct mtk_vcodec_enc_ctx *)inst->ctx;
+
+ if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, 0)) {
+ irq_status = ctx->irq_status;
+ mtk_venc_debug(ctx, "irq_status %x <-", irq_status);
+ }
+ return irq_status;
+}
+
+static void venc_set_bufs(struct venc_inst *inst,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf)
+{
+ unsigned int i;
+
+ if (frm_buf) {
+ for (i = 0; i < frm_buf->num_planes; i++) {
+ inst->vsi->venc.fb_addr[i] = frm_buf->fb_addr[i].dma_addr;
+ inst->vsi->venc.fb_size[i] = frm_buf->fb_addr[i].size;
+ mtk_venc_debug(inst->ctx, "%s: fb_buf[%d]: %llx(%d)\n",
+ __func__, i,
+ inst->vsi->venc.fb_addr[i],
+ inst->vsi->venc.fb_size[i]);
+ }
+ }
+
+ if (bs_buf) {
+ inst->vsi->venc.bs_addr = bs_buf->dma_addr;
+ inst->vsi->venc.bs_size = bs_buf->size;
+ mtk_venc_debug(inst->ctx, "%s: bs_buf: %llx(%d)\n",
+ __func__,
+ inst->vsi->venc.bs_addr,
+ (unsigned int)inst->vsi->venc.bs_size);
+ }
+}
+
+static int venc_encode_sps(struct venc_inst *inst,
+ struct mtk_vcodec_mem *bs_buf,
+ unsigned int *bs_size)
+{
+ int ret = 0;
+ unsigned int irq_status;
+
+ venc_set_bufs(inst, NULL, bs_buf);
+ ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_SPS, NULL, bs_buf, NULL);
+ if (ret)
+ return ret;
+
+ irq_status = venc_wait_encode_done(inst);
+ if (irq_status != MTK_VENC_IRQ_STATUS_SPS) {
+ mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_SPS);
+ return -EINVAL;
+ }
+
+ *bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
+ mtk_venc_debug(inst->ctx, "sps bs size %d <-", *bs_size);
+
+ return ret;
+}
+
+static int venc_encode_pps(struct venc_inst *inst,
+ struct mtk_vcodec_mem *bs_buf,
+ unsigned int *bs_size)
+{
+ int ret = 0;
+ unsigned int irq_status;
+
+ venc_set_bufs(inst, NULL, bs_buf);
+ ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_PPS, NULL, bs_buf, NULL);
+ if (ret)
+ return ret;
+
+ irq_status = venc_wait_encode_done(inst);
+ if (irq_status != MTK_VENC_IRQ_STATUS_PPS) {
+ mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_PPS);
+ return -EINVAL;
+ }
+
+ *bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
+ mtk_venc_debug(inst->ctx, "pps bs size %d <-", *bs_size);
+
+ return ret;
+}
+
+static int venc_encode_header(struct venc_inst *inst,
+ struct mtk_vcodec_mem *bs_buf,
+ unsigned int *bs_size)
+{
+ int ret = 0;
+ unsigned int bs_size_sps;
+ unsigned int bs_size_pps;
+
+ ret = venc_encode_sps(inst, bs_buf, &bs_size_sps);
+ if (ret)
+ return ret;
+
+ ret = venc_encode_pps(inst, &inst->pps_buf, &bs_size_pps);
+ if (ret)
+ return ret;
+
+ memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
+ *bs_size = bs_size_sps + bs_size_pps;
+
+ return ret;
+}
+
+static int venc_encode_frame(struct venc_inst *inst,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf,
+ unsigned int *bs_size)
+{
+ int ret = 0;
+ unsigned int irq_status;
+
+ venc_set_bufs(inst, frm_buf, bs_buf);
+ ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_FRAME, frm_buf, bs_buf, NULL);
+ if (ret)
+ return ret;
+
+ irq_status = venc_wait_encode_done(inst);
+ if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
+ mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_FRM);
+ return -EINVAL;
+ }
+
+ *bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
+
+ ++inst->frm_cnt;
+
+ return ret;
+}
+
+static int venc_encode(void *handle,
+ enum venc_start_opt opt,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf,
+ struct venc_done_result *result)
+{
+ int ret = 0;
+ struct venc_inst *inst = (struct venc_inst *)handle;
+ struct mtk_vcodec_enc_ctx *ctx;
+ unsigned int bs_size_hdr;
+
+ if (WARN_ON(!inst || !inst->vsi))
+ return -EINVAL;
+
+ ctx = inst->ctx;
+
+ mtk_venc_debug(ctx, "%s: opt: %d\n", __func__, opt);
+
+ enable_irq(ctx->dev->enc_irq);
+ switch (opt) {
+ case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
+ ret = venc_encode_header(inst, bs_buf, &bs_size_hdr);
+ if (ret)
+ goto encode_err;
+
+ result->bs_size = bs_size_hdr;
+ result->is_key_frm = false;
+ break;
+ }
+
+ case VENC_START_OPT_ENCODE_FRAME: {
+ if (!inst->prepend_hdr) {
+ ret = venc_encode_frame(inst, frm_buf, bs_buf, &result->bs_size);
+ if (ret)
+ goto encode_err;
+
+ result->is_key_frm = inst->vpu_inst.is_key_frm;
+ break;
+ }
+
+ ret = venc_encode_header(inst, &inst->seq_buf, &bs_size_hdr);
+ if (ret)
+ goto encode_err;
+
+ ret = venc_encode_frame(inst, frm_buf, bs_buf, &result->bs_size);
+ if (ret)
+ goto encode_err;
+
+ memmove(bs_buf->va + bs_size_hdr, bs_buf->va, result->bs_size);
+ memcpy(bs_buf->va, inst->seq_buf.va, bs_size_hdr);
+ result->bs_size += bs_size_hdr;
+
+ inst->prepend_hdr = 0;
+ result->is_key_frm = inst->vpu_inst.is_key_frm;
+ break;
+ }
+
+ default:
+ mtk_venc_err(inst->ctx, "venc_opt %d not supported", opt);
+ ret = -EINVAL;
+ break;
+ }
+
+encode_err:
+ disable_irq(ctx->dev->enc_irq);
+ mtk_venc_debug(ctx, "opt %d, return %d", opt, ret);
+
+ return ret;
+}
+
+static int mtk_venc_mem_alloc(struct venc_inst *inst,
+ struct device *dev,
+ struct venc_work_buf *buf)
+{
+ dma_addr_t dma_addr;
+
+ if (WARN_ON(!dev || !buf))
+ return -EINVAL;
+
+ if (buf->size == 0)
+ return 0;
+
+ buf->va = dma_alloc_coherent(dev, buf->size, &dma_addr, GFP_KERNEL);
+ if (!buf->va)
+ return -ENOMEM;
+
+ buf->iova = (unsigned long long)dma_addr;
+
+ mtk_venc_debug(inst->ctx, "allocate buffer, size: %d, va: %p, iova: 0x%llx",
+ buf->size, buf->va, buf->iova);
+
+ return 0;
+}
+
+static void mtk_venc_mem_free(struct venc_inst *inst,
+ struct device *dev,
+ struct venc_work_buf *buf)
+{
+ if (WARN_ON(!dev || !buf))
+ return;
+
+ if (!buf->va)
+ return;
+
+ mtk_venc_debug(inst->ctx, "free buffer, size: %d, va: %p, iova: 0x%llx",
+ buf->size, buf->va, buf->iova);
+
+ dma_free_coherent(dev, buf->size, buf->va, buf->iova);
+ buf->va = NULL;
+ buf->iova = 0;
+ buf->size = 0;
+}
+
+static void venc_free_rc_buf(struct venc_inst *inst,
+ struct venc_work_buf_list *bufs,
+ unsigned int core_num)
+{
+ int i;
+ struct device *dev;
+
+ dev = &inst->ctx->dev->plat_dev->dev;
+ mtk_venc_mem_free(inst, dev, &bufs->rc_code);
+
+ for (i = 0; i < core_num; i++)
+ mtk_venc_mem_free(inst, dev, &bufs->rc_info[i]);
+}
+
+static void venc_free_work_buf(struct venc_inst *inst)
+{
+ int i;
+ struct venc_work_buf_list *bufs = &inst->vsi->bufs;
+ unsigned int core_num = inst->vsi->config.core_num;
+ unsigned int dpb_size = inst->vsi->config.dpb_size;
+ struct device *dev;
+
+ if (bufs->rc_code.va)
+ venc_free_rc_buf(inst, bufs, core_num);
+
+ dev = &inst->ctx->dev->plat_dev->dev;
+
+ for (i = 0; i < core_num; i++) {
+ mtk_venc_mem_free(inst, dev, &bufs->wpp[i]);
+ mtk_venc_mem_free(inst, dev, &bufs->wpp_nbm[i]);
+ }
+
+ for (i = 0; i < dpb_size; i++) {
+ mtk_venc_mem_free(inst, dev, &bufs->luma[i]);
+ mtk_venc_mem_free(inst, dev, &bufs->chroma[i]);
+ mtk_venc_mem_free(inst, dev, &bufs->sub_luma[i]);
+ mtk_venc_mem_free(inst, dev, &bufs->sub_write[i]);
+ mtk_venc_mem_free(inst, dev, &bufs->col_mv[i]);
+ }
+
+ if (inst->pps_buf.va)
+ mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
+
+ if (inst->seq_buf.va)
+ mtk_vcodec_mem_free(inst->ctx, &inst->seq_buf);
+}
+
+static int venc_alloc_rc_buf(struct venc_inst *inst,
+ struct venc_work_buf_list *bufs,
+ unsigned int core_num)
+{
+ int i;
+ struct mtk_vcodec_fw *fw = inst->ctx->dev->fw_handler;
+ struct device *dev;
+ void *tmp_va;
+
+ dev = &inst->ctx->dev->plat_dev->dev;
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
+ return -ENOMEM;
+
+ tmp_va = mtk_vcodec_fw_map_dm_addr(fw, bufs->rc_code.pa);
+ memcpy(bufs->rc_code.va, tmp_va, bufs->rc_code.size);
+
+ for (i = 0; i < core_num; i++) {
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_info[i]))
+ goto err_rc_buf;
+ }
+
+ return 0;
+
+err_rc_buf:
+ venc_free_rc_buf(inst, bufs, core_num);
+
+ return -ENOMEM;
+}
+
+static int venc_alloc_work_buf(struct venc_inst *inst)
+{
+ int i, ret;
+ struct venc_work_buf_list *bufs = &inst->vsi->bufs;
+ unsigned int core_num = inst->vsi->config.core_num;
+ unsigned int dpb_size = inst->vsi->config.dpb_size;
+ struct device *dev;
+
+ if (bufs->rc_code.size != 0) {
+ ret = venc_alloc_rc_buf(inst, bufs, core_num);
+ if (ret) {
+ mtk_venc_err(inst->ctx, "cannot allocate rc buf");
+ return -ENOMEM;
+ }
+ }
+
+ dev = &inst->ctx->dev->plat_dev->dev;
+
+ for (i = 0; i < core_num; i++) {
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->wpp[i]) ||
+ mtk_venc_mem_alloc(inst, dev, &bufs->wpp_nbm[i]))
+ goto err_alloc;
+ }
+
+ for (i = 0; i < dpb_size; i++) {
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->luma[i]) ||
+ mtk_venc_mem_alloc(inst, dev, &bufs->chroma[i]) ||
+ mtk_venc_mem_alloc(inst, dev, &bufs->sub_luma[i]) ||
+ mtk_venc_mem_alloc(inst, dev, &bufs->sub_write[i]) ||
+ mtk_venc_mem_alloc(inst, dev, &bufs->col_mv[i]))
+ goto err_alloc;
+ }
+
+ /* the pps_buf and seq_buf are used by AP side only */
+ inst->pps_buf.size = PPS_SIZE;
+ ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf);
+ if (ret) {
+ mtk_venc_err(inst->ctx, "cannot allocate pps_buf");
+ goto err_alloc;
+ }
+
+ inst->seq_buf.size = SEQ_HEADER_SIZE;
+ ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->seq_buf);
+ if (ret) {
+ mtk_venc_err(inst->ctx, "cannot allocate seq_buf");
+ goto err_alloc;
+ }
+ return 0;
+
+err_alloc:
+ venc_free_work_buf(inst);
+ return -ENOMEM;
+}
+
+static int venc_set_param(void *handle,
+ enum venc_set_param_type type,
+ struct venc_enc_param *enc_prm)
+{
+ int ret = 0;
+ struct venc_inst *inst = (struct venc_inst *)handle;
+
+ switch (type) {
+ case VENC_SET_PARAM_ENC:
+ if (WARN_ON(!inst->vsi))
+ return -EINVAL;
+ inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+ inst->vsi->config.bitrate = enc_prm->bitrate;
+ inst->vsi->config.pic_w = enc_prm->width;
+ inst->vsi->config.pic_h = enc_prm->height;
+ inst->vsi->config.buf_w = enc_prm->buf_width;
+ inst->vsi->config.buf_h = enc_prm->buf_height;
+ inst->vsi->config.gop_size = enc_prm->gop_size;
+ inst->vsi->config.framerate = enc_prm->frm_rate;
+ inst->vsi->config.intra_period = enc_prm->intra_period;
+ inst->vsi->config.profile = enc_prm->profile;
+ inst->vsi->config.level = enc_prm->level;
+
+ ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
+ if (ret)
+ break;
+
+ if (inst->work_buf_allocated) {
+ venc_free_work_buf(inst);
+ inst->work_buf_allocated = false;
+ }
+ ret = venc_alloc_work_buf(inst);
+ if (ret)
+ break;
+ inst->work_buf_allocated = true;
+ break;
+ case VENC_SET_PARAM_PREPEND_HEADER:
+ inst->prepend_hdr = 1;
+ break;
+ default:
+ ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
+ break;
+ }
+
+ return ret;
+}
+
+static int venc_deinit(void *handle)
+{
+ int ret = 0;
+ struct venc_inst *inst = (struct venc_inst *)handle;
+
+ ret = vpu_enc_deinit(&inst->vpu_inst);
+
+ if (inst->work_buf_allocated)
+ venc_free_work_buf(inst);
+
+ kfree(inst);
+
+ return ret;
+}
+
+const struct venc_common_if venc_if = {
+ .init = venc_init,
+ .encode = venc_encode,
+ .set_param = venc_set_param,
+ .deinit = venc_deinit,
+};
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
index d2f4d732d2f7..320c505cdb21 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
@@ -723,9 +723,9 @@ static void h264_enc_set_vsi_configs(struct venc_h264_inst *inst,
inst->vsi->config.framerate = enc_prm->frm_rate;
inst->vsi->config.intra_period = enc_prm->intra_period;
inst->vsi->config.profile =
- h264_get_profile(inst, enc_prm->h264_profile);
+ h264_get_profile(inst, enc_prm->profile);
inst->vsi->config.level =
- h264_get_level(inst, enc_prm->h264_level);
+ h264_get_level(inst, enc_prm->level);
inst->vsi->config.wfd = 0;
}
@@ -742,9 +742,9 @@ static void h264_enc_set_vsi_34_configs(struct venc_h264_inst *inst,
inst->vsi_34->config.framerate = enc_prm->frm_rate;
inst->vsi_34->config.intra_period = enc_prm->intra_period;
inst->vsi_34->config.profile =
- h264_get_profile(inst, enc_prm->h264_profile);
+ h264_get_profile(inst, enc_prm->profile);
inst->vsi_34->config.level =
- h264_get_level(inst, enc_prm->h264_level);
+ h264_get_level(inst, enc_prm->level);
inst->vsi_34->config.wfd = 0;
}
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h
index 889440a436b6..3c2a1b5e9312 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.h
@@ -66,8 +66,8 @@ enum venc_set_param_type {
* struct venc_enc_prm - encoder settings for VENC_SET_PARAM_ENC used in
* venc_if_set_param()
* @input_fourcc: input yuv format
- * @h264_profile: V4L2 defined H.264 profile
- * @h264_level: V4L2 defined H.264 level
+ * @profile: V4L2 defined profile
+ * @level: V4L2 defined level
* @width: image width
* @height: image height
* @buf_width: buffer width
@@ -79,8 +79,8 @@ enum venc_set_param_type {
*/
struct venc_enc_param {
enum venc_yuv_fmt input_yuv_fmt;
- unsigned int h264_profile;
- unsigned int h264_level;
+ unsigned int profile;
+ unsigned int level;
unsigned int width;
unsigned int height;
unsigned int buf_width;
@@ -107,9 +107,11 @@ struct venc_frame_info {
/*
* struct venc_frm_buf - frame buffer information used in venc_if_encode()
* @fb_addr: plane frame buffer addresses
+ * @num_planes: number of planes
*/
struct venc_frm_buf {
struct mtk_vcodec_fb fb_addr[MTK_VCODEC_MAX_PLANES];
+ unsigned int num_planes;
};
/*
@@ -124,6 +126,7 @@ struct venc_done_result {
extern const struct venc_common_if venc_h264_if;
extern const struct venc_common_if venc_vp8_if;
+extern const struct venc_common_if venc_if;
/*
* venc_if_init - Create the driver handle
--
2.45.2
^ permalink raw reply related
* [PATCH v7 5/6] media: mediatek: encoder: Add support for VCP encode process
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>
Adapt the encoder driver to support VCP firmware interface.
Use platform data fw_type to identify VCP firmware and perform
VCP-specific operations:
- Allocate RC buffers using the VCP device
- Send shared memory address to VCP firmware
- Map the encoder VSI address to the CPU address space using the
VCP shared memory address.
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
.../mediatek/vcodec/common/mtk_vcodec_fw.c | 6 +++++
.../mediatek/vcodec/common/mtk_vcodec_fw.h | 1 +
.../vcodec/common/mtk_vcodec_fw_priv.h | 1 +
.../vcodec/common/mtk_vcodec_fw_vcp.c | 6 +++++
.../vcodec/encoder/venc/venc_common_if.c | 22 ++++++++++++++-----
.../mediatek/vcodec/encoder/venc_vpu_if.c | 16 ++++++++++++--
6 files changed, 44 insertions(+), 8 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 9df64200d933..7619ccd1f538 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
@@ -90,3 +90,9 @@ int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
return fw->type;
}
EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
+
+struct device *mtk_vcodec_fw_get_dev(struct mtk_vcodec_fw *fw)
+{
+ return fw->ops->get_fw_dev(fw);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_dev);
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
index 142e2e87905c..8ff6fcc114e3 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
@@ -42,5 +42,6 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
void *buf, unsigned int len, unsigned int wait);
int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
int mtk_vcodec_fw_get_ipi(enum mtk_vcodec_fw_type type, int hw_id);
+struct device *mtk_vcodec_fw_get_dev(struct mtk_vcodec_fw *fw);
#endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
index 0a2a9b010244..710c83c871f4 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
@@ -29,6 +29,7 @@ struct mtk_vcodec_fw_ops {
int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf,
unsigned int len, unsigned int wait);
void (*release)(struct mtk_vcodec_fw *fw);
+ struct device *(*get_fw_dev)(struct mtk_vcodec_fw *fw);
};
#if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU)
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
index 061a61bda33f..72627fef0ac5 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
@@ -494,6 +494,11 @@ static void mtk_vcodec_vcp_release(struct mtk_vcodec_fw *fw)
fw->vcp->is_register_done = false;
}
+static struct device *mtk_vcodec_vcp_get_fw_dev(struct mtk_vcodec_fw *fw)
+{
+ return fw->vcp->vcp_device->dev;
+}
+
static const struct mtk_vcodec_fw_ops mtk_vcodec_vcp_msg = {
.load_firmware = mtk_vcodec_vcp_load_firmware,
.get_vdec_capa = mtk_vcodec_vcp_get_vdec_capa,
@@ -501,6 +506,7 @@ static const struct mtk_vcodec_fw_ops mtk_vcodec_vcp_msg = {
.ipi_register = mtk_vcodec_vcp_set_ipi_register,
.ipi_send = mtk_vcodec_vcp_ipi_send,
.release = mtk_vcodec_vcp_release,
+ .get_fw_dev = mtk_vcodec_vcp_get_fw_dev,
};
struct mtk_vcodec_fw *mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use fw_use)
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
index 0efb13aef8d6..5ee138f0b2e7 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
@@ -481,7 +481,11 @@ static void venc_free_rc_buf(struct venc_inst *inst,
int i;
struct device *dev;
- dev = &inst->ctx->dev->plat_dev->dev;
+ if (inst->ctx->dev->venc_pdata->fw_type == VCP)
+ dev = mtk_vcodec_fw_get_dev(inst->ctx->dev->fw_handler);
+ else
+ dev = &inst->ctx->dev->plat_dev->dev;
+
mtk_venc_mem_free(inst, dev, &bufs->rc_code);
for (i = 0; i < core_num; i++)
@@ -530,12 +534,18 @@ static int venc_alloc_rc_buf(struct venc_inst *inst,
struct device *dev;
void *tmp_va;
- dev = &inst->ctx->dev->plat_dev->dev;
- if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
- return -ENOMEM;
+ if (inst->ctx->dev->venc_pdata->fw_type == VCP) {
+ dev = mtk_vcodec_fw_get_dev(fw);
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
+ return -ENOMEM;
+ } else {
+ dev = &inst->ctx->dev->plat_dev->dev;
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
+ return -ENOMEM;
- tmp_va = mtk_vcodec_fw_map_dm_addr(fw, bufs->rc_code.pa);
- memcpy(bufs->rc_code.va, tmp_va, bufs->rc_code.size);
+ tmp_va = mtk_vcodec_fw_map_dm_addr(fw, bufs->rc_code.pa);
+ memcpy(bufs->rc_code.va, tmp_va, bufs->rc_code.size);
+ }
for (i = 0; i < core_num; i++) {
if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_info[i]))
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 7772b8442ebc..1da9043fd4f6 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
@@ -8,16 +8,26 @@
#include "venc_ipi_msg.h"
#include "venc_vpu_if.h"
+#define VSI_OFFSET_MASK 0x0FFFFFFF
+
static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
{
const struct venc_vpu_ipi_msg_init_comm *msg = data;
struct mtk_vcodec_fw *fw = vpu->ctx->dev->fw_handler;
+ u64 pa_start, vsi_offset;
vpu->inst_addr = msg->init_ack.vpu_inst_addr;
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, vpu->inst_addr);
+
+ if (vpu->ctx->dev->venc_pdata->fw_type == VCP) {
+ pa_start = (u64)fw->vcp->iova_addr;
+ vsi_offset = (msg->vpu_vsi_addr & VSI_OFFSET_MASK) - (pa_start & VSI_OFFSET_MASK);
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, ENCODER_MEM) + vsi_offset;
+ } else {
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, msg->vpu_vsi_addr);
+ }
/* Firmware version field value is unspecified on MT8173. */
- if (mtk_vcodec_fw_get_type(fw) == VPU)
+ if (vpu->ctx->dev->venc_pdata->fw_type == VPU)
return;
/* Check firmware version. */
@@ -155,6 +165,8 @@ int vpu_enc_init(struct venc_vpu_inst *vpu)
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;
+ if (vpu->ctx->dev->venc_pdata->fw_type == VCP)
+ out.shared_iova = vpu->ctx->dev->fw_handler->vcp->iova_addr;
msg_size = sizeof(struct venc_ap_ipi_msg_init_comm);
} else {
msg_size = sizeof(struct venc_ap_ipi_msg_init);
--
2.45.2
^ permalink raw reply related
* [PATCH v7 6/6] media: mediatek: encoder: Add MT8196 encoder compatible data
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>
MT8196 encoder use common firmware interface, add compatible data to
support MT8196 encoding, and need set dma mask to support 34bit.
Signed-off-by: Irui Wang <irui.wang@mediatek.com>
---
.../vcodec/encoder/mtk_vcodec_enc_drv.c | 22 +++++++++++++++++++
.../vcodec/encoder/mtk_vcodec_enc_drv.h | 2 ++
2 files changed, 24 insertions(+)
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 5f1feb3b07a6..bc6dfb564026 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
@@ -20,6 +20,8 @@
#include "mtk_vcodec_enc_pm.h"
#include "../common/mtk_vcodec_intr.h"
+#define VENC_DMA_BIT_MASK 34
+
static const struct mtk_video_fmt mtk_video_formats_output[] = {
{
.fourcc = V4L2_PIX_FMT_NV12M,
@@ -298,6 +300,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
goto err_res;
}
+ if (dev->venc_pdata->set_dma_bit_mask)
+ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(VENC_DMA_BIT_MASK));
+
mutex_init(&dev->enc_mutex);
mutex_init(&dev->dev_mutex);
spin_lock_init(&dev->dev_ctx_lock);
@@ -461,6 +466,22 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
.fw_init = mtk_vcodec_fw_scp_init,
};
+static const struct mtk_vcodec_enc_pdata mt8196_pdata = {
+ .venc_model_num = 8196,
+ .capture_formats = mtk_video_formats_capture_h264,
+ .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
+ .output_formats = mtk_video_formats_output,
+ .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
+ .min_bitrate = 64,
+ .max_bitrate = 100000000,
+ .core_id = VENC_SYS,
+ .uses_common_fw_iface = true,
+ .set_dma_bit_mask = true,
+ .fw_type = VCP,
+ .fw_init = mtk_vcodec_fw_vcp_init,
+ .ipi_id = VCP_IPI_ENCODER,
+};
+
static const struct of_device_id mtk_vcodec_enc_match[] = {
{.compatible = "mediatek,mt8173-vcodec-enc",
.data = &mt8173_avc_pdata},
@@ -470,6 +491,7 @@ static const struct of_device_id mtk_vcodec_enc_match[] = {
{.compatible = "mediatek,mt8188-vcodec-enc", .data = &mt8188_pdata},
{.compatible = "mediatek,mt8192-vcodec-enc", .data = &mt8192_pdata},
{.compatible = "mediatek,mt8195-vcodec-enc", .data = &mt8195_pdata},
+ {.compatible = "mediatek,mt8196-vcodec-enc", .data = &mt8196_pdata},
{},
};
MODULE_DEVICE_TABLE(of, 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 8a69168c350e..1aad27008ce6 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
@@ -32,6 +32,7 @@
* @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
+ * @set_dma_bit_mask: whether the encoder need set extra DMA bit mask
* @fw_type: firmware type (VPU, SCP, or VCP)
* @fw_init: firmware-specific initialization callback
* @ipi_id: IPI ID for encoder communication with firmware
@@ -48,6 +49,7 @@ struct mtk_vcodec_enc_pdata {
u8 core_id;
bool uses_34bit;
bool uses_common_fw_iface;
+ bool set_dma_bit_mask;
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;
--
2.45.2
^ permalink raw reply related
* Re: [PATCH] pinctrl: Move Airoha driver to dedicated directory
From: Lorenzo Bianconi @ 2026-06-05 9:49 UTC (permalink / raw)
To: Christian Marangi
Cc: Linus Walleij, Sean Wang, Matthias Brugger,
AngeloGioacchino Del Regno, linux-kernel, linux-gpio,
linux-mediatek, linux-arm-kernel
In-Reply-To: <20260605071233.28873-1-ansuelsmth@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5747 bytes --]
> In preparation for additional SoC support, move the Airoha pinctrl driver
> for AN7581 SoC to a dedicated directory.
>
> This is to tidy things up and keep code organized without polluting the
> Mediatek driver directory.
>
> The driver doesn't depend on any generic or common code from the Mediatek
> codebase so it can be safely moved without any modification.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> MAINTAINERS | 2 +-
> drivers/pinctrl/Kconfig | 1 +
> drivers/pinctrl/Makefile | 1 +
> drivers/pinctrl/airoha/Kconfig | 20 +++++++++++++++++++
> drivers/pinctrl/airoha/Makefile | 3 +++
> .../{mediatek => airoha}/pinctrl-airoha.c | 0
> drivers/pinctrl/mediatek/Kconfig | 17 +---------------
> drivers/pinctrl/mediatek/Makefile | 1 -
> 8 files changed, 27 insertions(+), 18 deletions(-)
> create mode 100644 drivers/pinctrl/airoha/Kconfig
> create mode 100644 drivers/pinctrl/airoha/Makefile
> rename drivers/pinctrl/{mediatek => airoha}/pinctrl-airoha.c (100%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 21c0ef0b9ce5..38bf92149a15 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21024,7 +21024,7 @@ M: Lorenzo Bianconi <lorenzo@kernel.org>
> L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> S: Maintained
> F: Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
> -F: drivers/pinctrl/mediatek/pinctrl-airoha.c
> +F: drivers/pinctrl/airoha/pinctrl-airoha.c
>
> PIN CONTROLLER - AMD
> M: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 03f2e3ee065f..e0babad31445 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -679,6 +679,7 @@ config PINCTRL_RP1
> multi function device.
>
> source "drivers/pinctrl/actions/Kconfig"
> +source "drivers/pinctrl/airoha/Kconfig"
> source "drivers/pinctrl/aspeed/Kconfig"
> source "drivers/pinctrl/bcm/Kconfig"
> source "drivers/pinctrl/berlin/Kconfig"
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index f7d5d5f76d0c..36c55858801f 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -66,6 +66,7 @@ obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
> obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
>
> obj-y += actions/
> +obj-y += airoha/
> obj-$(CONFIG_ARCH_ASPEED) += aspeed/
> obj-y += bcm/
> obj-$(CONFIG_PINCTRL_BERLIN) += berlin/
> diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
> new file mode 100644
> index 000000000000..03adaeae8fc3
> --- /dev/null
> +++ b/drivers/pinctrl/airoha/Kconfig
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +menu "Airoha pinctrl drivers"
> + depends on ARCH_AIROHA || COMPILE_TEST
> +
> +config PINCTRL_AIROHA
> + tristate "Airoha EN7581 pin control"
> + depends on OF
> + depends on ARM64 || COMPILE_TEST
> + select PINMUX
> + select GENERIC_PINCONF
> + select GENERIC_PINCTRL_GROUPS
> + select GENERIC_PINMUX_FUNCTIONS
> + select GPIOLIB
> + select GPIOLIB_IRQCHIP
> + select REGMAP_MMIO
> + help
> + Say yes here to support pin controller and gpio driver
> + on Airoha EN7581 SoC.
> +
> +endmenu
> diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
> new file mode 100644
> index 000000000000..a25b744dd7a8
> --- /dev/null
> +++ b/drivers/pinctrl/airoha/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
> diff --git a/drivers/pinctrl/mediatek/pinctrl-airoha.c b/drivers/pinctrl/airoha/pinctrl-airoha.c
> similarity index 100%
> rename from drivers/pinctrl/mediatek/pinctrl-airoha.c
> rename to drivers/pinctrl/airoha/pinctrl-airoha.c
> diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
> index 4819617d9368..97980cc28b9c 100644
> --- a/drivers/pinctrl/mediatek/Kconfig
> +++ b/drivers/pinctrl/mediatek/Kconfig
> @@ -1,6 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0-only
> menu "MediaTek pinctrl drivers"
> - depends on ARCH_MEDIATEK || ARCH_AIROHA || RALINK || COMPILE_TEST
> + depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
>
> config EINT_MTK
> tristate "MediaTek External Interrupt Support"
> @@ -126,21 +126,6 @@ config PINCTRL_MT8127
> select PINCTRL_MTK
>
> # For ARMv8 SoCs
> -config PINCTRL_AIROHA
> - tristate "Airoha EN7581 pin control"
> - depends on OF
> - depends on ARM64 || COMPILE_TEST
> - select PINMUX
> - select GENERIC_PINCONF
> - select GENERIC_PINCTRL_GROUPS
> - select GENERIC_PINMUX_FUNCTIONS
> - select GPIOLIB
> - select GPIOLIB_IRQCHIP
> - select REGMAP_MMIO
> - help
> - Say yes here to support pin controller and gpio driver
> - on Airoha EN7581 SoC.
> -
> config PINCTRL_MT2712
> bool "MediaTek MT2712 pin control"
> depends on OF
> diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
> index ae765bd99965..6dc17b0c23f9 100644
> --- a/drivers/pinctrl/mediatek/Makefile
> +++ b/drivers/pinctrl/mediatek/Makefile
> @@ -8,7 +8,6 @@ obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o
> obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o
>
> # SoC Drivers
> -obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
> obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
> obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o
> obj-$(CONFIG_PINCTRL_MT76X8) += pinctrl-mt76x8.o
> --
> 2.53.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v6 0/3] arm64: dts: rockchip: add Vicharak Axon board support
From: Krzysztof Kozlowski @ 2026-06-05 10:15 UTC (permalink / raw)
To: Hrushiraj Gandhi
Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
devicetree, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <20260601162143.170030-1-hrushirajg23@gmail.com>
On Mon, Jun 01, 2026 at 09:51:39PM +0530, Hrushiraj Gandhi wrote:
> This series adds initial device tree support for the Vicharak Axon
> single-board computer, which is based on the Rockchip RK3588 SoC.
>
> The Vicharak Axon is a feature-rich SBC targeting developer and embedded
> use cases. It ships with:
Slow down, please. One patchset per 24h.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v3 0/3] Add Shikra (QCM2390) display support
From: Nabige Aala @ 2026-06-05 10:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Krishna Manikandan,
Loic Poulain, Bjorn Andersson, Konrad Dybcio, Will Deacon,
Robin Murphy, Joerg Roedel (AMD)
Cc: linux-arm-msm, dri-devel, freedreno, devicetree, linux-kernel,
iommu, linux-arm-kernel, Nabige Aala, Dmitry Baryshkov
Shikra (QCM2390) is a Qualcomm SoC based on the QCM2290 family that
reuses the same MDSS/DPU 6.5 hardware as QCM2290. This series enables
the display subsystem for Shikra by adding DT binding updates for MDSS,
DSI controller and DPU, arm64 defconfig enablement for the ILI7807S DSI
panel, and UBWC configuration mapping Shikra to qcm2290_data.
Driver and SMMU support are covered by the existing qcom,qcm2290-mdss
fallback compatible string — no separate drm/msm or IOMMU patches are
required.
Tested on Shikra CQM EVK board with ILI7807S DSI panel. Display
pipeline probes cleanly and panel renders correctly.
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
---
Nabige Aala (3):
dt-bindings: display: msm: qcm2290: Add Shikra MDSS
arm64: defconfig: Enable ILI7807S DSI panel driver
soc: qcom: ubwc: Add Shikra UBWC config
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml | 4 ++++
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml | 7 +++++--
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml | 22 +++++++++++++++-------
arch/arm64/configs/defconfig | 1 +
drivers/soc/qcom/ubwc_config.c | 1 +
5 files changed, 26 insertions(+), 9 deletions(-)
---
Prerequisite-Message-Id: <20260518-ili7807s-panel-v1-0-d7b048163b1c@oss.qualcomm.com>
---
Changes in v3:
- Use a fallback compatible chain for qcom,shikra-dsi-ctrl
in dsi-controller-main.yaml instead of a standalone enum entry, with
qcom,qcm2290-dsi-ctrl and qcom,mdss-dsi-ctrl as fallbacks
- Replace oneOf in qcm2290-mdss patternProperties DSI compatible with
contains: qcom,qcm2290-dsi-ctrl to avoid duplicating full chain
validation already handled by dsi-controller-main.yaml
- Drop unnecessary select: block from qcom,qcm2290-mdss.yaml; default
dt-validate compatible matching is sufficient
- Remove self from qcom,qcm2290-mdss.yaml maintainers list
- Link to v2: https://patch.msgid.link/20260604-shikra-display-v2-0-b3c1b2b67edc@oss.qualcomm.com
Changes in v2:
- Drop drm/msm/mdss: Shikra support patch; driver reuse is handled via
the qcom,qcm2290-mdss fallback compatible string (per Dmitry's review)
- Drop iommu/arm-smmu: Shikra SMMU client table patch; not required with
fallback compatible approach
- Fix UBWC config to map qcom,shikra to qcm2290_data instead of
no_ubwc_data; Shikra shares UBWC support with QCM2290
- Refactor series from 5 patches to 3 patches
- Link to v1: https://patch.msgid.link/20260603-shikra-display-v1-0-aeac1b94faa7@oss.qualcomm.com
---
Nabige Aala (3):
dt-bindings: display: msm: qcm2290: Add Shikra MDSS
arm64: defconfig: Enable ILI7807S DSI panel driver
soc: qcom: ubwc: Add Shikra UBWC config
.../bindings/display/msm/dsi-controller-main.yaml | 4 ++++
.../bindings/display/msm/qcom,qcm2290-dpu.yaml | 7 +++++--
.../bindings/display/msm/qcom,qcm2290-mdss.yaml | 22 +++++++++++++++-------
arch/arm64/configs/defconfig | 1 +
drivers/soc/qcom/ubwc_config.c | 1 +
5 files changed, 26 insertions(+), 9 deletions(-)
---
base-commit: 3a34f9c13cc0688f8db2a0db8506bf8c0d90737d
change-id: 20260603-shikra-display-07767208fa90
Best regards,
--
Nabige Aala <nabige.aala@oss.qualcomm.com>
^ permalink raw reply
* [PATCH v3 1/3] dt-bindings: display: msm: qcm2290: Add Shikra MDSS
From: Nabige Aala @ 2026-06-05 10:18 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Krishna Manikandan,
Loic Poulain, Bjorn Andersson, Konrad Dybcio, Will Deacon,
Robin Murphy, Joerg Roedel (AMD)
Cc: linux-arm-msm, dri-devel, freedreno, devicetree, linux-kernel,
iommu, linux-arm-kernel, Nabige Aala
In-Reply-To: <20260605-shikra-display-v3-0-9846ba5fe635@oss.qualcomm.com>
Shikra reuses the same MDSS/DPU 6.5 hardware as QCM2290. Extend
the existing qcm2290 bindings to cover Shikra by adding fallback
compatible chains for MDSS, DPU and DSI controller nodes rather
than introducing a separate binding file.
Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
---
.../bindings/display/msm/dsi-controller-main.yaml | 4 ++++
.../bindings/display/msm/qcom,qcm2290-dpu.yaml | 7 +++++--
.../bindings/display/msm/qcom,qcm2290-mdss.yaml | 22 +++++++++++++++-------
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index dbc0613e427e..ab2cfd6d6e3e 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -57,6 +57,10 @@ properties:
- const: qcom,eliza-dsi-ctrl
- const: qcom,sm8750-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
+ - items:
+ - const: qcom,shikra-dsi-ctrl
+ - const: qcom,qcm2290-dsi-ctrl
+ - const: qcom,mdss-dsi-ctrl
- enum:
- qcom,dsi-ctrl-6g-qcm2290
- qcom,mdss-dsi-ctrl # This should always come with an SoC-specific compatible
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
index be6cd8adb3b6..e166a73651df 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
@@ -13,8 +13,11 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
- const: qcom,qcm2290-dpu
-
+ oneOf:
+ - const: qcom,qcm2290-dpu
+ - items:
+ - const: qcom,shikra-dpu
+ - const: qcom,qcm2290-dpu
reg:
items:
- description: Address offset and size for mdp register set
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
index bb09ecd1a5b4..ef21b2c263f2 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Qualcomm QCM220 Display MDSS
+title: Qualcomm QCM2290 and Shikra Display MDSS
maintainers:
- Loic Poulain <loic.poulain@linaro.org>
@@ -12,13 +12,18 @@ maintainers:
description:
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
- are mentioned for QCM2290 target.
+ are mentioned for QCM2290 and Shikra targets. Shikra uses the same MDSS/DPU/DSI
+ hardware as QCM2290 (DPU 6.5) and shares the same register layout.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
- const: qcom,qcm2290-mdss
+ oneOf:
+ - const: qcom,qcm2290-mdss
+ - items:
+ - const: qcom,shikra-mdss
+ - const: qcom,qcm2290-mdss
clocks:
items:
@@ -52,7 +57,11 @@ patternProperties:
properties:
compatible:
- const: qcom,qcm2290-dpu
+ oneOf:
+ - const: qcom,qcm2290-dpu
+ - items:
+ - const: qcom,shikra-dpu
+ - const: qcom,qcm2290-dpu
"^dsi@[0-9a-f]+$":
type: object
@@ -60,9 +69,8 @@ patternProperties:
properties:
compatible:
- items:
- - const: qcom,qcm2290-dsi-ctrl
- - const: qcom,mdss-dsi-ctrl
+ contains:
+ const: qcom,qcm2290-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
--
2.34.1
^ permalink raw reply related
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