* Re: [PATCH] pinctrl: qcom: Make important drivers default
From: Konrad Dybcio @ 2026-04-27 10:18 UTC (permalink / raw)
To: Krzysztof Kozlowski, Russell King, Bjorn Andersson, Konrad Dybcio,
Linus Walleij, linux-arm-kernel, linux-kernel, linux-arm-msm,
linux-gpio
In-Reply-To: <20260425155505.83688-2-krzysztof.kozlowski@oss.qualcomm.com>
On 4/25/26 5:55 PM, Krzysztof Kozlowski wrote:
> The main SoC TLMM (Top-Level Multiplexer) pin controller drivers are
> essential for booting up SoCs and are not really optional for a given
> platform. Kernel should not ask users choice of drivers when that
> choice is obvious and known to the developers that answer should be
> 'yes' or 'module'.
>
> Switch all Qualcomm TLMM pin controller drivers to a default 'yes' for
> ARCH_QCOM. This has impact:
>
> 1. arm64 defconfig: enable PINCTRL_SM7150 and PINCTRL_HAWI, which were
> not selected before but should be, because these platforms need them
> for proper boot.
>
> 2. arm qcom_defconfig: no changes.
>
> 3. arm multi_v7 defconfig: enable drivers necessary to boot ARM 32-bit
> platforms, which are already enabled on qcom_defconfig.
>
> 4. COMPILE_TEST builds: enable by default all drivers for arm or arm64
> builds, whenever ARCH_QCOM is selected. This has impact on build
> time and feels logical, because if one selects ARCH_QCOM then
> probably by default wants to build test it entirely. Kernels with
> COMPILE_TEST are not supposed to be used for booting.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH] pinctrl: mediatek: moore: implement gpio_chip::get_direction()
From: Bartosz Golaszewski @ 2026-04-27 10:32 UTC (permalink / raw)
To: Linus Walleij
Cc: Frank Wunderlich, Frank Wunderlich, bartosz.golaszewski, linux,
sean.wang, matthias.bgg, angelogioacchino.delregno,
linux-mediatek, linux-gpio, linux-kernel, linux-arm-kernel
In-Reply-To: <CAD++jLkz189qT1kJr34ratZT_n20oWEAQg8q0ttQ-VrsFchp7g@mail.gmail.com>
On Sun, Apr 19, 2026 at 11:25 PM Linus Walleij <linusw@kernel.org> wrote:
>
> On Mon, Apr 13, 2026 at 6:59 PM Frank Wunderlich
> <frank.wunderlich@linux.dev> wrote:
> > Am 13. April 2026 um 10:01 schrieb "Linus Walleij" <linusw@kernel.org mailto:linusw@kernel.org?to=%22Linus%20Walleij%22%20%3Clinusw%40kernel.org%3E >:
> > >
> > > On Fri, Apr 10, 2026 at 11:24 AM Frank Wunderlich
> > > <frank-w@public-files.de> wrote:
> > >
> > > >
> > > > Gesendet: Freitag, 10. April 2026 um 09:09
> > > > Von: "Bartosz Golaszewski" <bartosz.golaszewski@oss.qualcomm.com>
> > > > An: "Frank Wunderlich" <linux@fw-web.de>, "Sean Wang" <sean.wang@kernel.org>, "Linus Walleij" <linusw@kernel.org>, "Matthias Brugger" <matthias.bgg@gmail.com>, "AngeloGioacchino Del Regno" <angelogioacchino.delregno@collabora.com>, "Bartosz Golaszewski" <brgl@kernel.org>
> > > > CC: linux-mediatek@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, "Bartosz Golaszewski" <bartosz.golaszewski@oss.qualcomm.com>
> > > > Betreff: [PATCH] pinctrl: mediatek: moore: implement gpio_chip::get_direction()
> > > >
> > > > If the gpio_chip::get_direction() callback is not implemented by the GPIO
> > > > controller driver, GPIOLIB emits a warning.
> > > >
> > > > Implement get_direction() for the GPIO part of pinctrl-moore.
> > > >
> > > > Fixes: 471e998c0e31 ("gpiolib: remove redundant callback check")
> > > > Fixes: e623c4303ed1 ("gpiolib: sanitize the return value of gpio_chip::get_direction()")
> > > > Reported-by: Frank Wunderlich <linux@fw-web.de>
> > > >
> > > > please use the email i used for SoB in my linked patch (closes link below), the other email i use only for sending patches due to mail provider limitation.
> > > >
> > > I can't fix this up because the closes link isn't working right now.
> > > Is it the same
> > > as the one this mail came from frank-w@public-files.de?
> >
> > yes, closes-link works for me
>
> Fixed up and applied. Will be going in as fix for v7.1.
>
> Yours,
> Linus Walleij
>
Hi Linus!
It seems this one got lost somewhere along the way? I don't see it in
mainline nor next.
Bart
^ permalink raw reply
* Re: [PATCH v4 3/3] coco: guest: arm64: Query host IPA-change alignment via RHI
From: Marc Zyngier @ 2026-04-27 10:33 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-kernel, iommu, linux-coco, linux-arm-kernel, kvmarm,
Catalin Marinas, Jason Gunthorpe, Marek Szyprowski, Robin Murphy,
Steven Price, Suzuki K Poulose, Thomas Gleixner, Will Deacon
In-Reply-To: <20260427063108.909019-4-aneesh.kumar@kernel.org>
On Mon, 27 Apr 2026 07:31:08 +0100,
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
>
> Add the Realm Host Interface support needed to query host configuration
> from a Realm guest. Define the RHI hostconf SMCs, add rsi_host_call(), and
> use them during Realm initialization to retrieve the host IPA-change
> alignment size.
I don't understand what "IPA-change" means. What you are after is the
host's sharing granule size.
>
> Expose that alignment through realm_get_hyp_pagesize() and
> mem_decrypt_granule_size() so shared-buffer allocation and
> encryption/decryption paths can honor the ipa change page-size requirement.
>
> If the host reports an invalid alignment (when alginment value is not
> multiple of 4K), do not enable Realm support.
>
> This provides the host alignment information required by the shared buffer
> alignment changes.
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> arch/arm64/include/asm/mem_encrypt.h | 3 ++
> arch/arm64/include/asm/rhi.h | 24 +++++++++++++
> arch/arm64/include/asm/rsi.h | 2 ++
> arch/arm64/include/asm/rsi_cmds.h | 10 ++++++
> arch/arm64/include/asm/rsi_smc.h | 7 ++++
> arch/arm64/kernel/Makefile | 2 +-
> arch/arm64/kernel/rhi.c | 54 ++++++++++++++++++++++++++++
> arch/arm64/kernel/rsi.c | 13 +++++++
> arch/arm64/mm/mem_encrypt.c | 8 +++++
> 9 files changed, 122 insertions(+), 1 deletion(-)
> create mode 100644 arch/arm64/include/asm/rhi.h
> create mode 100644 arch/arm64/kernel/rhi.c
>
> diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
> index 314b2b52025f..5541911eb028 100644
> --- a/arch/arm64/include/asm/mem_encrypt.h
> +++ b/arch/arm64/include/asm/mem_encrypt.h
> @@ -16,6 +16,9 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops);
> int set_memory_encrypted(unsigned long addr, int numpages);
> int set_memory_decrypted(unsigned long addr, int numpages);
>
> +#define mem_decrypt_granule_size mem_decrypt_granule_size
> +size_t mem_decrypt_granule_size(void);
> +
> int realm_register_memory_enc_ops(void);
>
> static inline bool force_dma_unencrypted(struct device *dev)
> diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h
> new file mode 100644
> index 000000000000..0895dd92ea1d
> --- /dev/null
> +++ b/arch/arm64/include/asm/rhi.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2026 ARM Ltd.
> + */
> +
> +#ifndef __ASM_RHI_H_
> +#define __ASM_RHI_H_
> +
> +#include <linux/types.h>
> +
> +#define SMC_RHI_CALL(func) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_64, \
> + ARM_SMCCC_OWNER_STANDARD_HYP,\
> + (func))
> +
> +unsigned long rhi_get_ipa_change_alignment(void);
> +#define RHI_HOSTCONF_VER_1_0 0x10000
> +#define RHI_HOSTCONF_VERSION SMC_RHI_CALL(0x004E)
> +
> +#define __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT BIT(0)
> +#define RHI_HOSTCONF_FEATURES SMC_RHI_CALL(0x004F)
> +#define RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT SMC_RHI_CALL(0x0050)
> +#endif
> diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
> index 88b50d660e85..ae54fb3b1429 100644
> --- a/arch/arm64/include/asm/rsi.h
> +++ b/arch/arm64/include/asm/rsi.h
> @@ -67,4 +67,6 @@ static inline int rsi_set_memory_range_shared(phys_addr_t start,
> return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY,
> RSI_CHANGE_DESTROYED);
> }
> +
> +unsigned long realm_get_hyp_pagesize(void);
> #endif /* __ASM_RSI_H_ */
> diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi_cmds.h
> index 2c8763876dfb..a341ce0eeda1 100644
> --- a/arch/arm64/include/asm/rsi_cmds.h
> +++ b/arch/arm64/include/asm/rsi_cmds.h
> @@ -159,4 +159,14 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
> return res.a0;
> }
>
> +static inline unsigned long rsi_host_call(struct rsi_host_call *rhi_call)
> +{
> + phys_addr_t addr = virt_to_phys(rhi_call);
> + struct arm_smccc_res res;
> +
> + arm_smccc_1_1_invoke(SMC_RSI_HOST_CALL, addr, &res);
Errr... What guarantees that *rhi_call is *IPA contiguous*? This is
incredibly fragile. You should at the very least check that this isn't
vmalloc'd.
> +
> + return res.a0;
> +}
> +
> #endif /* __ASM_RSI_CMDS_H */
> diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_smc.h
> index e19253f96c94..9ee8b5c7612e 100644
> --- a/arch/arm64/include/asm/rsi_smc.h
> +++ b/arch/arm64/include/asm/rsi_smc.h
> @@ -182,6 +182,13 @@ struct realm_config {
> */
> #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198)
>
> +struct rsi_host_call {
> + union {
> + u16 imm;
> + u64 padding0;
> + };
> + u64 gprs[31];
> +} __aligned(0x100);
> /*
> * Make a Host call.
> *
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index fe627100d199..3e72dd9584ed 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -34,7 +34,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
> cpufeature.o alternative.o cacheinfo.o \
> smp.o smp_spin_table.o topology.o smccc-call.o \
> syscall.o proton-pack.o idle.o patching.o pi/ \
> - rsi.o jump_label.o
> + rsi.o jump_label.o rhi.o
>
> obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
> sys_compat.o
> diff --git a/arch/arm64/kernel/rhi.c b/arch/arm64/kernel/rhi.c
> new file mode 100644
> index 000000000000..7cd6c5102464
> --- /dev/null
> +++ b/arch/arm64/kernel/rhi.c
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 ARM Ltd.
> + */
> +
> +#include <linux/mm.h>
> +#include <asm/rsi.h>
> +#include <asm/rhi.h>
> +
> +/* we need an aligned rhicall for rsi_host_call. slab is not yet ready */
> +static struct rsi_host_call hyp_pagesize_rhicall;
Why the "hyp_" prefix? This has absolutely nothing to with the
hypervisor.
> +unsigned long rhi_get_ipa_change_alignment(void)
> +{
> + long ret;
> + unsigned long ipa_change_align;
> +
> + hyp_pagesize_rhicall.imm = 0;
> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_VERSION;
> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> + if (ret != RSI_SUCCESS)
> + goto err_out;
> +
> + if (hyp_pagesize_rhicall.gprs[0] != RHI_HOSTCONF_VER_1_0)
> + goto err_out;
> +
> + hyp_pagesize_rhicall.imm = 0;
> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_FEATURES;
> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> + if (ret != RSI_SUCCESS)
> + goto err_out;
> +
> + if (!(hyp_pagesize_rhicall.gprs[0] & __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT))
> + goto err_out;
> +
> + hyp_pagesize_rhicall.imm = 0;
> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT;
> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> + if (ret != RSI_SUCCESS)
> + goto err_out;
> +
> + ipa_change_align = hyp_pagesize_rhicall.gprs[0];
> + /* This error needs special handling in the caller */
> + if (ipa_change_align & (SZ_4K - 1))
> + return 0;
> +
> + return ipa_change_align;
> +
> +err_out:
> + /*
> + * For failure condition assume host is built with 4K page size
> + * and hence ipa change alignment can be guest PAGE_SIZE.
> + */
> + return PAGE_SIZE;
> +}
Why can't this be part of rsi.c? This is an RSI call, and it should be
part of the RSI initialisation.
> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
> index 9e846ce4ef9c..ff735c04e236 100644
> --- a/arch/arm64/kernel/rsi.c
> +++ b/arch/arm64/kernel/rsi.c
> @@ -14,8 +14,10 @@
> #include <asm/mem_encrypt.h>
> #include <asm/pgtable.h>
> #include <asm/rsi.h>
> +#include <asm/rhi.h>
>
> static struct realm_config config;
> +static unsigned long ipa_change_alignment = PAGE_SIZE;
>
> unsigned long prot_ns_shared;
> EXPORT_SYMBOL(prot_ns_shared);
> @@ -139,6 +141,11 @@ static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
> return 0;
> }
>
> +unsigned long realm_get_hyp_pagesize(void)
> +{
> + return ipa_change_alignment;
> +}
Again, this has nothing to do with the hypervisor, but the host. And
ipa_change_alignment is still a wording I can't wrap my small head
around.
> +
> void __init arm64_rsi_init(void)
> {
> if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
> @@ -147,6 +154,12 @@ void __init arm64_rsi_init(void)
> return;
> if (WARN_ON(rsi_get_realm_config(&config)))
> return;
> +
> + ipa_change_alignment = rhi_get_ipa_change_alignment();
> + /* If we don't get a correct alignment response, don't enable realm */
> + if (!ipa_change_alignment)
> + return;
But at the same time, you override a global value with an error, and
then paper over it in mem_decrypt_granule_size()...
> +
> prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));
>
> if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
> diff --git a/arch/arm64/mm/mem_encrypt.c b/arch/arm64/mm/mem_encrypt.c
> index 38c62c9e4e74..f5d64bc29c20 100644
> --- a/arch/arm64/mm/mem_encrypt.c
> +++ b/arch/arm64/mm/mem_encrypt.c
> @@ -59,3 +59,11 @@ int set_memory_decrypted(unsigned long addr, int numpages)
> return crypt_ops->decrypt(addr, numpages);
> }
> EXPORT_SYMBOL_GPL(set_memory_decrypted);
> +
> +size_t mem_decrypt_granule_size(void)
> +{
> + if (is_realm_world())
> + return max(PAGE_SIZE, realm_get_hyp_pagesize());
If you didn't mess with ipa_change_alignment above, you shouldn't need
this max().
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v8 0/6] Add support for Orange Pi 5 Pro
From: Heiko Stuebner @ 2026-04-27 10:37 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Dennis Gilmore
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maxime Ripard, Alexey Charkov,
devicetree, linux-rockchip, linux-arm-kernel, dri-devel,
linux-kernel, Dennis Gilmore
In-Reply-To: <20260425031011.2529364-1-dennis@ausil.us>
Hi Dennis,
Am Samstag, 25. April 2026, 05:10:05 Mitteleuropäische Sommerzeit schrieb Dennis Gilmore:
> This series adds initial support for the Xunlong Orange Pi 5 Pro, based on
> the Rockchip RK3588S SoC. The board features eMMC, SD card, NVMe (PCIe),
> a Motorcomm YT6801 NIC (PCIe), WiFi/BT (BCM43456), dual HDMI output (the
> second via a Lontium LT8711UXD DP-to-HDMI bridge on dp0), and a 40-pin
> expansion header.
more as a general node as the dp-hdmi thing is ongoing, you might want
to just submit the orange-pi5-pro basics first and do a separate series
with the display parts (both driver + dts integration).
That way the core board support can already be applied and get testing.
Heiko
^ permalink raw reply
* Re: [PATCH v5 07/10] drm/rockchip: dw_hdmi_qp: Add missing newlines in dev_err_probe() messages
From: Heiko Stuebner @ 2026-04-27 10:39 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-7-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:19 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Add the missing trailing newlines to a couple of dev_err_probe() calls
> in dw_hdmi_qp_rockchip_bind().
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH v5 08/10] drm/rockchip: dw_hdmi_qp: Use local dev variable consistently in bind()
From: Heiko Stuebner @ 2026-04-27 10:39 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-8-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:20 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Replace indirect struct device accesses via hdmi->dev and pdev->dev with
> the local dev parameter already available in dw_hdmi_qp_rockchip_bind(),
> for consistency and readability.
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH v5 06/10] drm/bridge: dw-hdmi-qp: Rate limit i2c read error messages
From: Heiko Stuebner @ 2026-04-27 10:41 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-6-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:18 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> During EDID reads, repeated i2c errors can flood the kernel log:
>
> [ 25.361716] dwhdmiqp-rockchip fde80000.hdmi: i2c read error
> [ 25.363376] dwhdmiqp-rockchip fde80000.hdmi: i2c read error
> ...
> [ 25.368671] dwhdmiqp-rockchip fde80000.hdmi: i2c read error
> [ 25.369440] dwhdmiqp-rockchip fde80000.hdmi: failed to get edid
>
> Switch to dev_err_ratelimited() in dw_hdmi_qp_i2c_read() to reduce log
> spam while still reporting the condition.
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* [PATCH v6 0/3] ARM: omap1: use real firmware node lookup for GPIOs on Nokia 770
From: Bartosz Golaszewski @ 2026-04-27 10:46 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren, Russell King,
Dmitry Torokhov, Kevin Hilman, Arnd Bergmann
Cc: brgl, driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap, Bartosz Golaszewski
This converts Nokia 770 to using real firmware node lookup for GPIOs by
attaching the software nodes describing GPIO controllers to their target
devices.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Changes in v6:
- Switch to using platform_device_register_full() and pass the software
node via the swnode field of struct platform_device_info
- Drop driver-core prerequisites from the series
- Rebase on top of v7.1-rc1
- Add patch dropping an unused variable
- Link to v5: https://patch.msgid.link/20260402-nokia770-gpio-swnodes-v5-0-d730db3dd299@oss.qualcomm.com
Changes in v5:
- Put ksysfs_init() in a separate new header
- Remove software_node_exit() in a separate patch
- Link to v4: https://patch.msgid.link/20260330-nokia770-gpio-swnodes-v4-0-b68592e977d0@oss.qualcomm.com
Changes in v4:
- Add patches making software nodes available earlier
- Remove stray newline
- Link to v3: https://lore.kernel.org/all/20260212112508.73500-1-bartosz.golaszewski@oss.qualcomm.com/
Changes in v3:
- fix references to the MPU node
Changes in v2:
- fix build with CONFIG_I2C_CBUS_GPIO
- only export the two symbols that are actually required by the nokia
board file
---
Bartosz Golaszewski (3):
ARM: omap1: drop unused variable from omap16xx_gpio_init()
ARM: omap1: use platform_device_register_full() for GPIO devices on OMAP 16xx
ARM: omap1: enable real software node lookup of GPIOs on Nokia 770
arch/arm/mach-omap1/board-nokia770.c | 30 +++-----------
arch/arm/mach-omap1/common.h | 3 ++
arch/arm/mach-omap1/gpio16xx.c | 77 ++++++++++++++++++------------------
3 files changed, 47 insertions(+), 63 deletions(-)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260330-nokia770-gpio-swnodes-5da8ba35946e
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* [PATCH v6 1/3] ARM: omap1: drop unused variable from omap16xx_gpio_init()
From: Bartosz Golaszewski @ 2026-04-27 10:46 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren, Russell King,
Dmitry Torokhov, Kevin Hilman, Arnd Bergmann
Cc: brgl, driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap, Bartosz Golaszewski
In-Reply-To: <20260427-nokia770-gpio-swnodes-v6-0-b693296c1985@oss.qualcomm.com>
The pdata variable is set but not used. Remove it.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
arch/arm/mach-omap1/gpio16xx.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 55acec22fef4e73f20935473602ef6cb2f4f379c..e8dbe173bd33fae72c7c884f930a530f78096839 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -212,7 +212,6 @@ static int __init omap16xx_gpio_init(void)
void __iomem *base;
struct resource *res;
struct platform_device *pdev;
- struct omap_gpio_platform_data *pdata;
if (!cpu_is_omap16xx())
return -EINVAL;
@@ -226,7 +225,6 @@ static int __init omap16xx_gpio_init(void)
for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
pdev = omap16xx_gpio_dev[i];
- pdata = pdev->dev.platform_data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {
--
2.47.3
^ permalink raw reply related
* [PATCH v6 2/3] ARM: omap1: use platform_device_register_full() for GPIO devices on OMAP 16xx
From: Bartosz Golaszewski @ 2026-04-27 10:46 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren, Russell King,
Dmitry Torokhov, Kevin Hilman, Arnd Bergmann
Cc: brgl, driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap, Bartosz Golaszewski
In-Reply-To: <20260427-nokia770-gpio-swnodes-v6-0-b693296c1985@oss.qualcomm.com>
Ahead of changes attaching GPIO controller's software nodes referenced
from the Nokia 770 board files to their target devices, switch the
method for registering the platform devices to the
platform_device_register_full() variant. This is done to leverage the
new swnode field of struct platform_device_info which automate the
software node's registration and assignment.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
arch/arm/mach-omap1/gpio16xx.c | 68 ++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 36 deletions(-)
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index e8dbe173bd33fae72c7c884f930a530f78096839..2904ce38c001505d48d0996f7053369bbf683209 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -55,14 +55,13 @@ static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
.regs = &omap16xx_mpuio_regs,
};
-static struct platform_device omap16xx_mpu_gpio = {
+static const struct platform_device_info omap16xx_mpu_gpio = {
.name = "omap_gpio",
.id = 0,
- .dev = {
- .platform_data = &omap16xx_mpu_gpio_config,
- },
- .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
- .resource = omap16xx_mpu_gpio_resources,
+ .data = &omap16xx_mpu_gpio_config,
+ .size_data = sizeof(omap16xx_mpu_gpio_config),
+ .num_res = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
+ .res = omap16xx_mpu_gpio_resources,
};
/* gpio1 */
@@ -99,14 +98,13 @@ static struct omap_gpio_platform_data omap16xx_gpio1_config = {
.regs = &omap16xx_gpio_regs,
};
-static struct platform_device omap16xx_gpio1 = {
+static const struct platform_device_info omap16xx_gpio1 = {
.name = "omap_gpio",
.id = 1,
- .dev = {
- .platform_data = &omap16xx_gpio1_config,
- },
- .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
- .resource = omap16xx_gpio1_resources,
+ .data = &omap16xx_gpio1_config,
+ .size_data = sizeof(omap16xx_gpio1_config),
+ .num_res = ARRAY_SIZE(omap16xx_gpio1_resources),
+ .res = omap16xx_gpio1_resources,
};
/* gpio2 */
@@ -127,14 +125,13 @@ static struct omap_gpio_platform_data omap16xx_gpio2_config = {
.regs = &omap16xx_gpio_regs,
};
-static struct platform_device omap16xx_gpio2 = {
+static const struct platform_device_info omap16xx_gpio2 = {
.name = "omap_gpio",
.id = 2,
- .dev = {
- .platform_data = &omap16xx_gpio2_config,
- },
- .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
- .resource = omap16xx_gpio2_resources,
+ .data = &omap16xx_gpio2_config,
+ .size_data = sizeof(omap16xx_gpio2_config),
+ .num_res = ARRAY_SIZE(omap16xx_gpio2_resources),
+ .res = omap16xx_gpio2_resources,
};
/* gpio3 */
@@ -155,14 +152,13 @@ static struct omap_gpio_platform_data omap16xx_gpio3_config = {
.regs = &omap16xx_gpio_regs,
};
-static struct platform_device omap16xx_gpio3 = {
+static const struct platform_device_info omap16xx_gpio3 = {
.name = "omap_gpio",
.id = 3,
- .dev = {
- .platform_data = &omap16xx_gpio3_config,
- },
- .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
- .resource = omap16xx_gpio3_resources,
+ .data = &omap16xx_gpio3_config,
+ .size_data = sizeof(omap16xx_gpio3_config),
+ .num_res = ARRAY_SIZE(omap16xx_gpio3_resources),
+ .res = omap16xx_gpio3_resources,
};
/* gpio4 */
@@ -183,17 +179,16 @@ static struct omap_gpio_platform_data omap16xx_gpio4_config = {
.regs = &omap16xx_gpio_regs,
};
-static struct platform_device omap16xx_gpio4 = {
+static const struct platform_device_info omap16xx_gpio4 = {
.name = "omap_gpio",
.id = 4,
- .dev = {
- .platform_data = &omap16xx_gpio4_config,
- },
- .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
- .resource = omap16xx_gpio4_resources,
+ .data = &omap16xx_gpio4_config,
+ .size_data = sizeof(omap16xx_gpio4_config),
+ .num_res = ARRAY_SIZE(omap16xx_gpio4_resources),
+ .res = omap16xx_gpio4_resources,
};
-static struct platform_device *omap16xx_gpio_dev[] __initdata = {
+static const struct platform_device_info *omap16xx_gpio_dev[] __initconst = {
&omap16xx_mpu_gpio,
&omap16xx_gpio1,
&omap16xx_gpio2,
@@ -210,8 +205,9 @@ static int __init omap16xx_gpio_init(void)
{
int i;
void __iomem *base;
- struct resource *res;
+ const struct resource *res;
struct platform_device *pdev;
+ const struct platform_device_info *pdevinfo;
if (!cpu_is_omap16xx())
return -EINVAL;
@@ -224,9 +220,9 @@ static int __init omap16xx_gpio_init(void)
ULPD_CAM_CLK_CTRL);
for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
- pdev = omap16xx_gpio_dev[i];
+ pdevinfo = omap16xx_gpio_dev[i];
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = &pdevinfo->res[0];
if (unlikely(!res)) {
dev_err(&pdev->dev, "Invalid mem resource.\n");
return -ENODEV;
@@ -234,14 +230,14 @@ static int __init omap16xx_gpio_init(void)
base = ioremap(res->start, resource_size(res));
if (unlikely(!base)) {
- dev_err(&pdev->dev, "ioremap failed.\n");
+ pr_err("ioremap failed.\n");
return -ENOMEM;
}
__raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG);
iounmap(base);
- platform_device_register(omap16xx_gpio_dev[i]);
+ platform_device_register_full(omap16xx_gpio_dev[i]);
}
return 0;
--
2.47.3
^ permalink raw reply related
* [PATCH v6 3/3] ARM: omap1: enable real software node lookup of GPIOs on Nokia 770
From: Bartosz Golaszewski @ 2026-04-27 10:46 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren, Russell King,
Dmitry Torokhov, Kevin Hilman, Arnd Bergmann
Cc: brgl, driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap, Bartosz Golaszewski
In-Reply-To: <20260427-nokia770-gpio-swnodes-v6-0-b693296c1985@oss.qualcomm.com>
Currently the board file for Nokia 770 creates dummy software nodes not
attached in any way to the actual GPIO controller devices and uses the
fact that GPIOLIB matching swnode's name to the GPIO chip's label during
software node lookup. This behavior is wrong and we want to remove it.
To that end, we need to first convert all existing users to creating
actual fwnode links.
Create real software nodes for GPIO controllers on OMAP16xx and
reference them from the software nodes in the nokia board file.
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
arch/arm/mach-omap1/board-nokia770.c | 30 +++++-------------------------
arch/arm/mach-omap1/common.h | 3 +++
arch/arm/mach-omap1/gpio16xx.c | 7 +++++++
3 files changed, 15 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index a5bf5554800fe17b430e84ae421ffa8da2bb11a0..46f817f6316b70ff37bb9dfde86c675fd692999b 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -36,25 +36,6 @@
#include "clock.h"
#include "mmc.h"
-static const struct software_node nokia770_mpuio_gpiochip_node = {
- .name = "mpuio",
-};
-
-static const struct software_node nokia770_gpiochip1_node = {
- .name = "gpio-0-15",
-};
-
-static const struct software_node nokia770_gpiochip2_node = {
- .name = "gpio-16-31",
-};
-
-static const struct software_node *nokia770_gpiochip_nodes[] = {
- &nokia770_mpuio_gpiochip_node,
- &nokia770_gpiochip1_node,
- &nokia770_gpiochip2_node,
- NULL
-};
-
#define ADS7846_PENDOWN_GPIO 15
static const unsigned int nokia770_keymap[] = {
@@ -112,7 +93,7 @@ static const struct omap_lcd_config nokia770_lcd_config __initconst = {
};
static const struct property_entry nokia770_mipid_props[] = {
- PROPERTY_ENTRY_GPIO("reset-gpios", &nokia770_gpiochip1_node,
+ PROPERTY_ENTRY_GPIO("reset-gpios", &omap16xx_gpio1_swnode,
13, GPIO_ACTIVE_LOW),
{ }
};
@@ -138,7 +119,7 @@ static const struct property_entry nokia770_ads7846_props[] = {
PROPERTY_ENTRY_U16("ti,x-plate-ohms", 180),
PROPERTY_ENTRY_U16("ti,debounce-tol", 3),
PROPERTY_ENTRY_U16("ti,debounce-rep", 1),
- PROPERTY_ENTRY_GPIO("pendown-gpios", &nokia770_gpiochip1_node,
+ PROPERTY_ENTRY_GPIO("pendown-gpios", &omap16xx_gpio1_swnode,
ADS7846_PENDOWN_GPIO, GPIO_ACTIVE_LOW),
{ }
};
@@ -225,9 +206,9 @@ static inline void nokia770_mmc_init(void)
#if IS_ENABLED(CONFIG_I2C_CBUS_GPIO)
static const struct software_node_ref_args nokia770_cbus_gpio_refs[] = {
- SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 9, 0),
- SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 10, 0),
- SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 11, 0),
+ SOFTWARE_NODE_REFERENCE(&omap16xx_mpu_gpio_swnode, 9, 0),
+ SOFTWARE_NODE_REFERENCE(&omap16xx_mpu_gpio_swnode, 10, 0),
+ SOFTWARE_NODE_REFERENCE(&omap16xx_mpu_gpio_swnode, 11, 0),
};
static const struct property_entry nokia770_cbus_props[] = {
@@ -318,7 +299,6 @@ static void __init omap_nokia770_init(void)
/* Unmask SleepX signal */
omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
- software_node_register_node_group(nokia770_gpiochip_nodes);
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
gpiod_add_lookup_table(&nokia770_irq_gpio_table);
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index 7a7c3d9eb84a06c18fbc70e7c94a161b487cd002..c0f6e231fdb4422c5d2c1aa3e33dd6dd99d2710e 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -35,6 +35,9 @@
#include "soc.h"
#include "i2c.h"
+extern const struct software_node omap16xx_mpu_gpio_swnode;
+extern const struct software_node omap16xx_gpio1_swnode;
+
#ifdef CONFIG_OMAP_SERIAL_WAKE
int omap_serial_wakeup_init(void);
#else
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 2904ce38c001505d48d0996f7053369bbf683209..abc71bb562df18fb1f683c6f216c698a38cf09a9 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -9,6 +9,7 @@
*/
#include <linux/platform_data/gpio-omap.h>
+#include <linux/property.h>
#include <linux/soc/ti/omap1-io.h>
#include "hardware.h"
@@ -55,6 +56,8 @@ static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
.regs = &omap16xx_mpuio_regs,
};
+const struct software_node omap16xx_mpu_gpio_swnode = { };
+
static const struct platform_device_info omap16xx_mpu_gpio = {
.name = "omap_gpio",
.id = 0,
@@ -62,6 +65,7 @@ static const struct platform_device_info omap16xx_mpu_gpio = {
.size_data = sizeof(omap16xx_mpu_gpio_config),
.num_res = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
.res = omap16xx_mpu_gpio_resources,
+ .swnode = &omap16xx_mpu_gpio_swnode,
};
/* gpio1 */
@@ -98,6 +102,8 @@ static struct omap_gpio_platform_data omap16xx_gpio1_config = {
.regs = &omap16xx_gpio_regs,
};
+const struct software_node omap16xx_gpio1_swnode = { };
+
static const struct platform_device_info omap16xx_gpio1 = {
.name = "omap_gpio",
.id = 1,
@@ -105,6 +111,7 @@ static const struct platform_device_info omap16xx_gpio1 = {
.size_data = sizeof(omap16xx_gpio1_config),
.num_res = ARRAY_SIZE(omap16xx_gpio1_resources),
.res = omap16xx_gpio1_resources,
+ .swnode = &omap16xx_gpio1_swnode,
};
/* gpio2 */
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v5 05/10] drm/bridge: dw-hdmi-qp: Add HDMI 2.0 SCDC scrambling and high TMDS clock ratio support
From: Heiko Stuebner @ 2026-04-27 10:49 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
Diederik de Haas, Maud Spierings
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-5-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:17 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Enable HDMI 2.0 display modes (e.g. 4K@60Hz) by adding SCDC management
> for the high TMDS clock ratio and scrambling, required when the TMDS
> character rate exceeds the 340 MHz HDMI 1.4b limit.
>
> A periodic work item monitors the sink's scrambling status to recover
> from sink-side resets. On hotplug detect, if SCDC scrambling state is
> out of sync with the driver, trigger a CRTC reset to re-establish the
> link.
>
> Reject modes requiring TMDS rates above 600 MHz, as those fall in the
> HDMI 2.1 FRL domain which is not supported. In no_hpd configurations,
> further restrict to 340 MHz since SCDC requires a connected sink.
>
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 188 ++++++++++++++++++++++++---
> 1 file changed, 172 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index d649a1cf07f5..c482a8e7da25 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@ -2,6 +2,7 @@
> /*
> * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
> * Copyright (c) 2024 Collabora Ltd.
> + * Copyright (c) 2025 Amazon.com, Inc. or its affiliates.
I have no real clue about the inner workings of hdmi, but that line
does make me curious, because no part of the patch authorship does
mention Amazon ;-) .
Also I think "or it's affiliates" might be way too broad, because this
can be essentially everyone. So noone in the future will know who to
ask on copyright questions.
Similarly when _somebody_ comes forward with "I hold a copyright on this"
no-one could verify this claim as well.
I somehow expect _one_ entity being specified, not possibly hundreds.
Heiko
^ permalink raw reply
* Re: [PATCH v4 2/4] coresight: pass THIS_MODULE implicitly through a macro
From: Leo Yan @ 2026-04-27 10:49 UTC (permalink / raw)
To: Shashank Balaji
Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
Sami Tolvanen, Aaron Tomlin, Mike Leach, Rahul Bukte,
linux-kernel, coresight, linux-arm-kernel, driver-core,
rust-for-linux, linux-doc, Daniel Palmer, Tim Bird, linux-modules
In-Reply-To: <20260427-acpi_mod_name-v4-2-22b42240c9bf@sony.com>
Hi Shashank,
On Mon, Apr 27, 2026 at 11:41:22AM +0900, Shashank Balaji wrote:
[...]
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -1694,7 +1694,7 @@ static void __exit coresight_exit(void)
> module_init(coresight_init);
> module_exit(coresight_exit);
>
> -int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
> +int __coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
> struct platform_driver *pdev_drv, struct module *owner)
> {
> int ret;
> @@ -1713,7 +1713,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
> amba_driver_unregister(amba_drv);
> return ret;
> }
> -EXPORT_SYMBOL_GPL(coresight_init_driver);
> +EXPORT_SYMBOL_GPL(__coresight_init_driver);
For consistency, we usually use prefix "__" for internal functions.
Could you rename this function as:
int coresight_init_driver_with_owner(..., struct module *owner);
> +#define coresight_init_driver(drv, amba_drv, pdev_drv) \
> + __coresight_init_driver(drv, amba_drv, pdev_drv, THIS_MODULE)
> +int __coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
> struct platform_driver *pdev_drv, struct module *owner);
Please first function declaration, then followed by the macro to
define coresight_init_driver().
With above changes:
Reviewed-by: Leo Yan <leo.yan@arm.com>
^ permalink raw reply
* Re: [PATCH v2 0/4] ARM: pxa: attach software nodes to the GPIO controllers
From: Arnd Bergmann @ 2026-04-27 10:49 UTC (permalink / raw)
To: Bartosz Golaszewski, Daniel Mack, Haojian Zhuang, Robert Jarzmik,
Russell King, Dmitry Torokhov, Linus Walleij
Cc: Bartosz Golaszewski, linux-arm-kernel, open list:GPIO SUBSYSTEM,
linux-kernel
In-Reply-To: <20260427-pxa-gpio-swnodes-v2-0-86fc24b9e714@oss.qualcomm.com>
On Mon, Apr 27, 2026, at 12:14, Bartosz Golaszewski wrote:
> Convert GPIO controllers and their consumers on the PXA platform to using
> "attached" software nodes. Since everything happens in a bord-file, it's
> quite straightforward. We technically now have a way of passing an
> unregistered software node to platform_device_register_full() but that
> requires using struct platform_device_info and since the existing
> platform devices are either referenced from other places or defined in a
> different compilation unit, I wanted to reduce the impact of the changes
> I can't test and went with the older method.
>
> Signed-off-by: Bartosz Golaszewski
> <bartosz.golaszewski@oss.qualcomm.com>
> ---
Hi Bartosz,
These patches are individually all fine, but I was hoping to
finally get around to removing the pxa board files completely,
sorry it's been taking me so long to rebase my series for
that.
The only remaining board files I expect to have soon are for
the omap1 and s3c machines, so if you are going through the
board files to convert them to over, I would suggest focusing
on those.
Arnd
^ permalink raw reply
* Re: [PATCH v6 2/3] ARM: omap1: use platform_device_register_full() for GPIO devices on OMAP 16xx
From: Arnd Bergmann @ 2026-04-27 10:50 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren,
Russell King, Dmitry Torokhov, Kevin Hilman
Cc: Bartosz Golaszewski, driver-core, linux-kernel, linux-acpi,
linux-arm-kernel, Linux-OMAP
In-Reply-To: <20260427-nokia770-gpio-swnodes-v6-2-b693296c1985@oss.qualcomm.com>
On Mon, Apr 27, 2026, at 12:46, Bartosz Golaszewski wrote:
> Ahead of changes attaching GPIO controller's software nodes referenced
> from the Nokia 770 board files to their target devices, switch the
> method for registering the platform devices to the
> platform_device_register_full() variant. This is done to leverage the
> new swnode field of struct platform_device_info which automate the
> software node's registration and assignment.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH v6 1/3] ARM: omap1: drop unused variable from omap16xx_gpio_init()
From: Arnd Bergmann @ 2026-04-27 10:52 UTC (permalink / raw)
To: Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J . Wysocki,
Danilo Krummrich, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren,
Russell King, Dmitry Torokhov, Kevin Hilman
Cc: Bartosz Golaszewski, driver-core, linux-kernel, linux-acpi,
linux-arm-kernel, Linux-OMAP
In-Reply-To: <20260427-nokia770-gpio-swnodes-v6-1-b693296c1985@oss.qualcomm.com>
On Mon, Apr 27, 2026, at 12:46, Bartosz Golaszewski wrote:
> The pdata variable is set but not used. Remove it.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---
> arch/arm/mach-omap1/gpio16xx.c | 2 --
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH v2 3/4] ARM: pxa: pxa25x: attach software node to its target GPIO controller
From: Russell King (Oracle) @ 2026-04-27 10:58 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Dmitry Torokhov,
Arnd Bergmann, Linus Walleij, brgl, linux-arm-kernel, linux-gpio,
linux-kernel
In-Reply-To: <20260427-pxa-gpio-swnodes-v2-3-86fc24b9e714@oss.qualcomm.com>
On Mon, Apr 27, 2026 at 12:14:34PM +0200, Bartosz Golaszewski wrote:
> Software node describing the GPIO controller for the pxa25x platforms is
> currently "dangling" - it's not actually attached to the relevant
> controller and doesn't allow real fwnode lookup. Attach it once it's
> registered as a firmware node before adding the platform device.
>
> Reviewed-by: Linus Walleij <linusw@kernel.org>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---
> arch/arm/mach-pxa/pxa25x.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
> index 70509a5998142ec6b9c484e5f094751eda6db6cd..6875774f2cae1db4798d18c813f445bdc31b15de 100644
> --- a/arch/arm/mach-pxa/pxa25x.c
> +++ b/arch/arm/mach-pxa/pxa25x.c
> @@ -179,7 +179,6 @@ void __init pxa25x_map_io(void)
> }
>
> static struct platform_device *pxa25x_devices[] __initdata = {
> - &pxa25x_device_gpio,
> &pxa25x_device_udc,
> &pxa_device_pmu,
> &pxa_device_i2s,
> @@ -240,6 +239,10 @@ static int __init pxa25x_init(void)
>
> if (!of_have_populated_dt()) {
> software_node_register(&pxa2xx_gpiochip_node);
> + pxa25x_device_gpio.dev.fwnode = software_node_fwnode(
> + &pxa2xx_gpiochip_node);
> + platform_device_register(&pxa25x_device_gpio);
> +
> pxa2xx_set_dmac_info(&pxa25x_dma_pdata);
> ret = platform_add_devices(pxa25x_devices,
> ARRAY_SIZE(pxa25x_devices));
Why do you need to explicitly register using platform_device_register()
rather than leaving the device in the pxa25x_devices list and letting
platform_add_devices() do that for you? platform_add_devices() is just
a wrapper around platform_device_register() which calls that for all
devices in the array.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
* Re: [PATCH v5 02/10] drm/bridge: Add detect_ctx hook and drm_bridge_detect_ctx() helper
From: Heiko Stuebner @ 2026-04-27 11:00 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
Diederik de Haas, Maud Spierings
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-2-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:14 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Add an atomic-aware .detect_ctx() callback to drm_bridge_funcs and a
> drm_bridge_detect_ctx() helper that accepts an optional
> drm_modeset_acquire_ctx.
>
> This enables bridge drivers to perform operations requiring modeset
> locking during connector detection, such as SCDC management for HDMI
> 2.0. When both ->detect_ctx and ->detect are defined, the former takes
> precedence. When ctx is NULL, locking is managed internally with EDEADLK
> retry.
>
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
while this looks sane to me, my drm insights are spotty, so I can
only provide the lighter
Acked-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH v2 0/4] ARM: pxa: attach software nodes to the GPIO controllers
From: Bartosz Golaszewski @ 2026-04-27 11:01 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Bartosz Golaszewski, Daniel Mack, Haojian Zhuang, Robert Jarzmik,
Russell King, Dmitry Torokhov, Linus Walleij, linux-arm-kernel,
open list:GPIO SUBSYSTEM, linux-kernel
In-Reply-To: <da7ea88f-845f-49e3-852b-3ca352c1790d@app.fastmail.com>
On Mon, Apr 27, 2026 at 12:50 PM Arnd Bergmann <arnd@kernel.org> wrote:
>
> On Mon, Apr 27, 2026, at 12:14, Bartosz Golaszewski wrote:
> > Convert GPIO controllers and their consumers on the PXA platform to using
> > "attached" software nodes. Since everything happens in a bord-file, it's
> > quite straightforward. We technically now have a way of passing an
> > unregistered software node to platform_device_register_full() but that
> > requires using struct platform_device_info and since the existing
> > platform devices are either referenced from other places or defined in a
> > different compilation unit, I wanted to reduce the impact of the changes
> > I can't test and went with the older method.
> >
> > Signed-off-by: Bartosz Golaszewski
> > <bartosz.golaszewski@oss.qualcomm.com>
> > ---
>
> Hi Bartosz,
>
> These patches are individually all fine, but I was hoping to
> finally get around to removing the pxa board files completely,
> sorry it's been taking me so long to rebase my series for
> that.
>
If that'll be queued for v7.2, then I'm fine with dropping this
series. Otherwise, I'd like to see it applied as I want to get all the
changes required to remove the software node name matching from
GPIOLIB into v7.2 and then finally remove it in v7.3.
> The only remaining board files I expect to have soon are for
> the omap1 and s3c machines, so if you are going through the
> board files to convert them to over, I would suggest focusing
> on those.
>
S3C does not seem to need any changes, I already sent out a series for omap1.
Bart
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Thomas Gleixner @ 2026-04-27 11:03 UTC (permalink / raw)
To: Florian Weimer
Cc: Peter Zijlstra, Mathias Stearn, Dmitry Vyukov, Jinjie Ruan,
linux-man, Mark Rutland, Mathieu Desnoyers, Catalin Marinas,
Will Deacon, Boqun Feng, Paul E. McKenney, Chris Kennelly,
regressions, linux-kernel, linux-arm-kernel, Ingo Molnar,
Blake Oler, Rich Felker, Matthew Wilcox, Greg Kroah-Hartman,
Linus Torvalds, criu
In-Reply-To: <lhujyts4zr8.fsf@oldenburg.str.redhat.com>
On Mon, Apr 27 2026 at 09:40, Florian Weimer wrote:
> * Thomas Gleixner:
>> The real question is how to differentiate between the legacy and the
>> optimized mode. I have two working variants to achieve that:
>>
>> 1) The fully safe option requires a new flag for RSEQ
>> registration. It obviously requires a glibc update. (Suggested by
>> PeterZ)
>
> Without glibc changes, RSEQ would keep working, but with the old,
> problematic performance, right?
Correct.
> If we don't have a notification in the auxiliary vector, we'd have to do
> two system calls at process start, which isn't ideal, but is probably
> not a significant issue, either.
>
> I haven't verified this, but it looks like introducing the flag breaks
> CRIU? In dump_thread_rseq, we have this:
>
> if (rseqc.flags != 0) {
> pr_err("something wrong with ptrace(PTRACE_GET_RSEQ_CONFIGURATION, %d) flags = 0x%x\n", tid,
> rseqc.flags);
> return -1;
> }
Yeah. That'd need to be fixed or work around.
> I suppose a workaround could make this behavior flag a prctl flag. CRIU
> wouldn't dump and restore that until taught about it. If the new
> behavior is switched on explicitly by the flag, it would be
> backwards-compatible, except that restoring with unpatched CRIU would
> lead to a performance loss.
It's worse. The flag will also enable extended RSEQ features beyond
mmcid and requires that the registered rseq size is >= offsetof(struct
rseq, end)'
>> 2) Determine the requirements of the registering task via the size of
>> the registered RSEQ area.
>>
>> The original implementation, which TCMalloc depends on, registers
>> a 32 byte region (ORIG_RSEG_SIZE). This region has 32 byte
>> alignment requirement.
>>
>> The extension safe newer variant exposes the kernel RSEQ feature
>> size via getauxval(AT_RSEQ_FEATURE_SIZE) and the alignment
>> requirement via getauxval(AT_RSEQ_ALIGN). The alignment
>> requirement is that the registered rseq region is aligned to the
>> next power of two of the feature size. The kernel currently has a
>> feature size of 33 bytes, which means the alignment requirement is
>> 64 bytes.
>
> There are still glibc builds in use that do not use AT_RSEQ_ALIGN, and
> instead unconditionally reserve a size of 32. In some builds, the RSEQ
> area is not aligned to a multiple of 64, which makes glibc
> indistinguishable from tcmalloc.
That's how it is. So with a size of 32 this will fallback to legacy mode
and not unlock the extended features independent of the alignment. The
alignment requirements are:
Size 32: 32 bytes
Size >32: 64 bytes
> You could look at the location of the thread pointer relative to the
> RSEQ area at registration to tell them apart, but that is perhaps too
> nasty.
*Blink*
> Switching to the new extensible RSEQ allocation code in older glibc
> builds is not entirely trivial, and I would prefer not doing that.
> Registering with a new flag is comparatively simple, and we could
> backport it, except that it might not be compatible with CRIU.
Neither with CRIU nor with the requirement to support additional
features which require the registered rseq memory size to be at least as
large as the kernel requires. That's why we have AT_RSEQ_FEATURE_SIZE.
Otherwise we'd end up with runtime conditionals for every single
feature, which just adds more gunk into the hotpaths and ends up in a
ever growing compatibility nightmare.
So if a process runs on a newer kernel with let's say 40 bytes rseq
size, then it can't be safely migrated with CRIU to a older kernel with
32 bytes rseq size as you don't know whether the process uses some of
the extended features in the newer kernel already. But that's not any
different from extended syscall features etc.
So with the size based detection we end up with the following:
Size 32: legacy mode no matter whether that's TCMalloc or
glibc. Does not support extended features
Size >= kernel size: optimized mode with support for extended features
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH] coresight: cti: Fix DT filter signals silently ignored
From: Leo Yan @ 2026-04-27 11:03 UTC (permalink / raw)
To: Yingchao Deng
Cc: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Mathieu Poirier, Greg Kroah-Hartman, coresight, linux-arm-kernel,
linux-kernel, quic_yingdeng, Jinlong Mao, Tingwei Zhang, Jie Gan
In-Reply-To: <20260426-nr_sigs-v1-1-3b9df99dab97@oss.qualcomm.com>
On Sun, Apr 26, 2026 at 05:59:34PM +0800, Yingchao Deng wrote:
> In cti_plat_process_filter_sigs(), after allocating a temporary
> cti_trig_grp struct via kzalloc_obj(), the code never assigns tg->nr_sigs
> = nr_filter_sigs. Since kzalloc zero-initialises the struct, tg->nr_sigs
> remains 0. cti_plat_read_trig_group() guards with:
> if (!tgrp->nr_sigs)
> return 0;
>
> so it returns immediately without reading any signal indices from DT.
>
> Fix by assigning tg->nr_sigs before calling cti_plat_read_trig_group().
>
> Fixes: a5614770ab97 ("coresight: cti: Add device tree support for custom CTI")
> Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
> ---
> drivers/hwtracing/coresight/coresight-cti-platform.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c
> index 4eff96f48594..d6d5388705c3 100644
> --- a/drivers/hwtracing/coresight/coresight-cti-platform.c
> +++ b/drivers/hwtracing/coresight/coresight-cti-platform.c
> @@ -329,6 +329,7 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata,
> if (!tg)
> return -ENOMEM;
>
> + tg->nr_sigs = nr_filter_sigs;
> err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS);
I checked the naming, seems tg->nr_sigs is the right field to store
the number. LGTM:
Reviewed-by: Leo Yan <leo.yan@arm.com>
^ permalink raw reply
* [PATCH 0/7] Add MediaTek VCP remoteproc driver support
From: Xiangzhi Tang @ 2026-04-27 11:04 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Xiangzhi Tang
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, Hailong Fan,
Huayu Zong, Jarried Lin, Justin Yeh, Vince-WL Liu, Xiangzhi Tang
This patch series adds support for the MediaTek Video Companion
Processor (VCP), a RISC-V based coprocessor found on MediaTek SoCs
starting from mt8196. The VCP handles video processing and multimedia
tasks, offloading work from the main CPU cores.
Architecture Overview
=====================
The VCP subsystem consists of several components:
1. Hardware Architecture
- RISC-V coprocessor with 1-2 harts per core
- Multi-core capable (mt8196 has 2 VCP cores)
- Shared SRAM (up to 384KB) partitioned among cores
- Dedicated power domain for power management
- Integrated with SoC IOMMU for memory protection
2. Communication Infrastructure
- 5 hardware mailbox channels for IPI (Inter-Processor Interrupt)
- Shared memory regions for bulk data transfer
- IPI routing tables mapping message types to mailboxes
- Support for both blocking and non-blocking IPI operations
3. Boot and Runtime Management
- Firmware loaded via remoteproc framework from filesystem
- Boot sequence coordinated with ARM Trusted Firmware (ATF) via SMC
- Runtime power management with suspend/resume support
- Feature registration mechanism for cross-subsystem coordination
Patch Series Structure
======================
[PATCH 1/7] dt-bindings: Device tree binding for mt8196 VCP
[PATCH 2/7] remoteproc: Core VCP remoteproc driver with ATF integration
[PATCH 3/7] firmware: IPC protocol layer for VCP communication
[PATCH 4/7] remoteproc: IPI mailbox initialization and routing
[PATCH 5/7] remoteproc: IPI synchronization mechanism
[PATCH 6/7] remoteproc: Suspend/resume power management
[PATCH 7/7] MAINTAINERS: Add maintainer entry
Differences from MediaTek SCP
==============================
MediaTek SoCs have two types of companion processors:
- SCP (System Companion Processor): Cortex-M based, for system tasks
- VCP (Video Companion Processor): RISC-V based, for multimedia
While both use the remoteproc framework, VCP has distinct characteristics:
- Different ISA (RISC-V vs ARM Cortex-M)
- Different firmware and memory layout
- Different IPC protocol (5 mailboxes vs 1)
- ATF-coordinated boot sequence
- Multi-core capable architecture
Testing
=======
This patch series has been tested on mt8196 development boards with:
- Firmware loading and boot sequence verification
- IPI communication with video encoder/decoder subsystems
- Suspend/resume cycles with multimedia workloads active
- Multi-core VCP configuration
- IOMMU integration with multimedia memory management
Dependencies
============
- Mediatek Power management driver
- MediaTek VCP mailbox driver (MTK_VCP_MBOX)
- ARM SMCCC support for ATF communication
- IOMMU support for memory protection
Checkpatch Status
=================
All patches pass checkpatch.pl with no errors. Warnings about MAINTAINERS
are addressed in the final patch of the series.
Future Work
===========
- Support for additional SoC variants (mt8197, mt8198)
- Enhanced debugging infrastructure (trace, core dump)
- Performance optimizations for IPI latency
- Documentation under Documentation/remoteproc/
Xiangzhi Tang (7):
dt-bindings: remoteproc: Add MediaTek mt8196 VCP binding
remoteproc: mediatek: Add VCP remoteproc driver
firmware: mediatek: Add VCP IPC protocol driver
remoteproc: mediatek: Add VCP IPI mailbox initialization
remoteproc: mediatek: Add VCP ipi communication sync mechanism
remoteproc: mediatek: vcp: Add vcp suspend and resume feature
MAINTAINERS: Add entry for MediaTek VCP remoteproc driver
.../bindings/remoteproc/mediatek,mt8196-vcp.yaml | 166 ++++
MAINTAINERS | 14 +
drivers/firmware/Kconfig | 9 +
drivers/firmware/Makefile | 1 +
drivers/firmware/mtk-vcp-ipc.c | 481 +++++++++++
drivers/remoteproc/Kconfig | 12 +
drivers/remoteproc/Makefile | 3 +
drivers/remoteproc/mtk_vcp_common.c | 881 +++++++++++++++++++++
drivers/remoteproc/mtk_vcp_common.h | 281 +++++++
drivers/remoteproc/mtk_vcp_rproc.c | 581 ++++++++++++++
drivers/remoteproc/mtk_vcp_rproc.h | 95 +++
include/linux/firmware/mediatek/mtk-vcp-ipc.h | 151 ++++
include/linux/remoteproc/mtk_vcp_public.h | 146 ++++
include/linux/soc/mediatek/mtk_sip_svc.h | 2 +
14 files changed, 2823 insertions(+)
create mode 100644 Documentation/devicetree/bindings/remoteproc/mediatek,mt8196-vcp.yaml
create mode 100644 drivers/firmware/mtk-vcp-ipc.c
create mode 100644 drivers/remoteproc/mtk_vcp_common.c
create mode 100644 drivers/remoteproc/mtk_vcp_common.h
create mode 100644 drivers/remoteproc/mtk_vcp_rproc.c
create mode 100644 drivers/remoteproc/mtk_vcp_rproc.h
create mode 100644 include/linux/firmware/mediatek/mtk-vcp-ipc.h
create mode 100644 include/linux/remoteproc/mtk_vcp_public.h
--
2.46.0
^ permalink raw reply
* [PATCH v4 3/7] firmware: mediatek: Add VCP IPC protocol driver
From: Xiangzhi Tang @ 2026-04-27 11:04 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Xiangzhi Tang
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, Hailong Fan,
Huayu Zong, Jarried Lin, Justin Yeh, Vince-WL Liu, Xiangzhi Tang
In-Reply-To: <20260427111446.22955-1-xiangzhi.tang@mediatek.com>
Add the Inter-Processor Communication (IPC) protocol driver for
MediaTek Video Companion Processor (VCP), a RISC-V coprocessor
found on some MediaTek SoCs.
The VCP IPC protocol provides the communication layer between the
host CPU (AP) and VCP firmware using shared memory for message
passing and hardware mailboxes for signaling. The driver implements:
- Send/receive interfaces for IPI messages via mailbox channels
- Support for both blocking (send_compl) and non-blocking (send) modes
- Configurable IPI routing tables that map IPI IDs to mailbox channels
- Per-IPI callback registration for handling incoming messages
- Two receive modes: direct receive (recv_opt=0) and response mode
(recv_opt=1) for request-reply patterns
The IPC driver acts as a middle layer between the remoteproc framework
and the MediaTek mailbox hardware, abstracting the low-level mailbox
operations into higher-level IPI communication primitives.
This is required for the VCP remoteproc driver to communicate with
VCP firmware for multimedia processing tasks.
Signed-off-by: Xiangzhi Tang <xiangzhi.tang@mediatek.com>
---
drivers/firmware/Kconfig | 9 +
drivers/firmware/Makefile | 1 +
drivers/firmware/mtk-vcp-ipc.c | 481 ++++++++++++++++++
include/linux/firmware/mediatek/mtk-vcp-ipc.h | 151 ++++++
4 files changed, 642 insertions(+)
create mode 100644 drivers/firmware/mtk-vcp-ipc.c
create mode 100644 include/linux/firmware/mediatek/mtk-vcp-ipc.h
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bbd2155d8483..80f63b733820 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -178,6 +178,15 @@ config MTK_ADSP_IPC
ADSP exists on some mtk processors.
Client might use shared memory to exchange information with ADSP.
+config MTK_VCP_IPC
+ tristate "MTK VCP IPC Protocol driver"
+ depends on MTK_VCP_MBOX
+ help
+ Say yes here to add support for the MediaTek VCP IPC
+ between host AP (Linux) and the firmware running on VCP.
+ VCP exists on some mtk processors.
+ Client might use shared memory to exchange information with VCP.
+
config SYSFB
bool
select BOOT_VESA_SUPPORT
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4ddec2820c96..d6b6197cb54c 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
obj-$(CONFIG_MTK_ADSP_IPC) += mtk-adsp-ipc.o
+obj-$(CONFIG_MTK_VCP_IPC) += mtk-vcp-ipc.o
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
obj-$(CONFIG_SYSFB) += sysfb.o
diff --git a/drivers/firmware/mtk-vcp-ipc.c b/drivers/firmware/mtk-vcp-ipc.c
new file mode 100644
index 000000000000..8c9991018895
--- /dev/null
+++ b/drivers/firmware/mtk-vcp-ipc.c
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/firmware/mediatek/mtk-vcp-ipc.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/sched/clock.h>
+#include <linux/time64.h>
+#include <linux/vmalloc.h>
+
+/**
+ * struct mtk_ipi_chan_table - channel table that belong to mtk_ipi_device
+ * @mbox: the mbox channel number
+ * @mbox_pin_cb: callback function
+ * @holder: keep 1 if there are ipi waiters (to wait the reply)
+ * @ipi_record: timestamp of each ipi transmission stage
+ * @pin_buf: buffer point
+ * @prdata: private data
+ * @recv_opt: recv option, 0:receive ,1: response
+ * @notify: completion notify process
+ * @send_ofs: message offset in the slots of a mbox
+ * @send_index: bit offset in the mbox
+ * @msg_size: slot size of the ipi message
+ *
+ * All of these data should be initialized by mtk_ipi_device_register()
+ */
+struct mtk_ipi_chan_table {
+ u32 mbox;
+ mbox_pin_cb_t mbox_pin_cb;
+ atomic_t holder;
+ void *pin_buf;
+ void *prdata;
+ u32 recv_opt;
+ struct completion notify;
+ /* define a mutex for remote response */
+ struct mutex mutex_send;
+ u32 send_ofs;
+ u32 send_index;
+ u32 msg_size;
+};
+
+/**
+ * mbox information
+ *
+ * @mbdev: mbox device
+ * @mbox_id: mbox id
+ * @slot: how many slots that mbox used
+ * @opt: option for tx mode, 0:mbox, 1:share memory 2:queue
+ * @base: mbox base address
+ * @mbox_client: mbox client
+ * @mbox_chan: mbox channel
+ */
+struct mtk_mbox_info {
+ struct mtk_vcp_ipc *vcp_ipc;
+ u32 mbox_id;
+ u32 slot;
+ u32 opt;
+ /* lock of mbox */
+ spinlock_t mbox_lock;
+ struct mbox_client cl;
+ struct mbox_chan *ch;
+ struct mtk_ipi_info ipi_info;
+};
+
+static const char * const mbox_names[VCP_MBOX_NUM] = {
+ "mbox0", "mbox1", "mbox2", "mbox3", "mbox4"
+};
+
+/**
+ * mtk_vcp_ipc_recv - recv callback used by MTK VCP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of VCP IPC will need to provide handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_vcp_ipc_recv(struct mbox_client *c, void *msg)
+{
+ struct mtk_mbox_info *minfo = container_of(c, struct mtk_mbox_info, cl);
+ struct mtk_vcp_ipc *vcp_ipc = minfo->vcp_ipc;
+ struct mtk_ipi_info *ipi_info = msg;
+ struct mtk_ipi_device *ipidev = vcp_ipc->ipi_priv;
+ struct mtk_ipi_chan_table *table;
+ struct mtk_mbox_recv_table *mbox_recv;
+ u32 id;
+
+ /* execute all receive pin handler */
+ for (id = 0; id < vcp_ipc->mbdev->recv_count; id++) {
+ mbox_recv = &vcp_ipc->mbdev->recv_table[id];
+ if (mbox_recv->mbox_id != minfo->mbox_id)
+ continue;
+
+ if (!(BIT(mbox_recv->pin_index) & ipi_info->irq_status))
+ continue;
+
+ table = &ipidev->table[mbox_recv->ipi_id];
+ if (!table->pin_buf) {
+ dev_err(vcp_ipc->dev, "IPI%d buf is null.\n",
+ mbox_recv->ipi_id);
+ continue;
+ }
+
+ memcpy(table->pin_buf,
+ ipi_info->msg + mbox_recv->offset * MBOX_SLOT_SIZE,
+ mbox_recv->msg_size * MBOX_SLOT_SIZE);
+
+ if (!mbox_recv->recv_opt && table->mbox_pin_cb)
+ table->mbox_pin_cb(mbox_recv->ipi_id,
+ table->prdata,
+ table->pin_buf,
+ mbox_recv->msg_size * MBOX_SLOT_SIZE);
+
+ /* notify task */
+ if (table->recv_opt == MBOX_RECV_MESSAGE ||
+ atomic_read(&table->holder))
+ complete(&table->notify);
+ }
+}
+
+/*
+ * mtk_vcp_ipc_send - send ipc command to MTK VCP
+ *
+ * @ipidev: VCP struct mtk_ipi_device handle
+ * @id: id of the feature IPI
+ * @data: message address
+ * @len: message length
+ *
+ * Return: Zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_vcp_ipc_send(struct mtk_ipi_device *ipidev, u32 id, void *data, u32 len)
+{
+ struct device *dev;
+ struct mtk_mbox_info *minfo;
+ struct mtk_ipi_chan_table *table;
+ struct mtk_vcp_ipc *vcp_ipc;
+ int ret;
+
+ if (!ipidev || !ipidev->ipi_inited || !data)
+ return IPI_UNAVAILABLE;
+ vcp_ipc = ipidev->vcp_ipc;
+ if (!vcp_ipc)
+ return IPI_UNAVAILABLE;
+
+ table = ipidev->table;
+ dev = ipidev->vcp_ipc->dev;
+ minfo = &ipidev->vcp_ipc->info_table[table[id].mbox];
+ if (!minfo) {
+ dev_err(dev, "%s IPI%d minfo is invalid.\n", ipidev->name, id);
+ return IPI_UNAVAILABLE;
+ }
+
+ if (len > table[id].msg_size)
+ return IPI_MSG_TOO_BIG;
+ else if (!len)
+ len = table[id].msg_size;
+
+ mutex_lock(&table[id].mutex_send);
+
+ minfo->ipi_info.msg = data;
+ minfo->ipi_info.len = len;
+ minfo->ipi_info.id = id;
+ minfo->ipi_info.index = table[id].send_index;
+ minfo->ipi_info.slot_ofs = table[id].send_ofs * MBOX_SLOT_SIZE;
+
+ ret = mbox_send_message(minfo->ch, &minfo->ipi_info);
+ mutex_unlock(&table[id].mutex_send);
+ if (ret < 0) {
+ dev_err(dev, "%s IPI%d send failed.\n", ipidev->name, id);
+ return IPI_MBOX_ERR;
+ }
+
+ return IPI_ACTION_DONE;
+}
+EXPORT_SYMBOL(mtk_vcp_ipc_send);
+
+/*
+ * mtk_vcp_ipc_send_compl - send ipc command to MTK VCP
+ *
+ * @ipidev: VCP struct mtk_ipi_device handle
+ * @id: id of the feature IPI
+ * @data: message address
+ * @len: message length
+ * @timeout_ms:
+ *
+ * Return: Zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_vcp_ipc_send_compl(struct mtk_ipi_device *ipidev, u32 id,
+ void *data, u32 len, u32 timeout_ms)
+{
+ struct device *dev;
+ struct mtk_mbox_info *minfo;
+ struct mtk_ipi_chan_table *table;
+ struct mtk_vcp_ipc *vcp_ipc;
+ int ret;
+
+ if (!ipidev || !ipidev->ipi_inited || !data)
+ return IPI_UNAVAILABLE;
+ vcp_ipc = ipidev->vcp_ipc;
+ if (!vcp_ipc)
+ return IPI_UNAVAILABLE;
+
+ table = ipidev->table;
+ dev = ipidev->vcp_ipc->dev;
+ minfo = &ipidev->vcp_ipc->info_table[table[id].mbox];
+ if (!minfo) {
+ dev_err(dev, "%s IPI%d minfo is invalid.\n", ipidev->name, id);
+ return IPI_UNAVAILABLE;
+ }
+
+ if (len > table[id].msg_size)
+ return IPI_MSG_TOO_BIG;
+ else if (!len)
+ len = table[id].msg_size;
+
+ mutex_lock(&table[id].mutex_send);
+
+ minfo->ipi_info.msg = data;
+ minfo->ipi_info.len = len;
+ minfo->ipi_info.id = id;
+ minfo->ipi_info.index = table[id].send_index;
+ minfo->ipi_info.slot_ofs = table[id].send_ofs * MBOX_SLOT_SIZE;
+
+ atomic_inc(&table[id].holder);
+
+ ret = mbox_send_message(minfo->ch, &minfo->ipi_info);
+ if (ret < 0) {
+ atomic_set(&table[id].holder, 0);
+ mutex_unlock(&table[id].mutex_send);
+ dev_err(dev, "%s IPI%d send failed.\n", ipidev->name, id);
+ return IPI_MBOX_ERR;
+ }
+
+ /* wait for completion */
+ ret = wait_for_completion_timeout(&table[id].notify,
+ msecs_to_jiffies(timeout_ms));
+ atomic_set(&table[id].holder, 0);
+ if (ret > 0)
+ ret = IPI_ACTION_DONE;
+
+ mutex_unlock(&table[id].mutex_send);
+
+ return ret;
+}
+EXPORT_SYMBOL(mtk_vcp_ipc_send_compl);
+
+int mtk_vcp_mbox_ipc_register(struct mtk_ipi_device *ipidev, int id,
+ mbox_pin_cb_t cb, void *prdata, void *msg)
+{
+ if (!ipidev || !ipidev->ipi_inited)
+ return IPI_DEV_ILLEGAL;
+ if (!msg)
+ return IPI_NO_MSGBUF;
+
+ if (ipidev->table[id].pin_buf)
+ return IPI_ALREADY_USED;
+ ipidev->table[id].mbox_pin_cb = cb;
+ ipidev->table[id].pin_buf = msg;
+ ipidev->table[id].prdata = prdata;
+
+ return IPI_ACTION_DONE;
+}
+EXPORT_SYMBOL(mtk_vcp_mbox_ipc_register);
+
+int mtk_vcp_mbox_ipc_unregister(struct mtk_ipi_device *ipidev, int id)
+{
+ if (!ipidev || !ipidev->ipi_inited)
+ return IPI_DEV_ILLEGAL;
+
+ /* Drop the ipi and reset the record */
+ complete(&ipidev->table[id].notify);
+
+ ipidev->table[id].mbox_pin_cb = NULL;
+ ipidev->table[id].pin_buf = NULL;
+ ipidev->table[id].prdata = NULL;
+
+ return IPI_ACTION_DONE;
+}
+EXPORT_SYMBOL(mtk_vcp_mbox_ipc_unregister);
+
+static void mtk_fill_in_entry(struct mtk_ipi_chan_table *entry, const u32 ipi_id,
+ const struct mtk_mbox_table *mbdev)
+{
+ const struct mtk_mbox_send_table *mbox_send = mbdev->send_table;
+ u32 index;
+
+ for (index = 0; index < mbdev->send_count; index++) {
+ if (ipi_id != mbox_send[index].ipi_id)
+ continue;
+
+ entry->send_ofs = mbox_send[index].offset;
+ entry->send_index = mbox_send[index].pin_index;
+ entry->msg_size = mbox_send[index].msg_size;
+ entry->mbox = mbox_send[index].mbox_id;
+ return;
+ }
+
+ entry->mbox = -ENOENT;
+}
+
+int mtk_vcp_ipc_device_register(struct mtk_ipi_device *ipidev,
+ u32 ipi_chan_count, struct mtk_vcp_ipc *vcp_ipc)
+{
+ struct mtk_ipi_chan_table *ipi_chan_table;
+ struct mtk_mbox_table *mbdev;
+ u32 index;
+
+ if (!vcp_ipc || !ipidev)
+ return -EINVAL;
+
+ ipi_chan_table = kcalloc(ipi_chan_count,
+ sizeof(struct mtk_ipi_chan_table), GFP_KERNEL);
+ if (!ipi_chan_table)
+ return -ENOMEM;
+
+ mbdev = vcp_ipc->mbdev;
+ vcp_ipc->ipi_priv = (void *)ipidev;
+ ipidev->table = ipi_chan_table;
+ ipidev->vcp_ipc = vcp_ipc;
+
+ for (index = 0; index < ipi_chan_count; index++) {
+ atomic_set(&ipi_chan_table[index].holder, 0);
+ mutex_init(&ipi_chan_table[index].mutex_send);
+ init_completion(&ipi_chan_table[index].notify);
+ mtk_fill_in_entry(&ipi_chan_table[index], index, mbdev);
+ }
+
+ ipidev->ipi_inited = 1;
+
+ dev_dbg(vcp_ipc->dev, "%s (with %d IPI) has registered.\n",
+ ipidev->name, ipi_chan_count);
+
+ return IPI_ACTION_DONE;
+}
+EXPORT_SYMBOL(mtk_vcp_ipc_device_register);
+
+static int setup_mbox_table(struct mtk_mbox_table *mbdev, u32 mbox)
+{
+ struct mtk_mbox_send_table *mbox_send = &mbdev->send_table[0];
+ struct mtk_mbox_recv_table *mbox_recv = &mbdev->recv_table[0];
+ u32 i, last_ofs = 0, last_idx = 0, last_slot = 0, last_sz = 0;
+
+ for (i = 0; i < mbdev->send_count; i++) {
+ if (mbox == mbox_send[i].mbox_id) {
+ mbox_send[i].offset = last_ofs + last_slot;
+ mbox_send[i].pin_index = last_idx + last_sz;
+ last_idx = mbox_send[i].pin_index;
+ last_sz = DIV_ROUND_UP(mbox_send[i].msg_size, MBOX_SLOT_ALIGN);
+ last_ofs = last_sz * MBOX_SLOT_ALIGN;
+ last_slot = last_idx * MBOX_SLOT_ALIGN;
+ } else if (mbox < mbox_send[i].mbox_id) {
+ /* no need to search the rest id */
+ break;
+ }
+ }
+
+ for (i = 0; i < mbdev->recv_count; i++) {
+ if (mbox == mbox_recv[i].mbox_id) {
+ mbox_recv[i].offset = last_ofs + last_slot;
+ mbox_recv[i].pin_index = last_idx + last_sz;
+ last_idx = mbox_recv[i].pin_index;
+ last_sz = DIV_ROUND_UP(mbox_recv[i].msg_size, MBOX_SLOT_ALIGN);
+ last_ofs = last_sz * MBOX_SLOT_ALIGN;
+ last_slot = last_idx * MBOX_SLOT_ALIGN;
+ } else if (mbox < mbox_recv[i].mbox_id) {
+ /* no need to search the rest id */
+ break;
+ }
+ }
+
+ if (last_idx > MBOX_MAX_PIN || (last_ofs + last_slot) > MTK_VCP_MBOX_SLOT_MAX_SIZE / 4)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mtk_vcp_ipc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_vcp_ipc *vcp_ipc;
+ struct mbox_client *cl;
+ struct mtk_mbox_info *minfo;
+ int ret;
+ u32 mbox, i;
+ struct mtk_mbox_table *mbox_data = dev_get_platdata(dev);
+
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+ vcp_ipc = devm_kzalloc(dev, sizeof(*vcp_ipc), GFP_KERNEL);
+ if (!vcp_ipc)
+ return -ENOMEM;
+
+ if (!mbox_data) {
+ dev_err(dev, "No platform data available\n");
+ return -EINVAL;
+ }
+ vcp_ipc->mbdev = mbox_data;
+
+ /* alloc and init mmup_mbox_info */
+ vcp_ipc->info_table = vzalloc(sizeof(*vcp_ipc->info_table) * VCP_MBOX_NUM);
+ if (!vcp_ipc->info_table)
+ return -ENOMEM;
+
+ /* create mbox dev */
+ for (mbox = 0; mbox < VCP_MBOX_NUM; mbox++) {
+ minfo = &vcp_ipc->info_table[mbox];
+ minfo->mbox_id = mbox;
+ minfo->vcp_ipc = vcp_ipc;
+ spin_lock_init(&minfo->mbox_lock);
+
+ ret = setup_mbox_table(vcp_ipc->mbdev, mbox);
+ if (ret)
+ return ret;
+
+ cl = &minfo->cl;
+ cl->dev = &pdev->dev;
+ cl->tx_block = false;
+ cl->knows_txdone = false;
+ cl->tx_prepare = NULL;
+ cl->rx_callback = mtk_vcp_ipc_recv;
+ minfo->ch = mbox_request_channel_byname(cl, mbox_names[mbox]);
+ if (IS_ERR(minfo->ch)) {
+ ret = PTR_ERR(minfo->ch);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to request mbox channel %s ret %d\n",
+ mbox_names[mbox], ret);
+
+ for (i = 0; i < mbox; i++) {
+ minfo = &vcp_ipc->info_table[i];
+ mbox_free_channel(minfo->ch);
+ }
+
+ vfree(vcp_ipc->info_table);
+ return ret;
+ }
+ }
+
+ vcp_ipc->dev = dev;
+ dev_set_drvdata(dev, vcp_ipc);
+ dev_dbg(dev, "MTK VCP IPC initialized\n");
+
+ return 0;
+}
+
+static void mtk_vcp_ipc_remove(struct platform_device *pdev)
+{
+ struct mtk_vcp_ipc *vcp_ipc = dev_get_drvdata(&pdev->dev);
+ struct mtk_mbox_info *minfo;
+ int i;
+
+ for (i = 0; i < VCP_MBOX_NUM; i++) {
+ minfo = &vcp_ipc->info_table[i];
+ mbox_free_channel(minfo->ch);
+ }
+
+ vfree(vcp_ipc->info_table);
+}
+
+static struct platform_driver mtk_vcp_ipc_driver = {
+ .probe = mtk_vcp_ipc_probe,
+ .remove = mtk_vcp_ipc_remove,
+ .driver = {
+ .name = "mtk-vcp-ipc",
+ },
+};
+builtin_platform_driver(mtk_vcp_ipc_driver);
+
+MODULE_AUTHOR("Jjian Zhou <jjian.zhou@mediatek.com>");
+MODULE_DESCRIPTION("MediaTek VCP IPC Controller");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/firmware/mediatek/mtk-vcp-ipc.h b/include/linux/firmware/mediatek/mtk-vcp-ipc.h
new file mode 100644
index 000000000000..dc34b0ba9dd8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-vcp-ipc.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ */
+
+#ifndef __MTK_VCP_IPC_H__
+#define __MTK_VCP_IPC_H__
+
+#include <linux/completion.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox/mtk-vcp-mailbox.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* IPI result definition */
+#define IPI_ACTION_DONE 0
+#define IPI_DEV_ILLEGAL -1 /* ipi device is not initialized */
+#define IPI_ALREADY_USED -2 /* the ipi has be registered */
+#define IPI_UNAVAILABLE -3 /* the ipi can't be found */
+#define IPI_NO_MSGBUF -4 /* receiver doesn't have message buffer */
+#define IPI_MSG_TOO_BIG -5 /* message length is larger than defined */
+#define IPI_MBOX_ERR -99 /* some error from rpmsg layer */
+
+/* mbox recv action definition */
+enum mtk_ipi_recv_opt {
+ MBOX_RECV_MESSAGE = 0,
+ MBOX_RECV_ACK = 1,
+};
+
+/* mbox table item number definition */
+#define send_item_num 3
+#define recv_item_num 4
+#define VCP_MBOX_NUM 5
+
+/* mbox slot size definition: 1 slot for 4 bytes */
+#define MBOX_SLOT_SIZE 0x4
+#define MBOX_MAX_PIN 32
+#define VCP_MBOX_NUM 5
+#define MBOX_SLOT_ALIGN 2
+
+struct mtk_vcp_ipc;
+struct mtk_ipi_chan_table;
+
+typedef int (*mbox_pin_cb_t)(u32 ipi_id, void *prdata, void *data, u32 len);
+
+/**
+ * mbox pin structure, this is for send definition,
+ * @offset: message offset in the slots of a mbox
+ * @msg_size: message used slots in the mbox, 4 bytes alignment
+ * @pin_index: bit offset in the mbox
+ * @ipi_id: ipi enum number
+ * @mbox_id: mbox number id
+ */
+struct mtk_mbox_send_table {
+ u32 offset;
+ u32 msg_size;
+ u32 pin_index;
+ u32 ipi_id;
+ u32 mbox_id;
+};
+
+/**
+ * mbox pin structure, this is for receive definition,
+ * @offset: message offset in the slots of a mbox
+ * @recv_opt: recv option, 0:receive ,1: response
+ * @msg_size: message used slots in the mbox, 4 bytes alignment
+ * @pin_index: bit offset in the mbox
+ * @ipi_id: ipi enum number
+ * @mbox_id: mbox number id
+ */
+struct mtk_mbox_recv_table {
+ u32 offset;
+ u32 recv_opt;
+ u32 msg_size;
+ u32 pin_index;
+ u32 ipi_id;
+ u32 mbox_id;
+};
+
+/**
+ * struct mtk_ipi_device - device for represent the tinysys using mtk ipi
+ * @name: name of tinysys device
+ * @id: device id (used to match between rpmsg drivers and devices)
+ * @vcp_ipc: vcp ipc structure for tinysys device
+ * @table: channel table with endpoint & channel_info & mbox_pin info
+ * @prdata: private data for the callback use
+ * @ipi_inited: set when vcp_ipi_device_register() done
+ */
+struct mtk_ipi_device {
+ const char *name;
+ struct mtk_vcp_ipc *vcp_ipc;
+ struct mtk_ipi_chan_table *table;
+ void *prdata;
+ int ipi_inited;
+};
+
+/**
+ * The mtk_mbox_table is a structure used to record the send
+ * table and recv table. The send table is used to record
+ * the feature ID and size of the sent data. The recv table
+ * is used to record the feature ID and size of the received
+ * data, and whether a callback needs to be invoked.
+ *
+ * Following are platform specific interfacer
+ * @recv_table: structure mtk_mbox_recv_table
+ * @send_table: structure mtk_mbox_send_table
+ * @recv_count: receive feature number in this channel
+ * @send_count: send feature number in this channel
+ */
+struct mtk_mbox_table {
+ struct mtk_mbox_recv_table recv_table[32];
+ struct mtk_mbox_send_table send_table[32];
+ u32 recv_count;
+ u32 send_count;
+};
+
+/**
+ * Mbox is a dedicate hardware of a tinysys consists of:
+ * 1) a share memory tightly coupled to the tinysys
+ * 2) several IRQs
+ *
+ * Following are platform specific interface
+ * @dev: vcp device
+ * @name: identity of the device
+ * @info_table: mbox info structure
+ * @ipi_priv: private data for synchronization layer
+ * @mbox_id: mbox number
+ * @mbdev: mtk_mbox_table structure
+ */
+struct mtk_vcp_ipc {
+ struct device *dev;
+ const char *name;
+ struct mtk_mbox_info *info_table;
+ void *ipi_priv;
+ void *mbox_id;
+ struct mtk_mbox_table *mbdev;
+};
+
+int mtk_vcp_ipc_device_register(struct mtk_ipi_device *ipidev,
+ u32 ipi_chan_count,
+ struct mtk_vcp_ipc *vcp_ipc);
+int mtk_vcp_ipc_send(struct mtk_ipi_device *ipidev, u32 ipi_id,
+ void *data, u32 len);
+int mtk_vcp_ipc_send_compl(struct mtk_ipi_device *ipidev, u32 ipi_id,
+ void *data, u32 len, u32 timeout_ms);
+int mtk_vcp_mbox_ipc_register(struct mtk_ipi_device *ipidev, int ipi_id,
+ mbox_pin_cb_t cb, void *prdata, void *msg);
+int mtk_vcp_mbox_ipc_unregister(struct mtk_ipi_device *ipidev, int ipi_id);
+
+#endif
--
2.46.0
^ permalink raw reply related
* [PATCH v4 1/7] dt-bindings: remoteproc: Add MediaTek mt8196 VCP binding
From: Xiangzhi Tang @ 2026-04-27 11:04 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Xiangzhi Tang
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, Hailong Fan,
Huayu Zong, Jarried Lin, Justin Yeh, Vince-WL Liu, Xiangzhi Tang
In-Reply-To: <20260427111446.22955-1-xiangzhi.tang@mediatek.com>
Add device tree binding for the MediaTek Video Companion Processor
(VCP), a RISC-V based coprocessor used for video processing and
multimedia tasks on mt8196 and future MediaTek SoCs.
The VCP is a heterogeneous multi-core processor that can contain
multiple RISC-V cores with different hart (hardware thread)
configurations. Key features:
- Supports both single-core and multi-core VCP configurations
- Each core can have 1 or 2 harts (hardware threads)
- Shared SRAM memory space partitioned among cores
- Communication via 5 dedicated mailbox channels for IPI messaging
- Integrated with SoC IOMMU for multimedia memory management
- Boot and power management coordinated with ARM Trusted Firmware
The binding defines both the top-level VCP device (with mailboxes,
interrupts, and power domains) and child nodes for individual VCP
cores (with SRAM allocation and hart configuration).
Signed-off-by: Xiangzhi Tang <xiangzhi.tang@mediatek.com>
---
.../remoteproc/mediatek,mt8196-vcp.yaml | 166 ++++++++++++++++++
1 file changed, 166 insertions(+)
create mode 100644 Documentation/devicetree/bindings/remoteproc/mediatek,mt8196-vcp.yaml
diff --git a/Documentation/devicetree/bindings/remoteproc/mediatek,mt8196-vcp.yaml b/Documentation/devicetree/bindings/remoteproc/mediatek,mt8196-vcp.yaml
new file mode 100644
index 000000000000..8ecb643cbdc5
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/mediatek,mt8196-vcp.yaml
@@ -0,0 +1,166 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/mediatek,mt8196-vcp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Video Companion Processor (VCP)
+
+maintainers:
+ - Xiangzhi Tang <xiangzhi.tang@mediatek.com>
+
+description:
+ This binding provides support for the MediaTek Video Companion Processor
+ (VCP), a Risc-V coprocessor found on some MediaTek SoCs.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8196-vcp
+
+ reg:
+ items:
+ - description: sram base
+ - description: cfg group IO
+ - description: cfg core group IO
+ - description: cfg sec group IO
+
+ reg-names:
+ items:
+ - const: sram
+ - const: cfg
+ - const: cfg-core
+ - const: cfg-sec
+
+ interrupts:
+ maxItems: 1
+
+ mboxes:
+ maxItems: 5
+
+ mbox-names:
+ items:
+ - const: mbox0
+ - const: mbox1
+ - const: mbox2
+ - const: mbox3
+ - const: mbox4
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ description:
+ Using MediaTek IOMMU to apply larb ports for Multimedia Memory
+ Management Unit and address translation.
+ maxItems: 1
+
+ memory-region:
+ maxItems: 1
+
+patternProperties:
+ "^vcp@[a-f0-9]+$":
+ type: object
+ description:
+ The MediaTek VCP integrated to SoC might be a multi-core version.
+ The other cores are represented as child nodes of the boot core.
+ There are some integration differences for the IP like the usage of
+ address translator for translating SoC bus addresses into address
+ space for the processor.
+
+ The SRAM is shared by all cores, each VCP core only using a piece of
+ SRAM memory. The power of SRAM should be enabled before booting VCP cores.
+ The size of SRAM varies on different SoCs.
+
+ The VCP cores have differences on different SoCs for Hart support.
+
+ properties:
+ compatible:
+ enum:
+ - mediatek,vcp-core
+
+ reg:
+ description: The base address and size of SRAM.
+ maxItems: 1
+
+ reg-names:
+ const: sram
+
+ mediatek,vcp-core-harts:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of harts in this VCP core.
+ enum: [1, 2]
+
+ mediatek,vcp-core-sram-offset:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Offset of the allocated SRAM memory for this VCP core.
+
+ required:
+ - compatible
+ - reg
+ - reg-names
+ - mediatek,vcp-core-harts
+ - mediatek,vcp-core-sram-offset
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - mboxes
+ - mbox-names
+ - power-domains
+ - iommus
+ - memory-region
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/power/mt8196-power.h>
+
+ vcp: vcp@31800000 {
+ compatible = "mediatek,mt8196-vcp";
+ reg = <0x31800000 0x60000>,
+ <0x31a04000 0xa000>,
+ <0x31bd0000 0x1000>,
+ <0x31a70020 0x100>;
+ reg-names = "sram",
+ "cfg",
+ "cfg-core",
+ "cfg-sec";
+
+ interrupts = <GIC_SPI 787 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ mboxes = <&vcp_mailbox0>,
+ <&vcp_mailbox1>,
+ <&vcp_mailbox2>,
+ <&vcp_mailbox3>,
+ <&vcp_mailbox4>;
+ mbox-names = "mbox0", "mbox1", "mbox2", "mbox3", "mbox4";
+
+ power-domains = <&scpsys MT8196_POWER_DOMAIN_MM_PROC_DORMANT>;
+ iommus = <&mm_smmu 160>;
+ memory-region = <&vcp_resv_mem>;
+
+ vcp@0 {
+ compatible = "mediatek,vcp-core";
+ reg = <0x0 0x31000>;
+ reg-names = "sram";
+ mediatek,vcp-core-harts = <2>;
+ mediatek,vcp-core-sram-offset = <0x0>;
+ };
+
+ vcp@31000 {
+ compatible = "mediatek,vcp-core";
+ reg = <0x31000 0x60000>;
+ reg-names = "sram";
+ mediatek,vcp-core-harts = <1>;
+ mediatek,vcp-core-sram-offset = <0x31000>;
+ };
+ };
--
2.46.0
^ permalink raw reply related
* [PATCH v4 4/7] remoteproc: mediatek: Add VCP IPI mailbox initialization
From: Xiangzhi Tang @ 2026-04-27 11:04 UTC (permalink / raw)
To: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Xiangzhi Tang
Cc: linux-remoteproc, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, Hailong Fan,
Huayu Zong, Jarried Lin, Justin Yeh, Vince-WL Liu, Xiangzhi Tang
In-Reply-To: <20260427111446.22955-1-xiangzhi.tang@mediatek.com>
Initialize the IPI (Inter-Processor Interrupt) communication channels
between the host AP and VCP firmware using the MediaTek mailbox
framework.
The VCP uses 5 hardware mailboxes (mbox0-4) to route different types
of IPI messages between the host CPU and the VCP coprocessor. Each IPI
channel has a specific purpose and is configured with message size and
routing information:
- mbox0: Video decoder (VDEC) communication
- mbox1: Video encoder (VENC), multimedia DVFS, and hardware voter
- mbox2: Multimedia QoS (MMQOS), power sleep control, and test interface
- mbox3: DVFS for multimedia utility processor, debug, and display
- mbox4: Logger control for both VCP cores
The IPI routing tables (mt8196_ipc_tb) define 14 send channels and
11 receive channels, specifying message sizes (in 4-byte slots) and
mailbox assignments for each IPI ID.
The vcp_ipi_mbox_init() function:
1. Registers the mtk-vcp-ipc platform device with the IPC routing table
2. Waits for the IPC driver to probe and become ready
3. Registers the IPI device with the VCP for subsequent IPI operations
A new vcp_get_ipidev() API is exported to allow other kernel drivers
to obtain the IPI device handle for sending messages to VCP.
Signed-off-by: Xiangzhi Tang <xiangzhi.tang@mediatek.com>
---
drivers/remoteproc/Kconfig | 2 +
drivers/remoteproc/mtk_vcp_rproc.c | 99 +++++++++++++++++++++++
drivers/remoteproc/mtk_vcp_rproc.h | 6 ++
include/linux/remoteproc/mtk_vcp_public.h | 55 +++++++++++++
4 files changed, 162 insertions(+)
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 93827f6fd3c5..54b416db0c0b 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -70,6 +70,8 @@ config MTK_VCP_RPROC
tristate "MediaTek VCP support"
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on ARCH_DMA_ADDR_T_64BIT
+ select MTK_VCP_IPC
+ select MTK_VCP_MBOX
help
Say y here to support MediaTek's Video Companion Processor (VCP) via
the remote processor framework.
diff --git a/drivers/remoteproc/mtk_vcp_rproc.c b/drivers/remoteproc/mtk_vcp_rproc.c
index f12df45d782e..f3b2646f79f6 100644
--- a/drivers/remoteproc/mtk_vcp_rproc.c
+++ b/drivers/remoteproc/mtk_vcp_rproc.c
@@ -5,6 +5,7 @@
#include <linux/device.h>
#include <linux/module.h>
+#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -57,6 +58,19 @@ void vcp_put(struct mtk_vcp_device *vcp)
}
EXPORT_SYMBOL_GPL(vcp_put);
+/**
+ * vcp_get_ipidev() - get a vcp ipi device struct to reference vcp ipi.
+ *
+ * @vcp: mtk_vcp_device structure from vcp_get().
+ *
+ * Return: Pointer to mtk_ipi_device structure.
+ */
+struct mtk_ipi_device *vcp_get_ipidev(struct mtk_vcp_device *vcp)
+{
+ return vcp->ipi_dev;
+}
+EXPORT_SYMBOL_GPL(vcp_get_ipidev);
+
static int mtk_vcp_start(struct rproc *rproc)
{
struct mtk_vcp_device *vcp = rproc->priv;
@@ -108,6 +122,34 @@ static const struct rproc_ops mtk_vcp_ops = {
.stop = mtk_vcp_stop,
};
+static int vcp_ipi_mbox_init(struct mtk_vcp_device *vcp)
+{
+ struct mtk_vcp_ipc *vcp_ipc;
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_register_data(vcp->dev, "mtk-vcp-ipc",
+ PLATFORM_DEVID_NONE,
+ vcp->platdata->ipc_data,
+ sizeof(struct mtk_mbox_table));
+ if (IS_ERR(pdev))
+ return dev_err_probe(vcp->dev, PTR_ERR(pdev), "ipc_data register failed\n");
+
+ ret = read_poll_timeout_atomic(dev_get_drvdata,
+ vcp_ipc, vcp_ipc,
+ USEC_PER_MSEC,
+ VCP_IPI_DEV_READY_TIMEOUT * USEC_PER_MSEC,
+ false, &pdev->dev);
+ if (ret)
+ return dev_err_probe(vcp->dev, -EPROBE_DEFER, "get vcp_ipc drvdata failed\n");
+
+ ret = mtk_vcp_ipc_device_register(vcp->ipi_dev, VCP_IPI_COUNT, vcp_ipc);
+ if (ret)
+ dev_err_probe(vcp->dev, ret, "ipi_dev register failed, ret %d\n", ret);
+
+ return ret;
+}
+
static int vcp_multi_core_init(struct platform_device *pdev,
struct mtk_vcp_of_cluster *vcp_cluster,
enum vcp_core_id core_id)
@@ -156,7 +198,9 @@ static struct mtk_vcp_device *vcp_rproc_init(struct platform_device *pdev,
vcp->dev = dev;
vcp->ops = &vcp_of_data->ops;
vcp->platdata = &vcp_of_data->platdata;
+ vcp->ipi_ops = vcp_of_data->platdata.ipi_ops;
vcp->vcp_cluster = vcp_cluster;
+ vcp->ipi_dev = &vcp_cluster->vcp_ipidev;
rproc->auto_boot = vcp_of_data->platdata.auto_boot;
rproc->sysfs_read_only = vcp_of_data->platdata.sysfs_read_only;
@@ -189,6 +233,10 @@ static struct mtk_vcp_device *vcp_rproc_init(struct platform_device *pdev,
if (ret)
return ERR_PTR(dev_err_probe(dev, ret, "vcp_wdt_irq_init failed\n"));
+ ret = vcp_ipi_mbox_init(vcp);
+ if (ret)
+ return ERR_PTR(dev_err_probe(dev, ret, "vcp_ipi_mbox_init failed\n"));
+
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
@@ -309,6 +357,55 @@ static struct mtk_vcp_reserved_mem_table mt8196_memory_tb[NUMS_MEM_ID] = {
{ .memory_id = MMQOS_MEM_ID, .size = 0x1000 },
};
+static struct mtk_mbox_table mt8196_ipc_tb = {
+ .send_table = {
+ { .msg_size = 18, .ipi_id = 0, .mbox_id = 0 },
+
+ { .msg_size = 8, .ipi_id = 15, .mbox_id = 1 },
+ { .msg_size = 18, .ipi_id = 16, .mbox_id = 1 },
+ { .msg_size = 2, .ipi_id = 9, .mbox_id = 1 },
+
+ { .msg_size = 18, .ipi_id = 11, .mbox_id = 2 },
+ { .msg_size = 2, .ipi_id = 2, .mbox_id = 2 },
+ { .msg_size = 3, .ipi_id = 3, .mbox_id = 2 },
+ { .msg_size = 2, .ipi_id = 32, .mbox_id = 2 },
+
+ { .msg_size = 2, .ipi_id = 33, .mbox_id = 3 },
+ { .msg_size = 2, .ipi_id = 13, .mbox_id = 3 },
+ { .msg_size = 2, .ipi_id = 35, .mbox_id = 3 },
+
+ { .msg_size = 2, .ipi_id = 20, .mbox_id = 4 },
+ { .msg_size = 3, .ipi_id = 21, .mbox_id = 4 },
+ { .msg_size = 2, .ipi_id = 23, .mbox_id = 4 }
+ },
+ .recv_table = {
+ { .recv_opt = 0, .msg_size = 18, .ipi_id = 1, .mbox_id = 0 },
+
+ { .recv_opt = 1, .msg_size = 8, .ipi_id = 15, .mbox_id = 1 },
+ { .recv_opt = 0, .msg_size = 18, .ipi_id = 17, .mbox_id = 1 },
+ { .recv_opt = 0, .msg_size = 2, .ipi_id = 10, .mbox_id = 1 },
+
+ { .recv_opt = 0, .msg_size = 18, .ipi_id = 12, .mbox_id = 2 },
+ { .recv_opt = 0, .msg_size = 1, .ipi_id = 5, .mbox_id = 2 },
+ { .recv_opt = 1, .msg_size = 1, .ipi_id = 2, .mbox_id = 2 },
+
+ { .recv_opt = 0, .msg_size = 2, .ipi_id = 34, .mbox_id = 3 },
+ { .recv_opt = 0, .msg_size = 2, .ipi_id = 14, .mbox_id = 3 },
+
+ { .recv_opt = 0, .msg_size = 1, .ipi_id = 26, .mbox_id = 4 },
+ { .recv_opt = 1, .msg_size = 1, .ipi_id = 20, .mbox_id = 4 }
+ },
+ .recv_count = 11,
+ .send_count = 14,
+};
+
+static struct mtk_vcp_ipi_ops mt8196_vcp_ipi_ops = {
+ .ipi_send = mtk_vcp_ipc_send,
+ .ipi_send_compl = mtk_vcp_ipc_send_compl,
+ .ipi_register = mtk_vcp_mbox_ipc_register,
+ .ipi_unregister = mtk_vcp_mbox_ipc_unregister,
+};
+
static const struct mtk_vcp_of_data mt8196_of_data = {
.ops = {
.get_mem_phys = vcp_get_reserve_mem_phys,
@@ -321,6 +418,8 @@ static const struct mtk_vcp_of_data mt8196_of_data = {
.auto_boot = true,
.sysfs_read_only = true,
.rtos_static_iova = 0x180600000,
+ .ipc_data = &mt8196_ipc_tb,
+ .ipi_ops = &mt8196_vcp_ipi_ops,
.feature_tb = mt8196_feature_tb,
.memory_tb = mt8196_memory_tb,
.fw_name = "mediatek/mt8196/vcp.img",
diff --git a/drivers/remoteproc/mtk_vcp_rproc.h b/drivers/remoteproc/mtk_vcp_rproc.h
index 3b989c8eb337..c34d3a2757a9 100644
--- a/drivers/remoteproc/mtk_vcp_rproc.h
+++ b/drivers/remoteproc/mtk_vcp_rproc.h
@@ -21,6 +21,7 @@
* @sram_offset: core sram memory layout
* @share_mem_iova: shared memory iova base
* @share_mem_size: shared memory size
+ * @vcp_ipidev: struct mtk_ipi_device
* @vcp_memory_tb: vcp memory allocated table
*/
struct mtk_vcp_of_cluster {
@@ -34,6 +35,7 @@ struct mtk_vcp_of_cluster {
u32 sram_offset[VCP_CORE_TOTAL];
dma_addr_t share_mem_iova;
size_t share_mem_size;
+ struct mtk_ipi_device vcp_ipidev;
struct vcp_reserve_mblock vcp_memory_tb[NUMS_MEM_ID];
};
@@ -43,6 +45,8 @@ struct mtk_vcp_of_cluster {
* @auto_boot: rproc auto_boot flag
* @sysfs_read_only: rproc sysfs_read_only flag
* @rtos_static_iova: vcp dram binary static map iova
+ * @mtk_mbox_table: mtk_mbox_table structure
+ * @mtk_vcp_ipi_ops: vcp ipi api ops structure
* @feature_tb: vcp feature table structure
* @memory_tb: vcp memory table structure
* @fw_name: vcp image name and path
@@ -51,6 +55,8 @@ struct mtk_vcp_platdata {
bool auto_boot;
bool sysfs_read_only;
dma_addr_t rtos_static_iova;
+ struct mtk_mbox_table *ipc_data;
+ struct mtk_vcp_ipi_ops *ipi_ops;
struct mtk_vcp_feature_table *feature_tb;
struct mtk_vcp_reserved_mem_table *memory_tb;
char *fw_name;
diff --git a/include/linux/remoteproc/mtk_vcp_public.h b/include/linux/remoteproc/mtk_vcp_public.h
index 7f326f9a1921..fda3cf5061e3 100644
--- a/include/linux/remoteproc/mtk_vcp_public.h
+++ b/include/linux/remoteproc/mtk_vcp_public.h
@@ -7,8 +7,18 @@
#define __MTK_VCP_PUBLIC_H__
#include <linux/platform_device.h>
+#include <linux/firmware/mediatek/mtk-vcp-ipc.h>
#include <linux/remoteproc.h>
+#define VCP_SYNC_TIMEOUT_MS (50)
+
+enum vcp_notify_event {
+ VCP_EVENT_READY = 0,
+ VCP_EVENT_STOP,
+ VCP_EVENT_SUSPEND,
+ VCP_EVENT_RESUME,
+};
+
enum vcp_reserve_mem_id {
VCP_RTOS_MEM_ID,
VDEC_MEM_ID,
@@ -36,15 +46,59 @@ enum vcp_feature_id {
NUM_FEATURE_ID,
};
+enum {
+ IPI_OUT_VDEC_1 = 0,
+ IPI_IN_VDEC_1 = 1,
+ IPI_OUT_C_SLEEP_0 = 2,
+ IPI_OUT_TEST_0 = 3,
+ IPI_IN_VCP_READY_0 = 5,
+ IPI_OUT_MMDVFS_VCP = 9,
+ IPI_IN_MMDVFS_VCP = 10,
+ IPI_OUT_MMQOS = 11,
+ IPI_IN_MMQOS = 12,
+ IPI_OUT_MMDEBUG = 13,
+ IPI_IN_MMDEBUG = 14,
+ IPI_OUT_C_VCP_HWVOTER_DEBUG = 15,
+ IPI_OUT_VENC_0 = 16,
+ IPI_IN_VENC_0 = 17,
+ IPI_OUT_C_SLEEP_1 = 20,
+ IPI_OUT_TEST_1 = 21,
+ IPI_OUT_LOGGER_CTRL_0 = 22,
+ IPI_OUT_VCPCTL_1 = 23,
+ IPI_IN_LOGGER_CTRL_0 = 25,
+ IPI_IN_VCP_READY_1 = 26,
+ IPI_OUT_LOGGER_CTRL_1 = 30,
+ IPI_IN_LOGGER_CTRL_1 = 31,
+ IPI_OUT_VCPCTL_0 = 32,
+ IPI_OUT_MMDVFS_MMUP = 33,
+ IPI_IN_MMDVFS_MMUP = 34,
+ IPI_OUT_VDISP = 35,
+ VCP_IPI_COUNT,
+ VCP_IPI_NS_SERVICE = 0xff,
+ VCP_IPI_NS_SERVICE_COUNT = 0x100,
+};
+
struct mtk_vcp_device {
struct platform_device *pdev;
struct device *dev;
struct rproc *rproc;
+ struct mtk_ipi_device *ipi_dev;
struct mtk_vcp_of_cluster *vcp_cluster;
+ const struct mtk_vcp_ipi_ops *ipi_ops;
const struct mtk_vcp_ops *ops;
const struct mtk_vcp_platdata *platdata;
};
+struct mtk_vcp_ipi_ops {
+ int (*ipi_send)(struct mtk_ipi_device *ipidev, u32 ipi_id,
+ void *data, u32 len);
+ int (*ipi_send_compl)(struct mtk_ipi_device *ipidev, u32 ipi_id,
+ void *data, u32 len, u32 timeout_ms);
+ int (*ipi_register)(struct mtk_ipi_device *ipidev, int ipi_id,
+ mbox_pin_cb_t cb, void *prdata, void *msg);
+ int (*ipi_unregister)(struct mtk_ipi_device *ipidev, int ipi_id);
+};
+
struct mtk_vcp_ops {
phys_addr_t (*get_mem_phys)(struct mtk_vcp_device *vcp,
enum vcp_reserve_mem_id id);
@@ -59,6 +113,7 @@ struct mtk_vcp_ops {
struct mtk_vcp_device *vcp_get(struct platform_device *pdev);
void vcp_put(struct mtk_vcp_device *vcp);
+struct mtk_ipi_device *vcp_get_ipidev(struct mtk_vcp_device *vcp);
/*
* These inline functions are intended for user drivers that are loaded
--
2.46.0
^ 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