* Re: [PATCH] KVM: arm64: Validate the FF-A memory access descriptor placement
From: Sebastian Ene @ 2026-04-23 9:29 UTC (permalink / raw)
To: Marc Zyngier
Cc: oupton, will, ayrton, catalin.marinas, joey.gouly, korneld,
kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
mrigendra.chaubey, perlarsen, suzuki.poulose, yuzenghui, stable
In-Reply-To: <867bpy14kx.wl-maz@kernel.org>
On Thu, Apr 23, 2026 at 09:08:46AM +0100, Marc Zyngier wrote:
> On Wed, 22 Apr 2026 14:35:55 +0100,
> Sebastian Ene <sebastianene@google.com> wrote:
> >
> > On Wed, Apr 22, 2026 at 01:24:02PM +0100, Marc Zyngier wrote:
> > > On Wed, 22 Apr 2026 11:25:40 +0100,
> > > Sebastian Ene <sebastianene@google.com> wrote:
> > > >
> > > > Prevent the pKVM hypervisor from making assumptions that the
> > > > endpoint memory access descriptor (EMAD) comes right after the
> > > > FF-A memory region header and enforce a strict placement for it
> > > > when validating an FF-A memory lend/share transaction.
> >
> > Hello Marc,
> >
> > >
> > > As I read this, you want to remove a bad assumption...
> > >
> > > >
> > > > Prior to FF-A version 1.1 the header of the memory region
> > > > didn't contain an offset to the endpoint memory access descriptor.
> > > > The layout of a memory transaction looks like this:
> > > >
> > > > Field name | Offset
> > > > -- 0
> > > > [ Header (ffa_mem_region) |__ ep_mem_offset
> > > > EMAD 1 (ffa_mem_region_attributes) |
> > > > ]
> > > >
> > > > Reject the host from specifying a memory access descriptor offset
> > > > that is different than the size of the memory region header.
> > >
> > > And yet you decide that you want to enforce this assumption. I don't
> > > understand how you arrive to this conclusion.
> > >
> > > Looking at the spec, it appears that the offset is *designed* to allow
> > > a gap between the header and the EMAD. Refusing to handle a it seems to be a
> > > violation of the spec.
> > >
> > > What am I missing?
> >
> > While the spec allows the gap to be variable (since version 1.1), the
> > arm ff-a driver places it at a fixed position in:
> > ffa_mem_region_additional_setup()
> > https://elixir.bootlin.com/linux/v7.0/source/drivers/firmware/arm_ffa/driver.c#L671
>
> That's an implementation detail, and you shouldn't rely on this.
>
> > and makes use of the same assumption in: ffa_mem_desc_offset().
> > https://elixir.bootlin.com/linux/v7.0/source/include/linux/arm_ffa.h#L448
> > The later one seems wrong IMO. because we should compute the offset
> > based on the value stored in ep_mem_offset and not adding it up with
> > sizeof(struct ffa_mem_region).
> >
> > Maybe this should be the fix instead and not the one in pKVM ? What do
> > you think ?
>
> I think you should parse the buffers as the spec intends them, without
> assumptions or limitations.
Ack.
>
> >
> > The current implementation in pKVM makes use of the
> > ffa_mem_desc_offset() to validate the first EMAD. If a compromised host
> > places an EMAD at a different offset than sizeof(struct ffa_mem_region),
> > then pKVM will not validate that EMAD.
>
> Why compromised? Isn't that a perfectly valid thing to do? What I
> understand is that the FFA 1.1 implementation in pKVM doesn't match
> the expectations of the spec. If that's indeed the case, pKVM should
> be fixed to accept these messages correctly, or stop using FFA 1.1.
>
> M.
Sorry, what I meant is that a potentially malicious host could abuse
this limitation of the FF-A proxy validation which is looking at a fixed
offset to do the EMAD validation. Another EMAD can be placed at a
different offset and it will bypass the validation of the proxy
alltogether.
We have two choices: the simple one is what this patch does (enforce a
fixed offset) or the second one : patch `ffa_mem_desc_offset` to use
ep_mem_offset instead of `sizeof(struct ffa_mem_region)` and validate
the ep_mem_offset.
>
> --
> Without deviation from the norm, progress is not possible.
Thanks,
Sebastian
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Will Deacon @ 2026-04-23 9:44 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel, Nicolin Chen,
Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <20260422162351.GK3611611@ziepe.ca>
On Wed, Apr 22, 2026 at 01:23:51PM -0300, Jason Gunthorpe wrote:
> On Wed, Apr 22, 2026 at 06:44:31AM +0000, Evangelos Petrongonas wrote:
> > The motivation is live update of the hypervisor: we want to kexec into a
> > new kernel while keeping DMA from passthrough devices flowing, which
> > means the SMMU's translation state has to survive the handover. The Live
> > Update Orchestrator work [1] and the in-progress "iommu: Add live
> > update state preservation" series [2] are building exactly this plumbing
> > on top of KHO; [2]'s cover letter calls out Arm SMMUv3 support as future
> > work, and an earlier RFC from Amazon [3] sketched the same idea for
> > iommufd.
>
> It would be appropriate to keep this patch with the rest of that out
> of tree pile, for example in the series that enables s2 only support
> in smmuv3.
>
> > For this use case, Stage 2 is materially easier to persist than Stage 1,
> > for structural rather than performance reasons:
>
> I don't think so. The driver needs to know each and every STE that
> will survive KHO. The ones that don't survive need to be reset to
> abort STEs. From that point it is trivial enough to include the CD
> memory in the preservation.
>
> It would help to send a preparation series to switch the ARM STE and
> CD logic away from dma_alloc_coherent and use iommu-pages instead,
> since we only expect iommu-pages to support preservation..
Does iommu-pages provide a mechanism to map the memory as non-cacheable
if the SMMU isn't coherent? I really don't want to entertain CMOs for
the queues.
Will
^ permalink raw reply
* [PATCH 1/5] drm/exynos: fbdev: Remove offset into screen_buffer
From: Thomas Zimmermann @ 2026-04-23 9:37 UTC (permalink / raw)
To: inki.dae, sw0312.kim, kyungmin.park, airlied, simona, dri-devel
Cc: linux-samsung-soc, Thomas Zimmermann, linux-arm-kernel, stable
In-Reply-To: <20260423094452.32665-1-tzimmermann@suse.de>
The screen_buffer field in struct fb_info contains the kernel address
of the first byte of framebuffer memory. Do not add the display offset.
This offset only describes scrolling during scanout.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 19c8b8343d9c ("drm/exynos: fixed overlay data updating.")
Cc: dri-devel@lists.freedesktop.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: <stable@vger.kernel.org> # v3.2+
---
drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 637927818dfe..d283ded266d5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -61,17 +61,13 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
struct fb_info *fbi = helper->info;
struct drm_framebuffer *fb = helper->fb;
unsigned int size = fb->width * fb->height * fb->format->cpp[0];
- unsigned long offset;
fbi->fbops = &exynos_drm_fb_ops;
drm_fb_helper_fill_info(fbi, helper, sizes);
- offset = fbi->var.xoffset * fb->format->cpp[0];
- offset += fbi->var.yoffset * fb->pitches[0];
-
fbi->flags |= FBINFO_VIRTFB;
- fbi->screen_buffer = exynos_gem->kvaddr + offset;
+ fbi->screen_buffer = exynos_gem->kvaddr;
fbi->screen_size = size;
fbi->fix.smem_len = size;
--
2.53.0
^ permalink raw reply related
* [PATCH v14 02/12] media: mediatek: jpeg: fix jpeg buffer payload size setting
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
For multi-core jpegdec, if one core gets resolution change event,
the payload size, representing the size of Y/C data, needs to change.
But others are decoding at the same time and it can not be changed
immediately, which results in the payload size to not match the real
buffer length.
The payload size must less than the real buffer length to remove
the warnning logs.
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 30f684ac9318..10d3bfd7ddd5 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -702,6 +702,7 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct mtk_jpeg_q_data *q_data = NULL;
struct v4l2_plane_pix_format plane_fmt = {};
+ size_t max_size;
int i;
q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
@@ -710,12 +711,20 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
for (i = 0; i < q_data->fmt->colplanes; i++) {
plane_fmt = q_data->pix_mp.plane_fmt[i];
+ max_size = plane_fmt.sizeimage;
+
if (ctx->enable_exif &&
- q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
- vb2_set_plane_payload(vb, i, plane_fmt.sizeimage +
- MTK_JPEG_MAX_EXIF_SIZE);
- else
- vb2_set_plane_payload(vb, i, plane_fmt.sizeimage);
+ q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
+ max_size += MTK_JPEG_MAX_EXIF_SIZE;
+
+ vb2_set_plane_payload(vb, i,
+ MIN(vb->planes[i].length,
+ max_size));
+ } else {
+ vb2_set_plane_payload(vb, i,
+ MIN(plane_fmt.sizeimage,
+ vb->planes[i].length));
+ }
}
return 0;
--
2.45.2
^ permalink raw reply related
* [PATCH v14 00/12]Enable jpeg enc & dec multi-hardwares for MT8196
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
This series have the follow changing:
Firstly fix some bugs, including resolution change handleing, stop
streaming sw flow, fix buffer layout and clock setting to support multi-hw
jpeg working and others.
Secondly add mt8196 jpegdec and jpegenc compatible to support MT8196
kernel driver.
Lastly, Add smmu setting to support smmu and iommu at the same time.
This series has been tested with MT8196 tast test.
Encoding and decoding worked for this chip.
Patches 1 fix jpeg hw count setting to support different chips.
Patches 2 fix jpeg buffer payload setting to handle buffer
size bug while resolution changed.
Patches 3 fix jpeg dst buffer layout.
Patches 4 fix multi-core stop streaming flow
Patches 5 fix multi-core clk suspend/resume setting
Patches 6 fix decoding buffer number setting timing issue
Patches 7 fix decoding resolution change operation
Patches 8 fix remove buffer operation
Patches 9-11 Adds jpeg encoder and decoder compatible.
Patches 12 add jpeg smmu sid setting.
---
Changes compared with v13:
--Rebased on top of the latest media tree
Changes compared with v12:
--Rebased on top of the latest media tree
--fix kernel rebot build warnings in patch 5
Changes compared with v11:
--Rebased on top of the latest media tree
--Some modifications for patch v11's review comments.
--add reviewer to commit messages
Changes compared with v10:
--Rebased on top of the latest media tree
--add reviewer to commit messages
Changes compared with v9:
--Rebased on top of the latest media tree
Changes compared with v8:
--Rebased on top of the latest media tree
Changes compared with v7:
--Rebased on top of the latest media tree
Changes compared with v6:
--Rebased on top of the latest media tree
Changes compared with v5:
--reorder the patches set.
--fix commit message of patch 1-8.
Changes compared with v4:
--fix kernel robot build errors for patch 4.
--add reviewer for patch 1 and patch 2.
Changes compared with v3:
--change patch subject of jpeg encoder and decoder compatible.
Changes compared with v2:
--refactor smmu sid setting function interface
--Some modifications for patch v2's review comments.
Changes compared with v1:
--refine jpeg dt-bindings for MT8196
--optimize software code to manage jpeg HW count
--refactor smmu sid setting function interface
--Some modifications for patch v1's review comments.
Kyrie Wu (12):
media: mediatek: jpeg: fix jpeg cores' amounts setting
media: mediatek: jpeg: fix jpeg buffer payload size setting
media: mediatek: jpeg: fix buffer structure size and layout
media: mediatek: jpeg: Fix buffer completion on multi-core streaming
stop
media: mediatek: jpeg: Fix multi-core clk suspend and resume setting
media: mediatek: jpeg: fix decoding buffer number setting timing issue
media: mediatek: jpeg: fix resolution change event handling in decoder
media: mediatek: jpeg: fix remove buffer removal timing for multi-core
media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgdec
compatible
media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgenc
compatible
media: mediatek: jpeg: add jpeg compatible
media: mediatek: jpeg: add jpeg smmu sid setting
.../media/mediatek,mt8195-jpegdec.yaml | 8 +-
.../media/mediatek,mt8195-jpegenc.yaml | 8 +-
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 151 +++++++++++++-----
.../platform/mediatek/jpeg/mtk_jpeg_core.h | 19 ++-
.../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 90 ++++++++++-
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 88 +++++++++-
6 files changed, 308 insertions(+), 56 deletions(-)
--
2.45.2
^ permalink raw reply
* [PATCH v14 07/12] media: mediatek: jpeg: fix resolution change event handling in decoder
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
This patch refines the handling of resolution change events within
JPEG decoder worker. The `mtk_jpeg_set_queue_data` function is now
called to set up queue data before signaling a source change through
`mtk_jpeg_queue_src_chg_event`. By reorganizing these calls, the
patch ensures that necessary queue information is updated prior to
transitioning the context state to `MTK_JPEG_SOURCE_CHANGE`.
A condition is added to exit early if the context is already in the
`MTK_JPEG_SOURCE_CHANGE` state, preventing redundant operations and
improving processing efficiency.
Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 99f3f3b4d081..7e176a91404c 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1736,11 +1736,15 @@ static void mtk_jpegdec_worker(struct work_struct *work)
if (mtk_jpeg_check_resolution_change(ctx,
&jpeg_src_buf->dec_param)) {
- mtk_jpeg_queue_src_chg_event(ctx);
+ mtk_jpeg_set_queue_data(ctx, &jpeg_src_buf->dec_param);
ctx->state = MTK_JPEG_SOURCE_CHANGE;
+ mtk_jpeg_queue_src_chg_event(ctx);
goto getbuf_fail;
}
+ if (ctx->state == MTK_JPEG_SOURCE_CHANGE)
+ goto getbuf_fail;
+
mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
if (ret < 0) {
--
2.45.2
^ permalink raw reply related
* [PATCH v14 03/12] media: mediatek: jpeg: fix buffer structure size and layout
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Updates the `buf_struct_size` in the JPEG driver to use the correct
structure `mtk_jpeg_src_buf` instead of `v4l2_m2m_buffer`, ensuring
proper handling of source buffers. The previous buffer size led to
mismatches and potential issues during video buffer handling.
Moves `frame_num` in the `mtk_jpeg_src_buf` structure to align with
other members appropriately. The first field of the driver-specific
buffer structure must be the subsystem-specificstruct
(vb2_v4l2_buffer in the case of V4L2).
Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 2 +-
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 10d3bfd7ddd5..ef7362feb697 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1092,7 +1092,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
dst_vq->ops = jpeg->variant->qops;
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 6be5cf30dea1..148fd41759b7 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -85,10 +85,10 @@ struct mtk_jpeg_variant {
};
struct mtk_jpeg_src_buf {
- u32 frame_num;
struct vb2_v4l2_buffer b;
struct list_head list;
u32 bs_size;
+ u32 frame_num;
struct mtk_jpeg_dec_param dec_param;
struct mtk_jpeg_ctx *curr_ctx;
--
2.45.2
^ permalink raw reply related
* [PATCH v14 04/12] media: mediatek: jpeg: Fix buffer completion on multi-core streaming stop
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Enhances the Mediatek JPEG driver's stability and reliability by ensuring
that all queued buffers are processed before stopping the streaming in
multi-core environments. It introduces a call to
`vb2_wait_for_all_buffers()` in the `mtk_jpeg_enc_stop_streaming()` and
`mtk_jpeg_dec_stop_streaming()` functions when the `multi_core` variant
is enabled. This change ensures that no buffers are left unprocessed,
preventing potential data loss or corruption during multi-core flow.
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index ef7362feb697..6e5de2680e3a 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -850,8 +850,12 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
{
struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
struct vb2_v4l2_buffer *vb;
+ if (jpeg->variant->multi_core)
+ vb2_wait_for_all_buffers(q);
+
while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
}
@@ -859,6 +863,7 @@ static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
{
struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct mtk_jpeg_dev *jpeg = ctx->jpeg;
struct vb2_v4l2_buffer *vb;
/*
@@ -866,6 +871,9 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
* Before STREAMOFF, we still have to return the old resolution and
* subsampling. Update capture queue when the stream is off.
*/
+ if (jpeg->variant->multi_core)
+ vb2_wait_for_all_buffers(q);
+
if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
V4L2_TYPE_IS_CAPTURE(q->type)) {
struct mtk_jpeg_src_buf *src_buf;
--
2.45.2
^ permalink raw reply related
* [PATCH v14 01/12] media: mediatek: jpeg: fix jpeg cores' amounts setting
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Different ICs have different amounts of cores,
use a variable to set the cores' amounts.
Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 8 ++++----
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h | 2 ++
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 1 +
drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 1 +
4 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 8c684756d5fc..30f684ac9318 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1461,7 +1461,7 @@ static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx)
int i;
spin_lock_irqsave(&jpeg->hw_lock, flags);
- for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
+ for (i = 0; i < jpeg->max_hw_count; i++) {
comp_jpeg = jpeg->enc_hw_dev[i];
if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
hw_id = i;
@@ -1508,7 +1508,7 @@ static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx)
int i;
spin_lock_irqsave(&jpeg->hw_lock, flags);
- for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
+ for (i = 0; i < jpeg->max_hw_count; i++) {
comp_jpeg = jpeg->dec_hw_dev[i];
if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
hw_id = i;
@@ -1591,7 +1591,7 @@ static void mtk_jpegenc_worker(struct work_struct *work)
jpeg_work);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
- for (i = 0; i < MTK_JPEGENC_HW_MAX; i++)
+ for (i = 0; i < jpeg->max_hw_count; i++)
comp_jpeg[i] = jpeg->enc_hw_dev[i];
i = 0;
@@ -1686,7 +1686,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
struct mtk_jpeg_fb fb;
unsigned long flags;
- for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++)
+ for (i = 0; i < jpeg->max_hw_count; i++)
comp_jpeg[i] = jpeg->dec_hw_dev[i];
i = 0;
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 02ed0ed5b736..6be5cf30dea1 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -212,6 +212,7 @@ struct mtk_jpegdec_comp_dev {
* @reg_decbase: jpg decode register base addr
* @dec_hw_dev: jpg decode hardware device
* @hw_index: jpg hw index
+ * @max_hw_count: jpeg hw-core count
*/
struct mtk_jpeg_dev {
struct mutex lock;
@@ -234,6 +235,7 @@ struct mtk_jpeg_dev {
void __iomem *reg_decbase[MTK_JPEGDEC_HW_MAX];
struct mtk_jpegdec_comp_dev *dec_hw_dev[MTK_JPEGDEC_HW_MAX];
atomic_t hw_index;
+ u32 max_hw_count;
};
/**
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 32372781daf5..4534caeb104f 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -664,6 +664,7 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
master_dev->dec_hw_dev[i] = dev;
master_dev->reg_decbase[i] = dev->reg_base;
dev->master_dev = master_dev;
+ master_dev->max_hw_count++;
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index b6f5b2249f1f..2765dafab4ad 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -386,6 +386,7 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
master_dev->enc_hw_dev[i] = dev;
master_dev->reg_encbase[i] = dev->reg_base;
dev->master_dev = master_dev;
+ master_dev->max_hw_count++;
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
--
2.45.2
^ permalink raw reply related
* [PATCH v14 05/12] media: mediatek: jpeg: Fix multi-core clk suspend and resume setting
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
The suspend/resume callback function is defined in the dev_pm_ops
structure, which is defined in platform_driver. For multiple-core
architecture, each hardware driver will register a platform_driver
structure, so it is necessary to add a suspend/resume callback
function for each hardware to support this operation.
Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 28 +++------
.../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 62 +++++++++++++++++--
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 60 ++++++++++++++++--
3 files changed, 121 insertions(+), 29 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 6e5de2680e3a..e85a3d0bd8ac 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1115,6 +1115,9 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
{
int ret;
+ if (jpeg->variant->multi_core)
+ return;
+
ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
jpeg->variant->clks);
if (ret)
@@ -1123,6 +1126,9 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
{
+ if (jpeg->variant->multi_core)
+ return;
+
clk_bulk_disable_unprepare(jpeg->variant->num_clks,
jpeg->variant->clks);
}
@@ -1646,13 +1652,6 @@ static void mtk_jpegenc_worker(struct work_struct *work)
goto enc_end;
}
- ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk);
- if (ret) {
- dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n",
- __func__, __LINE__);
- goto enc_end;
- }
-
v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
@@ -1749,20 +1748,13 @@ static void mtk_jpegdec_worker(struct work_struct *work)
jpeg_dst_buf->frame_num = ctx->total_frame_num;
mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
- ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev);
+ ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
if (ret < 0) {
dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
__func__, __LINE__);
goto dec_end;
}
- ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk);
- if (ret) {
- dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n",
- __func__, __LINE__);
- goto clk_end;
- }
-
v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
@@ -1772,7 +1764,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
&dst_buf->vb2_buf, &fb)) {
dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n",
__func__, __LINE__);
- goto setdst_end;
+ goto set_dst_fail;
}
schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
@@ -1793,9 +1785,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
return;
-setdst_end:
- clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk);
-clk_end:
+set_dst_fail:
pm_runtime_put(comp_jpeg[hw_id]->dev);
dec_end:
v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 4534caeb104f..9a8dbca6af00 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -533,13 +533,12 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work)
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
mtk_jpeg_dec_reset(cjpeg->reg_base);
- clk_disable_unprepare(cjpeg->jdec_clk.clks->clk);
- pm_runtime_put(cjpeg->dev);
cjpeg->hw_state = MTK_JPEG_HW_IDLE;
atomic_inc(&master_jpeg->hw_rdy);
wake_up(&master_jpeg->hw_wq);
v4l2_m2m_buf_done(src_buf, buf_state);
mtk_jpegdec_put_buf(cjpeg);
+ pm_runtime_put(cjpeg->dev);
}
static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
@@ -547,7 +546,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct mtk_jpeg_src_buf *jpeg_src_buf;
enum vb2_buffer_state buf_state;
- struct mtk_jpeg_ctx *ctx;
u32 dec_irq_ret;
u32 irq_status;
int i;
@@ -557,7 +555,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
cancel_delayed_work(&jpeg->job_timeout_work);
- ctx = jpeg->hw_param.curr_ctx;
src_buf = jpeg->hw_param.src_buffer;
dst_buf = jpeg->hw_param.dst_buffer;
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
@@ -580,12 +577,11 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
buf_state = VB2_BUF_STATE_DONE;
v4l2_m2m_buf_done(src_buf, buf_state);
mtk_jpegdec_put_buf(jpeg);
- pm_runtime_put(ctx->jpeg->dev);
- clk_disable_unprepare(jpeg->jdec_clk.clks->clk);
jpeg->hw_state = MTK_JPEG_HW_IDLE;
wake_up(&master_jpeg->hw_wq);
atomic_inc(&master_jpeg->hw_rdy);
+ pm_runtime_put(jpeg->dev);
return IRQ_HANDLED;
}
@@ -668,15 +664,69 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
+ ret = devm_clk_bulk_get(dev->dev,
+ jpegdec_clk->clk_num,
+ jpegdec_clk->clks);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init clk\n");
+ return ret;
+ }
return 0;
}
+static int mtk_jpegdec_pm_suspend(struct device *dev)
+{
+ struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ clk_bulk_disable_unprepare(jpeg->jdec_clk.clk_num,
+ jpeg->jdec_clk.clks);
+
+ return 0;
+}
+
+static int mtk_jpegdec_pm_resume(struct device *dev)
+{
+ struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ return clk_bulk_prepare_enable(jpeg->jdec_clk.clk_num,
+ jpeg->jdec_clk.clks);
+}
+
+static int mtk_jpegdec_suspend(struct device *dev)
+{
+ struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ v4l2_m2m_suspend(jpeg->master_dev->m2m_dev);
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int mtk_jpegdec_resume(struct device *dev)
+{
+ struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+ int ret;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret < 0)
+ return ret;
+
+ v4l2_m2m_resume(jpeg->master_dev->m2m_dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mtk_jpegdec_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(mtk_jpegdec_suspend, mtk_jpegdec_resume)
+ RUNTIME_PM_OPS(mtk_jpegdec_pm_suspend, mtk_jpegdec_pm_resume, NULL)
+};
+
static struct platform_driver mtk_jpegdec_hw_driver = {
.probe = mtk_jpegdec_hw_probe,
.driver = {
.name = "mtk-jpegdec-hw",
.of_match_table = mtk_jpegdec_hw_ids,
+ .pm = &mtk_jpegdec_pm_ops,
},
};
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index 2765dafab4ad..5d1c217fea0f 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -264,13 +264,12 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work)
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
mtk_jpeg_enc_reset(cjpeg->reg_base);
- clk_disable_unprepare(cjpeg->venc_clk.clks->clk);
- pm_runtime_put(cjpeg->dev);
cjpeg->hw_state = MTK_JPEG_HW_IDLE;
atomic_inc(&master_jpeg->hw_rdy);
wake_up(&master_jpeg->hw_wq);
v4l2_m2m_buf_done(src_buf, buf_state);
mtk_jpegenc_put_buf(cjpeg);
+ pm_runtime_put(cjpeg->dev);
}
static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
@@ -304,12 +303,11 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
buf_state = VB2_BUF_STATE_DONE;
v4l2_m2m_buf_done(src_buf, buf_state);
mtk_jpegenc_put_buf(jpeg);
- pm_runtime_put(ctx->jpeg->dev);
- clk_disable_unprepare(jpeg->venc_clk.clks->clk);
jpeg->hw_state = MTK_JPEG_HW_IDLE;
wake_up(&master_jpeg->hw_wq);
atomic_inc(&master_jpeg->hw_rdy);
+ pm_runtime_put(jpeg->dev);
return IRQ_HANDLED;
}
@@ -390,15 +388,69 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
+ ret = devm_clk_bulk_get(dev->dev,
+ jpegenc_clk->clk_num,
+ jpegenc_clk->clks);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init clk\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mtk_jpegenc_pm_suspend(struct device *dev)
+{
+ struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ clk_bulk_disable_unprepare(jpeg->venc_clk.clk_num,
+ jpeg->venc_clk.clks);
return 0;
}
+static int mtk_jpegenc_pm_resume(struct device *dev)
+{
+ struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ return clk_bulk_prepare_enable(jpeg->venc_clk.clk_num,
+ jpeg->venc_clk.clks);
+}
+
+static int mtk_jpegenc_suspend(struct device *dev)
+{
+ struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+ v4l2_m2m_suspend(jpeg->master_dev->m2m_dev);
+
+ return pm_runtime_force_suspend(dev);
+}
+
+static int mtk_jpegenc_resume(struct device *dev)
+{
+ struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+ int ret;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret < 0)
+ return ret;
+
+ v4l2_m2m_resume(jpeg->master_dev->m2m_dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mtk_jpegenc_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(mtk_jpegenc_suspend, mtk_jpegenc_resume)
+ RUNTIME_PM_OPS(mtk_jpegenc_pm_suspend, mtk_jpegenc_pm_resume, NULL)
+};
+
static struct platform_driver mtk_jpegenc_hw_driver = {
.probe = mtk_jpegenc_hw_probe,
.driver = {
.name = "mtk-jpegenc-hw",
.of_match_table = mtk_jpegenc_drv_ids,
+ .pm = &mtk_jpegenc_pm_ops,
},
};
--
2.45.2
^ permalink raw reply related
* [PATCH v14 08/12] media: mediatek: jpeg: fix remove buffer removal timing for multi-core
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Move calls to v4l2_m2m_src/dst_buf_remove() inside of the spinlock
protected scope to ensure all necessary operations are performed
before buffers are removed from their queues and ensure proper
synchronization of buffer handling to avoid buffer lost.
Fixes: 86379bd9d399 ("media: mtk-jpeg: Fixes jpeg enc&dec worker sw flow")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 7e176a91404c..a5b0f7620121 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1652,9 +1652,6 @@ static void mtk_jpegenc_worker(struct work_struct *work)
goto enc_end;
}
- v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
@@ -1672,6 +1669,8 @@ static void mtk_jpegenc_worker(struct work_struct *work)
&src_buf->vb2_buf);
mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base);
mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base);
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
@@ -1753,9 +1752,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
goto dec_end;
}
- v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
if (mtk_jpeg_set_dec_dst(ctx,
&jpeg_src_buf->dec_param,
@@ -1780,6 +1776,8 @@ static void mtk_jpegdec_worker(struct work_struct *work)
jpeg_src_buf->bs_size,
&bs,
&fb);
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base);
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
--
2.45.2
^ permalink raw reply related
* [PATCH v14 09/12] media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgdec compatible
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Krzysztof Kozlowski
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Compared to the previous generation IC, the MT8196 uses SMMU
instead of IOMMU and supports features such as dynamic voltage
and frequency scaling. Therefore, add "mediatek,mt8196-jpgdec"
compatible to the binding document.
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
.../bindings/media/mediatek,mt8195-jpegdec.yaml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegdec.yaml b/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegdec.yaml
index e5448c60e3eb..28a9a9bfdbf8 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegdec.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegdec.yaml
@@ -14,7 +14,9 @@ description:
properties:
compatible:
- const: mediatek,mt8195-jpgdec
+ enum:
+ - mediatek,mt8195-jpgdec
+ - mediatek,mt8196-jpgdec
power-domains:
maxItems: 1
@@ -44,7 +46,9 @@ patternProperties:
properties:
compatible:
- const: mediatek,mt8195-jpgdec-hw
+ enum:
+ - mediatek,mt8195-jpgdec-hw
+ - mediatek,mt8196-jpgdec-hw
reg:
maxItems: 1
--
2.45.2
^ permalink raw reply related
* [PATCH v14 12/12] media: mediatek: jpeg: add jpeg smmu sid setting
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Add a configuration to set jpeg dec & enc smmu sid
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 29 +++++++++++++++++++
.../platform/mediatek/jpeg/mtk_jpeg_core.h | 15 ++++++++++
.../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 23 +++++++++++++++
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 23 +++++++++++++++
4 files changed, 90 insertions(+)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 8bd52ca03e9f..30fc1feb42ad 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -15,6 +15,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <media/v4l2-event.h>
@@ -1600,6 +1601,22 @@ static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
return IRQ_HANDLED;
}
+static void mtk_jpeg_set_smmu_sid(struct regmap *smmu_regmap, unsigned int sid)
+{
+ if (sid == JPG_REG_GUSER_ID_DEC_SID)
+ regmap_update_bits(smmu_regmap, JPEG_DEC_SMMU_SID,
+ JPG_REG_GUSER_ID_MASK <<
+ JPG_REG_DEC_GUSER_ID_SHIFT,
+ JPG_REG_GUSER_ID_DEC_SID <<
+ JPG_REG_DEC_GUSER_ID_SHIFT);
+ else
+ regmap_update_bits(smmu_regmap, JPEG_ENC_SMMU_SID,
+ JPG_REG_GUSER_ID_MASK <<
+ JPG_REG_ENC_GUSER_ID_SHIFT,
+ JPG_REG_GUSER_ID_ENC_SID <<
+ JPG_REG_ENC_GUSER_ID_SHIFT);
+}
+
static void mtk_jpegenc_worker(struct work_struct *work)
{
struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX];
@@ -1661,6 +1678,11 @@ static void mtk_jpegenc_worker(struct work_struct *work)
jpeg_dst_buf->frame_num = ctx->total_frame_num;
ctx->total_frame_num++;
mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base);
+
+ if (jpeg->variant->support_smmu && comp_jpeg[hw_id]->smmu_regmap)
+ mtk_jpeg_set_smmu_sid(comp_jpeg[hw_id]->smmu_regmap,
+ JPG_REG_GUSER_ID_ENC_SID);
+
mtk_jpeg_set_enc_dst(ctx,
comp_jpeg[hw_id]->reg_base,
&dst_buf->vb2_buf);
@@ -1770,6 +1792,11 @@ static void mtk_jpegdec_worker(struct work_struct *work)
jpeg_dst_buf->frame_num = ctx->total_frame_num;
ctx->total_frame_num++;
mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
+
+ if (jpeg->variant->support_smmu && comp_jpeg[hw_id]->smmu_regmap)
+ mtk_jpeg_set_smmu_sid(comp_jpeg[hw_id]->smmu_regmap,
+ JPG_REG_GUSER_ID_DEC_SID);
+
mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base,
jpeg->variant->support_34bit,
&jpeg_src_buf->dec_param,
@@ -1928,6 +1955,7 @@ static struct mtk_jpeg_variant mtk8196_jpegenc_drvdata = {
.cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
.multi_core = true,
.jpeg_worker = mtk_jpegenc_worker,
+ .support_smmu = true,
};
static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
@@ -1954,6 +1982,7 @@ static const struct mtk_jpeg_variant mtk8196_jpegdec_drvdata = {
.cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
.multi_core = true,
.jpeg_worker = mtk_jpegdec_worker,
+ .support_smmu = true,
};
static const struct of_device_id mtk_jpeg_match[] = {
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 148fd41759b7..186cd1862028 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fh.h>
@@ -34,6 +35,14 @@
#define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024)
+#define JPEG_DEC_SMMU_SID 0
+#define JPEG_ENC_SMMU_SID 0
+#define JPG_REG_GUSER_ID_MASK 0x7
+#define JPG_REG_GUSER_ID_DEC_SID 0x4
+#define JPG_REG_GUSER_ID_ENC_SID 0x5
+#define JPG_REG_DEC_GUSER_ID_SHIFT 8
+#define JPG_REG_ENC_GUSER_ID_SHIFT 4
+
#define MTK_JPEG_ADDR_MASK GENMASK(1, 0)
/**
@@ -65,6 +74,7 @@ enum mtk_jpeg_ctx_state {
* @multi_core: mark jpeg hw is multi_core or not
* @jpeg_worker: jpeg dec or enc worker
* @support_34bit: flag to check support for 34-bit DMA address
+ * @support_smmu: flag to check if support smmu
*/
struct mtk_jpeg_variant {
struct clk_bulk_data *clks;
@@ -82,6 +92,7 @@ struct mtk_jpeg_variant {
bool multi_core;
void (*jpeg_worker)(struct work_struct *work);
bool support_34bit;
+ bool support_smmu;
};
struct mtk_jpeg_src_buf {
@@ -150,6 +161,7 @@ struct mtk_jpegdec_clk {
* @hw_param: jpeg encode hw parameters
* @hw_state: record hw state
* @hw_lock: spinlock protecting the hw device resource
+ * @smmu_regmap: SMMU registers mapping
*/
struct mtk_jpegenc_comp_dev {
struct device *dev;
@@ -163,6 +175,7 @@ struct mtk_jpegenc_comp_dev {
enum mtk_jpeg_hw_state hw_state;
/* spinlock protecting the hw device resource */
spinlock_t hw_lock;
+ struct regmap *smmu_regmap;
};
/**
@@ -177,6 +190,7 @@ struct mtk_jpegenc_comp_dev {
* @hw_param: jpeg decode hw parameters
* @hw_state: record hw state
* @hw_lock: spinlock protecting hw
+ * @smmu_regmap: SMMU registers mapping
*/
struct mtk_jpegdec_comp_dev {
struct device *dev;
@@ -190,6 +204,7 @@ struct mtk_jpegdec_comp_dev {
enum mtk_jpeg_hw_state hw_state;
/* spinlock protecting the hw device resource */
spinlock_t hw_lock;
+ struct regmap *smmu_regmap;
};
/**
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 5a485e905787..2e079a6e5d5d 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -613,6 +613,25 @@ static int mtk_jpegdec_hw_init_irq(struct mtk_jpegdec_comp_dev *dev)
return 0;
}
+static int mtk_jpegdec_smmu_init(struct mtk_jpegdec_comp_dev *dev)
+{
+ struct mtk_jpeg_dev *master_dev = dev->master_dev;
+
+ if (!master_dev->variant->support_smmu)
+ return 0;
+
+ dev->smmu_regmap =
+ syscon_regmap_lookup_by_phandle(dev->plat_dev->dev.of_node,
+ "mediatek,smmu-config");
+ if (IS_ERR(dev->smmu_regmap)) {
+ return dev_err_probe(dev->dev, PTR_ERR(dev->smmu_regmap),
+ "mmap smmu_base failed(%ld)\n",
+ PTR_ERR(dev->smmu_regmap));
+ }
+
+ return 0;
+}
+
static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
{
struct mtk_jpegdec_clk *jpegdec_clk;
@@ -666,6 +685,10 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
dev->master_dev = master_dev;
master_dev->max_hw_count++;
+ ret = mtk_jpegdec_smmu_init(dev);
+ if (ret)
+ return ret;
+
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
ret = devm_clk_bulk_get(dev->dev,
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index 1cfdfac98829..0001d69ae7ba 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -339,6 +339,25 @@ static int mtk_jpegenc_hw_init_irq(struct mtk_jpegenc_comp_dev *dev)
return 0;
}
+static int mtk_jpegenc_smmu_init(struct mtk_jpegenc_comp_dev *dev)
+{
+ struct mtk_jpeg_dev *master_dev = dev->master_dev;
+
+ if (!master_dev->variant->support_smmu)
+ return 0;
+
+ dev->smmu_regmap =
+ syscon_regmap_lookup_by_phandle(dev->plat_dev->dev.of_node,
+ "mediatek,smmu-config");
+ if (IS_ERR(dev->smmu_regmap)) {
+ return dev_err_probe(dev->dev, PTR_ERR(dev->smmu_regmap),
+ "mmap smmu_base failed(%ld)\n",
+ PTR_ERR(dev->smmu_regmap));
+ }
+
+ return 0;
+}
+
static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
{
struct mtk_jpegenc_clk *jpegenc_clk;
@@ -390,6 +409,10 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
dev->master_dev = master_dev;
master_dev->max_hw_count++;
+ ret = mtk_jpegenc_smmu_init(dev);
+ if (ret)
+ return ret;
+
platform_set_drvdata(pdev, dev);
pm_runtime_enable(&pdev->dev);
ret = devm_clk_bulk_get(dev->dev,
--
2.45.2
^ permalink raw reply related
* [PATCH v14 06/12] media: mediatek: jpeg: fix decoding buffer number setting timing issue
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
The src buffer doesn't need set information and dst buf parameters
only need to set when the power set succussed and protect the
setting by spinlock ensuring that any later operations acting
on this buffer reflect accurate state and frame data.
Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 9 +++------
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 1 +
drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 1 +
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index e85a3d0bd8ac..99f3f3b4d081 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1733,7 +1733,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
- jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
if (mtk_jpeg_check_resolution_change(ctx,
&jpeg_src_buf->dec_param)) {
@@ -1742,11 +1741,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
goto getbuf_fail;
}
- jpeg_src_buf->curr_ctx = ctx;
- jpeg_src_buf->frame_num = ctx->total_frame_num;
- jpeg_dst_buf->curr_ctx = ctx;
- jpeg_dst_buf->frame_num = ctx->total_frame_num;
-
mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
if (ret < 0) {
@@ -1771,6 +1765,9 @@ static void mtk_jpegdec_worker(struct work_struct *work)
msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
+ jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
+ jpeg_dst_buf->curr_ctx = ctx;
+ jpeg_dst_buf->frame_num = ctx->total_frame_num;
ctx->total_frame_num++;
mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base,
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 9a8dbca6af00..e4d2c5d4ec73 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -513,6 +513,7 @@ static void mtk_jpegdec_put_buf(struct mtk_jpegdec_comp_dev *jpeg)
v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
VB2_BUF_STATE_DONE);
ctx->last_done_frame_num++;
+ break;
}
}
}
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index 5d1c217fea0f..2adea3aca50b 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -242,6 +242,7 @@ static void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg)
v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
VB2_BUF_STATE_DONE);
ctx->last_done_frame_num++;
+ break;
}
}
}
--
2.45.2
^ permalink raw reply related
* [PATCH v14 11/12] media: mediatek: jpeg: add jpeg compatible
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Add jpeg dec and enc compatible for mt8196
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 34 +++++++++++++++++++
.../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 3 ++
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 3 ++
3 files changed, 40 insertions(+)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index a5b0f7620121..8bd52ca03e9f 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1917,6 +1917,19 @@ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
.jpeg_worker = mtk_jpegenc_worker,
};
+static struct mtk_jpeg_variant mtk8196_jpegenc_drvdata = {
+ .formats = mtk_jpeg_enc_formats,
+ .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
+ .qops = &mtk_jpeg_enc_qops,
+ .m2m_ops = &mtk_jpeg_multicore_enc_m2m_ops,
+ .dev_name = "mtk-jpeg-enc",
+ .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
+ .multi_core = true,
+ .jpeg_worker = mtk_jpegenc_worker,
+};
+
static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
.formats = mtk_jpeg_dec_formats,
.num_formats = MTK_JPEG_DEC_NUM_FORMATS,
@@ -1930,6 +1943,19 @@ static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = {
.jpeg_worker = mtk_jpegdec_worker,
};
+static const struct mtk_jpeg_variant mtk8196_jpegdec_drvdata = {
+ .formats = mtk_jpeg_dec_formats,
+ .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
+ .qops = &mtk_jpeg_dec_qops,
+ .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops,
+ .dev_name = "mtk-jpeg-dec",
+ .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
+ .multi_core = true,
+ .jpeg_worker = mtk_jpegdec_worker,
+};
+
static const struct of_device_id mtk_jpeg_match[] = {
{
.compatible = "mediatek,mt8173-jpgdec",
@@ -1951,6 +1977,14 @@ static const struct of_device_id mtk_jpeg_match[] = {
.compatible = "mediatek,mt8195-jpgdec",
.data = &mtk8195_jpegdec_drvdata,
},
+ {
+ .compatible = "mediatek,mt8196-jpgenc",
+ .data = &mtk8196_jpegenc_drvdata,
+ },
+ {
+ .compatible = "mediatek,mt8196-jpgdec",
+ .data = &mtk8196_jpegdec_drvdata,
+ },
{},
};
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index e4d2c5d4ec73..5a485e905787 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -45,6 +45,9 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = {
{
.compatible = "mediatek,mt8195-jpgdec-hw",
},
+ {
+ .compatible = "mediatek,mt8196-jpgdec-hw",
+ },
{},
};
MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids);
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index 2adea3aca50b..1cfdfac98829 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -52,6 +52,9 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = {
{
.compatible = "mediatek,mt8195-jpgenc-hw",
},
+ {
+ .compatible = "mediatek,mt8196-jpgenc-hw",
+ },
{},
};
MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids);
--
2.45.2
^ permalink raw reply related
* [PATCH v14 10/12] media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgenc compatible
From: Kyrie Wu @ 2026-04-23 9:46 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Nicolas Dufresne, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Kyrie Wu,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
Cc: Krzysztof Kozlowski
In-Reply-To: <20260423094656.32044-1-kyrie.wu@mediatek.com>
Compared to the previous generation IC, the MT8196 uses SMMU
instead of IOMMU and supports features such as dynamic voltage
and frequency scaling. Therefore, add "mediatek,mt8196-jpgenc"
compatible to the binding document.
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
.../bindings/media/mediatek,mt8195-jpegenc.yaml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegenc.yaml b/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegenc.yaml
index 596186497b68..e2d772ea0fb0 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegenc.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mt8195-jpegenc.yaml
@@ -14,7 +14,9 @@ description:
properties:
compatible:
- const: mediatek,mt8195-jpgenc
+ enum:
+ - mediatek,mt8195-jpgenc
+ - mediatek,mt8196-jpgenc
power-domains:
maxItems: 1
@@ -44,7 +46,9 @@ patternProperties:
properties:
compatible:
- const: mediatek,mt8195-jpgenc-hw
+ enum:
+ - mediatek,mt8195-jpgenc-hw
+ - mediatek,mt8196-jpgenc-hw
reg:
maxItems: 1
--
2.45.2
^ permalink raw reply related
* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Will Deacon @ 2026-04-23 9:47 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel, Nicolin Chen,
Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <aenp6FHzx9rtUQkZ@willie-the-truck>
On Thu, Apr 23, 2026 at 10:44:08AM +0100, Will Deacon wrote:
> On Wed, Apr 22, 2026 at 01:23:51PM -0300, Jason Gunthorpe wrote:
> > On Wed, Apr 22, 2026 at 06:44:31AM +0000, Evangelos Petrongonas wrote:
> > > The motivation is live update of the hypervisor: we want to kexec into a
> > > new kernel while keeping DMA from passthrough devices flowing, which
> > > means the SMMU's translation state has to survive the handover. The Live
> > > Update Orchestrator work [1] and the in-progress "iommu: Add live
> > > update state preservation" series [2] are building exactly this plumbing
> > > on top of KHO; [2]'s cover letter calls out Arm SMMUv3 support as future
> > > work, and an earlier RFC from Amazon [3] sketched the same idea for
> > > iommufd.
> >
> > It would be appropriate to keep this patch with the rest of that out
> > of tree pile, for example in the series that enables s2 only support
> > in smmuv3.
> >
> > > For this use case, Stage 2 is materially easier to persist than Stage 1,
> > > for structural rather than performance reasons:
> >
> > I don't think so. The driver needs to know each and every STE that
> > will survive KHO. The ones that don't survive need to be reset to
> > abort STEs. From that point it is trivial enough to include the CD
> > memory in the preservation.
> >
> > It would help to send a preparation series to switch the ARM STE and
> > CD logic away from dma_alloc_coherent and use iommu-pages instead,
> > since we only expect iommu-pages to support preservation..
>
> Does iommu-pages provide a mechanism to map the memory as non-cacheable
> if the SMMU isn't coherent? I really don't want to entertain CMOs for
> the queues.
Sorry, I said "queues" here but I was really referring to any of the
current dma_alloc_coherent() allocations and it's the CDs that matter
in this thread.
The rationale being that:
1. A cacheable mapping is going to pollute the cache unnecessarily.
2. Reasoning about atomicity and ordering is a lot more subtle with CMOs.
3. It seems like a pretty invasive driver change to support live update,
which isn't relevant for a lot of systems.
Will
^ permalink raw reply
* Re: [PATCH] KVM: arm64: Validate the FF-A memory access descriptor placement
From: Sudeep Holla @ 2026-04-23 9:55 UTC (permalink / raw)
To: Sebastian Ene
Cc: Marc Zyngier, oupton, will, ayrton, catalin.marinas, joey.gouly,
Sudeep Holla, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, suzuki.poulose,
yuzenghui, stable
In-Reply-To: <aenjvY5VJxFye52e@google.com>
On Thu, Apr 23, 2026 at 09:17:49AM +0000, Sebastian Ene wrote:
> On Wed, Apr 22, 2026 at 08:29:06PM +0100, Sudeep Holla wrote:
[...]
> Hello Sudeep,
>
> > That's just the current choice in the driver and can be changed in the future.
> >
> > > and makes use of the same assumption in: ffa_mem_desc_offset().
> > > https://elixir.bootlin.com/linux/v7.0/source/include/linux/arm_ffa.h#L448
> >
> > Again this is just in the transmit path of the message the driver is
> > constructing and hence it is a simple choice rather than wrong assumption.
> >
> > > The later one seems wrong IMO. because we should compute the offset
> > > based on the value stored in ep_mem_offset and not adding it up with
> > > sizeof(struct ffa_mem_region).
> > >
> >
> > Sorry what am I missing as the driver is building these descriptors to
> > send it across to SPMC, we are populating the field and it will be 0
> > before it is initialised
>
> Right, what I meant is having something like this since this function is not limited
> to the driver scope and using it from other components would imply relying on the
> assumption: 'ep_mem_offset == sizeof(struct ffa_mem_region)'. We will also have to validate
> that the `ep_mem_offset` doesn't point outside of the mailbox designated buffer.
>
Sure, we can extend the function itself or add addition helper to get the
functionality you are looking for the validation.
> ---
> diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
> index 81e603839c4a..62d67dae8b70 100644
> --- a/include/linux/arm_ffa.h
> +++ b/include/linux/arm_ffa.h
> @@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
> if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
> offset += offsetof(struct ffa_mem_region, ep_mem_offset);
> else
> - offset += sizeof(struct ffa_mem_region);
> + offset += buf->ep_mem_offset;
>
> return offset;
> }
> ---
>
> And then move `ffa_mem_region_additional_setup` to be called earlier before `ffa_mem_desc_offset`:
> (so that it can setup the value for ep_mem_offset)
>
> ---
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index f2f94d4d533e..66de59c88aff 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -691,6 +691,8 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
> mem_region->flags = args->flags;
> mem_region->sender_id = drv_info->vm_id;
> mem_region->attributes = ffa_memory_attributes_get(func_id);
> +
> + ffa_mem_region_additional_setup(drv_info->version, mem_region);
Ah this could do the trick. I need to check if all the usages are covered
though.
> composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
> drv_info->version);
>
> @@ -708,7 +710,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
> }
> mem_region->handle = 0;
> mem_region->ep_count = args->nattrs;
> - ffa_mem_region_additional_setup(drv_info->version, mem_region);
> ---
>
> >
> > > Maybe this should be the fix instead and not the one in pKVM ? What do
> > > you think ?
> > >
> >
> > Can you share the diff you have in mind to understand your concern better
> > or are you referring to this patch itself.
>
> Sure, please let me know if you think this is wrong. I might have misunderstood it.
>
Nope, the patch helped to understand it quicker. Thanks for that.
> >
> > > The current implementation in pKVM makes use of the
> > > ffa_mem_desc_offset() to validate the first EMAD. If a compromised host
> > > places an EMAD at a different offset than sizeof(struct ffa_mem_region),
> > > then pKVM will not validate that EMAD.
> > >
> >
> > Calling the host as compromised if it chooses a different offset seems bit
> > of extreme here. I am no sure if I am missing to understand something here.
> >
>
> Sorry for not explaining it, in pKVM model we don't trust the host kernel so
> we can assume that everything that doesn't pass the hypervisor validation(in
> this case the ff-a memory transaction) can be a potential attack that wants
> to compromise EL2.
>
I am aware of the principle in general, but this example with different offset
can't be assumed as comprised host if the offset + size is well within the
Tx buffer size boundaries. That should be the way for you to cross check for
any compromise IHMO.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH v2] iommu/arm-smmu-qcom: Fix fastrpc compatible string in ACTLR client match table
From: bibek.patro @ 2026-04-23 10:02 UTC (permalink / raw)
To: Rob Clark, Will Deacon, Robin Murphy, Joerg Roedel
Cc: Dmitry Baryshkov, iommu, linux-arm-msm, linux-arm-kernel,
linux-kernel, srinivas.kandagatla, Bibek Kumar Patro,
Dmitry Baryshkov, Shawn Guo
From: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
The qcom_smmu_actlr_client_of_match table contained "qcom,fastrpc" as
the compatible string for applying ACTLR prefetch settings to FastRPC
devices. However, "qcom,fastrpc" is the compatible string for the parent
rpmsg channel node, which is not an IOMMU client — it carries no
"iommus" property in the device tree and is never attached to an SMMU
context bank.
The actual IOMMU clients are the compute context bank (CB) child nodes,
which use the compatible string "qcom,fastrpc-compute-cb". These nodes
carry the "iommus" property and are probed by fastrpc_cb_driver via
fastrpc_cb_probe(), which sets up the DMA mask and IOMMU mappings for
each FastRPC session. The device tree structure is:
fastrpc {
compatible = "qcom,fastrpc"; /* rpmsg channel, no iommus */
...
compute-cb@3 {
compatible = "qcom,fastrpc-compute-cb";
iommus = <&apps_smmu 0x1823 0x0>; /* actual IOMMU client */
};
};
Since qcom_smmu_set_actlr_dev() calls of_match_device() against the
device being attached to the SMMU context bank, the "qcom,fastrpc"
entry was never matching any device. As a result, the ACTLR prefetch
settings (PREFETCH_DEEP | CPRE | CMTLB) were silently never applied
for FastRPC compute context banks.
Fix this by replacing "qcom,fastrpc" with "qcom,fastrpc-compute-cb"
in the match table so that the ACTLR settings are correctly applied
to the compute CB devices that are the true IOMMU clients.
Assisted-by: Claude:claude-sonnet-4-6
Fixes: 3e35c3e725de ("iommu/arm-smmu: Add ACTLR data and support for qcom_smmu_500")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
---
While there is an ongoing discussion [1] on how to differentiate ACTLR
prefetch settings between compute DSP and audio DSP fastrpc devices, it
is necessary to first fix the compatible string to
"qcom,fastrpc-compute-cb".
Both compute DSP and audio DSP fastrpc nodes use this compatible string,
so both will receive the ACTLR settings after this fix. However, for
audio DSP devices the effect remains the same as the current
state since they do not actively use prefetch — the write is effectively
a NOP for them. The fix is meaningful for compute DSP devices, which
actively use prefetch and were previously being silently skipped.
[1]:
https://lore.kernel.org/all/9b4c895a-c822-40e6-bb92-8fdcd09c82d3@oss.qualcomm.com/
v1->v2:
- Collect "Reviewed-by" tags.
- Address nit on "Assisted-by" tags format.
- [v1]:
https://lore.kernel.org/all/20260408130825.3268733-1-bibek.patro@oss.qualcomm.com/
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index edd41b5a3b6a..2d006049dd61 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -39,7 +39,7 @@ static const struct of_device_id qcom_smmu_actlr_client_of_match[] = {
.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
{ .compatible = "qcom,adreno-smmu",
.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
- { .compatible = "qcom,fastrpc",
+ { .compatible = "qcom,fastrpc-compute-cb",
.data = (const void *) (PREFETCH_DEEP | CPRE | CMTLB) },
{ .compatible = "qcom,qcm2290-mdss",
.data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) },
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Thomas Gleixner @ 2026-04-23 10:08 UTC (permalink / raw)
To: Catalin Marinas, Jinjie Ruan
Cc: peterz, sudeep.holla, yangyicong, dietmar.eggemann,
Jonathan.Cameron, linux-kernel, James Morse, linux-arm-kernel
In-Reply-To: <aeNxKpHzTQX4_kId@arm.com>
On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
> Another option would have been to avoid marking such CPUs present but I
> think this will break other things. Yet another option is to register
> all CPU devices even if they never come up (like maxcpus greater than
> actual CPUs).
>
> Opinions? It might be an arm64+ACPI-only thing.
I think so. The proper thing to do is to apply sane limits:
1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
2) The maxcpus limit on the command line N_MAXCPUS_CL
So the actual possible CPUs evaluates to:
num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
The evaluation of the firmware should not mark CPUs present which are
actually not. ACPI gives you that information. See:
5.2.12.14 GIC CPU Interface (GICC) Structure
in the ACPI spec. That has two related bits:
Enabled:
If this bit is set, the processor is ready for use. If this bit is
clear and the Online Capable bit is set, the system supports enabling
this processor during OS runtime. If this bit is clear and the Online
Capable bit is also clear, this processor is un- usable, and the
operating system support will not attempt to use it.
Online Capable:
The information conveyed by this bit depends on the value of the
Enabled bit. If the Enabled bit is set, this bit is reserved and must
be zero. Otherwise, if this bit is set, the system supports enabling
this processor later during OS runtime
So the combination of those gives you the right answer:
Enabled Online
Capable
0 0 Not present, not possible
0 1 Not present, but possible to "hotplug" layter
1 0 Present
1 1 Invalid
The kernel sizes everything on the number of possible CPUs and the
present CPU mask is only there to figure out which CPUs are actually
usable and can be brought up.
The runtime physical hotplug mechanics use acpi_[un]map_cpu() to toggle
the present bit.
Thanks,
tglx
^ permalink raw reply
* Re: [RFC PATCH v2 2/4] tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in
From: Jarkko Sakkinen @ 2026-04-23 10:17 UTC (permalink / raw)
To: Yeoreum Yun
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg, jgg, sudeep.holla,
maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, noodles, sebastianene
In-Reply-To: <20260422162449.1814615-3-yeoreum.yun@arm.com>
On Wed, Apr 22, 2026 at 05:24:47PM +0100, Yeoreum Yun wrote:
> commit 746d9e9f62a6 ("tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's build_in")
> probe tpm_crb_ffa forcefully when it's built-in to integrate with IMA.
>
> However, as IMA init function is changed to late_initcall_sync level.
> So, this change isn't required anymore.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
> drivers/char/tpm/tpm_crb_ffa.c | 18 +++---------------
> 1 file changed, 3 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c
> index 99f1c1e5644b..025c4d4b17ca 100644
> --- a/drivers/char/tpm/tpm_crb_ffa.c
> +++ b/drivers/char/tpm/tpm_crb_ffa.c
> @@ -177,23 +177,13 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
> */
> int tpm_crb_ffa_init(void)
> {
> - int ret = 0;
> -
> - if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
> - ret = ffa_register(&tpm_crb_ffa_driver);
> - if (ret) {
> - tpm_crb_ffa = ERR_PTR(-ENODEV);
> - return ret;
> - }
> - }
> -
> if (!tpm_crb_ffa)
> - ret = -ENOENT;
> + return -ENOENT;
>
> if (IS_ERR_VALUE(tpm_crb_ffa))
> - ret = -ENODEV;
> + return -ENODEV;
>
> - return ret;
> + return 0;
> }
> EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
>
> @@ -405,9 +395,7 @@ static struct ffa_driver tpm_crb_ffa_driver = {
> .id_table = tpm_crb_ffa_device_id,
> };
>
> -#ifdef MODULE
> module_ffa_driver(tpm_crb_ffa_driver);
> -#endif
>
> MODULE_AUTHOR("Arm");
> MODULE_DESCRIPTION("TPM CRB FFA driver");
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>
I'll hold review to next version i.e. after Mimi's concerns
have been addressed.
BR, Jarkko
^ permalink raw reply
* Re: [PATCH 1/4] arm64: dts: imx8mp: switch usb controller to flattened model
From: Xu Yang @ 2026-04-23 10:20 UTC (permalink / raw)
To: Frank Li
Cc: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, devicetree,
imx, linux-arm-kernel, linux-kernel, jun.li
In-Reply-To: <aehEXEsiFl2PVIye@lizhi-Precision-Tower-5810>
On Tue, Apr 21, 2026 at 11:45:32PM -0400, Frank Li wrote:
> On Tue, Apr 21, 2026 at 06:55:00PM +0800, Xu Yang wrote:
> > Switch to use flattened model for all USB controllers. To enable USB
> > controllers with restricted DMA access range to work correctly, add a
> > pseudo simple-bus to constrain the dma address.
>
> This should not "pseudo", and bus is physical existed, which limited dma
> range since it transparent to SW, which may not mention in spec.
OK. Will remove the word "pseudo" in v2.
>
> >
> > Also reorder USB-related nodes.
>
> this need new patch to just do reorder.
OK. Will add a separate patch.
Thanks,
Xu Yang
^ permalink raw reply
* Re: [PATCH v3 4/8] thermal: amlogic: Add support for secure monitor calibration readout
From: Daniel Lezcano @ 2026-04-23 10:25 UTC (permalink / raw)
To: Ronald Claveau, Guillaume La Roque, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl
Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260421-add-thermal-t7-vim4-v3-4-a2e7215ed003@aliel.fr>
Hi Ronald,
On 4/21/26 09:19, Ronald Claveau wrote:
> Some SoCs (e.g. T7) expose thermal calibration data through the secure
> monitor rather than a directly accessible eFuse register. Add a use_sm
> flag to amlogic_thermal_data to select this path, and retrieve the
> firmware handle and tsensor_id from the "amlogic,secure-monitor" DT
> phandle with one fixed argument.
>
> Also introduce the amlogic,t7-thermal compatible using this new path.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> drivers/thermal/amlogic_thermal.c | 58 +++++++++++++++++++++++++++++++++++----
> 1 file changed, 53 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c
> index 5448d772db12a..11e3948cc0669 100644
> --- a/drivers/thermal/amlogic_thermal.c
> +++ b/drivers/thermal/amlogic_thermal.c
> @@ -25,6 +25,7 @@
> #include <linux/platform_device.h>
> #include <linux/regmap.h>
> #include <linux/thermal.h>
> +#include <linux/firmware/meson/meson_sm.h>
>
> #include "thermal_hwmon.h"
>
> @@ -84,12 +85,14 @@ struct amlogic_thermal_soc_calib_data {
> * @u_efuse_off: register offset to read fused calibration value
> * @calibration_parameters: calibration parameters structure pointer
> * @regmap_config: regmap config for the device
> + * @use_sm: read data from secure monitor instead of efuse
> * This structure is required for configuration of amlogic thermal driver.
> */
> struct amlogic_thermal_data {
> int u_efuse_off;
> const struct amlogic_thermal_soc_calib_data *calibration_parameters;
> const struct regmap_config *regmap_config;
> + bool use_sm;
> };
>
> struct amlogic_thermal {
> @@ -100,6 +103,8 @@ struct amlogic_thermal {
> struct clk *clk;
> struct thermal_zone_device *tzd;
> u32 trim_info;
> + struct meson_sm_firmware *sm_fw;
> + u32 tsensor_id;
> };
>
> /*
> @@ -138,6 +143,12 @@ static int amlogic_thermal_initialize(struct amlogic_thermal *pdata)
> int ret = 0;
> int ver;
>
> + if (pdata->data->use_sm) {
> + return meson_sm_get_thermal_calib(pdata->sm_fw,
> + &pdata->trim_info,
> + pdata->tsensor_id);
> + }
> +
> regmap_read(pdata->sec_ao_map, pdata->data->u_efuse_off,
> &pdata->trim_info);
>
> @@ -226,6 +237,12 @@ static const struct amlogic_thermal_data amlogic_thermal_a1_cpu_param = {
> .regmap_config = &amlogic_thermal_regmap_config_g12a,
> };
>
> +static const struct amlogic_thermal_data amlogic_thermal_t7_param = {
> + .use_sm = true,
> + .calibration_parameters = &amlogic_thermal_g12a,
> + .regmap_config = &amlogic_thermal_regmap_config_g12a,
> +};
> +
> static const struct of_device_id of_amlogic_thermal_match[] = {
> {
> .compatible = "amlogic,g12a-ddr-thermal",
> @@ -239,6 +256,10 @@ static const struct of_device_id of_amlogic_thermal_match[] = {
> .compatible = "amlogic,a1-cpu-thermal",
> .data = &amlogic_thermal_a1_cpu_param,
> },
> + {
> + .compatible = "amlogic,t7-thermal",
> + .data = &amlogic_thermal_t7_param,
> + },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, of_amlogic_thermal_match);
> @@ -271,11 +292,38 @@ static int amlogic_thermal_probe(struct platform_device *pdev)
> if (IS_ERR(pdata->clk))
> return dev_err_probe(dev, PTR_ERR(pdata->clk), "failed to get clock\n");
>
> - pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
> - (pdev->dev.of_node, "amlogic,ao-secure");
> - if (IS_ERR(pdata->sec_ao_map)) {
> - dev_err(dev, "syscon regmap lookup failed.\n");
> - return PTR_ERR(pdata->sec_ao_map);
> + if (pdata->data->use_sm) {
> + struct device_node *sm_np;
> + struct of_phandle_args ph_args;
> +
> + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
> + "amlogic,secure-monitor",
> + 1, 0, &ph_args);
> + if (ret)
> + return ret;
> +
> + sm_np = ph_args.np;
> + if (!sm_np) {
> + dev_err(dev,
> + "Failed to parse secure monitor phandle\n");
> + return -ENODEV;
> + }
> +
> + pdata->sm_fw = meson_sm_get(sm_np);
> + of_node_put(sm_np);
> + if (!pdata->sm_fw) {
> + dev_err(dev, "Failed to get secure monitor firmware\n");
> + return -EPROBE_DEFER;
> + }
> +
> + pdata->tsensor_id = ph_args.args[0];
> + } else {
> + pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
> + (pdev->dev.of_node, "amlogic,ao-secure");
> + if (IS_ERR(pdata->sec_ao_map)) {
> + dev_err(dev, "syscon regmap lookup failed.\n");
> + return PTR_ERR(pdata->sec_ao_map);
> + }
> }
I suggest to separate these two routines into functions. That will help
the readability.
> pdata->tzd = devm_thermal_of_zone_register(&pdev->dev
The thermal zone is registered before calling
amlogic_thermal_initialize(), thus pdata->trim_info is not initialized.
When a thermal zone is registered the thermal framework reads the
temperature, so it reads an invalid value because:
devm_thermal_of_zone_register()
-> thermal_of_zone_register()
-> thermal_zone_device_register_with_trips()
-> thermal_zone_device_enable()
-> __thermal_zone_device_update()
-> __thermal_zone_get_temp()
-> amlogic_thermal_get_temp()
-> amlogic_thermal_code_to_millicelsius()
[ Use of uninitialized pdata->trim_info ]
Right ?
IIUC, amlogic_thermal_initialize() can be also split and moved the
corresponding blocks to the functions to be created in the comment above.
>
^ permalink raw reply
* Re: [PATCH] crypto: sun8i-ss - avoid hash and rng references
From: Arnd Bergmann @ 2026-04-23 10:26 UTC (permalink / raw)
To: Herbert Xu
Cc: Arnd Bergmann, Corentin Labbe, David S . Miller, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Eric Biggers, Ovidiu Panait,
linux-crypto, linux-arm-kernel, linux-sunxi, linux-kernel
In-Reply-To: <aenmEQNhhw9bnxEa@gondor.apana.org.au>
On Thu, Apr 23, 2026, at 11:27, Herbert Xu wrote:
> On Thu, Apr 23, 2026 at 11:25:19AM +0200, Arnd Bergmann wrote:
>>
>> Yes, I can rework the patch that way. I had considered this originally
>> but decided this would end up less readable in this case because
>> of the extra indentation level. The drivers already has a lot of
>> #ifdef checks, so adding more of those felt more in line with the
>> style used here.
>
> If we're adding new code I prefer doing it inline instead of as
> an ifdef so that we maximise compiler coverage.
Sure, but I'm not adding new code here, I only reported a regression
from Eric's (otherwise very nice) cleanup and tried to come up
with a better workaround than adding another 'select'.
I've tried to rework one driver to use IS_ENABLED() checks now
instead of the #ifdef, and also replace the for()/switch()
loop with three separate loops for simplicity. See below for
what I ended up with compared with my first patch.
I'm still not entirely happy with that version either, especially
since this is getting beyond a purely mechanical cleanup.
If you think this is better, I can do it for all three drivers,
otherwise I'd just send the oneline change to work around the
third driver link failure the same way that Eric did for the
other two, and let the sunxi maintainters worry about cleaning
it up.
Arnd
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
index 813c4bc6312a..330a1ed7eb03 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
@@ -31,7 +31,7 @@ static const struct ss_variant ss_a33_variant = {
.sha1_in_be = true,
};
-static struct sun4i_ss_alg_template ss_algs[] = {
+static struct sun4i_ss_alg_template ss_ahash_algs[] = {
{ .type = CRYPTO_ALG_TYPE_AHASH,
.mode = SS_OP_MD5,
.alg.hash = {
@@ -84,6 +84,9 @@ static struct sun4i_ss_alg_template ss_algs[] = {
}
}
},
+};
+
+static struct sun4i_ss_alg_template ss_skcipher_algs[] = {
{ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.crypto = {
.setkey = sun4i_ss_aes_setkey,
@@ -213,7 +216,9 @@ static struct sun4i_ss_alg_template ss_algs[] = {
}
}
},
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
+};
+
+static struct sun4i_ss_alg_template ss_rng_algs[] = {
{
.type = CRYPTO_ALG_TYPE_RNG,
.alg.rng = {
@@ -229,40 +234,46 @@ static struct sun4i_ss_alg_template ss_algs[] = {
.seedsize = SS_SEED_LEN / BITS_PER_BYTE,
}
},
-#endif
};
static int sun4i_ss_debugfs_show(struct seq_file *seq, void *v)
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
- if (!ss_algs[i].ss)
+ for (i = 0; i < ARRAY_SIZE(ss_skcipher_algs); i++) {
+ if (!ss_skcipher_algs[i].ss)
continue;
- switch (ss_algs[i].type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
- seq_printf(seq, "%s %s reqs=%lu opti=%lu fallback=%lu tsize=%lu\n",
- ss_algs[i].alg.crypto.base.cra_driver_name,
- ss_algs[i].alg.crypto.base.cra_name,
- ss_algs[i].stat_req, ss_algs[i].stat_opti, ss_algs[i].stat_fb,
- ss_algs[i].stat_bytes);
- break;
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n",
- ss_algs[i].alg.rng.base.cra_driver_name,
- ss_algs[i].alg.rng.base.cra_name,
- ss_algs[i].stat_req, ss_algs[i].stat_bytes);
- break;
-#endif
- case CRYPTO_ALG_TYPE_AHASH:
- seq_printf(seq, "%s %s reqs=%lu\n",
- ss_algs[i].alg.hash.halg.base.cra_driver_name,
- ss_algs[i].alg.hash.halg.base.cra_name,
- ss_algs[i].stat_req);
- break;
- }
+ seq_printf(seq, "%s %s reqs=%lu opti=%lu fallback=%lu tsize=%lu\n",
+ ss_skcipher_algs[i].alg.crypto.base.cra_driver_name,
+ ss_skcipher_algs[i].alg.crypto.base.cra_name,
+ ss_skcipher_algs[i].stat_req,
+ ss_skcipher_algs[i].stat_opti,
+ ss_skcipher_algs[i].stat_fb,
+ ss_skcipher_algs[i].stat_bytes);
}
+
+ for (i = 0; i < ARRAY_SIZE(ss_ahash_algs); i++) {
+ if (!ss_ahash_algs[i].ss)
+ continue;
+
+ seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n",
+ ss_ahash_algs[i].alg.rng.base.cra_driver_name,
+ ss_ahash_algs[i].alg.rng.base.cra_name,
+ ss_ahash_algs[i].stat_req,
+ ss_ahash_algs[i].stat_bytes);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ss_rng_algs); i++) {
+ if (!IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG) ||
+ !ss_rng_algs[i].ss)
+ continue;
+
+ seq_printf(seq, "%s %s reqs=%lu\n",
+ ss_rng_algs[i].alg.hash.halg.base.cra_driver_name,
+ ss_rng_algs[i].alg.hash.halg.base.cra_name,
+ ss_rng_algs[i].stat_req);
+ }
+
return 0;
}
DEFINE_SHOW_ATTRIBUTE(sun4i_ss_debugfs);
@@ -454,34 +465,36 @@ static int sun4i_ss_probe(struct platform_device *pdev)
pm_runtime_put_sync(ss->dev);
- for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
- ss_algs[i].ss = ss;
- switch (ss_algs[i].type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
- err = crypto_register_skcipher(&ss_algs[i].alg.crypto);
- if (err) {
- dev_err(ss->dev, "Fail to register %s\n",
- ss_algs[i].alg.crypto.base.cra_name);
- goto error_alg;
- }
- break;
- case CRYPTO_ALG_TYPE_AHASH:
- err = crypto_register_ahash(&ss_algs[i].alg.hash);
- if (err) {
- dev_err(ss->dev, "Fail to register %s\n",
- ss_algs[i].alg.hash.halg.base.cra_name);
- goto error_alg;
- }
- break;
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- err = crypto_register_rng(&ss_algs[i].alg.rng);
- if (err) {
- dev_err(ss->dev, "Fail to register %s\n",
- ss_algs[i].alg.rng.base.cra_name);
- }
+ for (i = 0; i < ARRAY_SIZE(ss_skcipher_algs); i++) {
+ ss_skcipher_algs[i].ss = ss;
+ err = crypto_register_skcipher(&ss_skcipher_algs[i].alg.crypto);
+ if (err) {
+ dev_err(ss->dev, "Fail to register %s\n",
+ ss_skcipher_algs[i].alg.crypto.base.cra_name);
+ goto error_skcipher_alg;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ss_ahash_algs); i++) {
+ ss_ahash_algs[i].ss = ss;
+ err = crypto_register_ahash(&ss_ahash_algs[i].alg.hash);
+ if (err) {
+ dev_err(ss->dev, "Fail to register %s\n",
+ ss_ahash_algs[i].alg.hash.halg.base.cra_name);
+ goto error_ahash_alg;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ss_rng_algs); i++) {
+ if (!IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG))
break;
-#endif
+
+ ss_rng_algs[i].ss = ss;
+ err = crypto_register_rng(&ss_rng_algs[i].alg.rng);
+ if (err) {
+ dev_err(ss->dev, "Fail to register %s\n",
+ ss_rng_algs[i].alg.rng.base.cra_name);
+ goto error_rng_alg;
}
}
@@ -491,23 +504,20 @@ static int sun4i_ss_probe(struct platform_device *pdev)
&sun4i_ss_debugfs_fops);
return 0;
-error_alg:
- i--;
- for (; i >= 0; i--) {
- switch (ss_algs[i].type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
- crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
- break;
- case CRYPTO_ALG_TYPE_AHASH:
- crypto_unregister_ahash(&ss_algs[i].alg.hash);
- break;
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- crypto_unregister_rng(&ss_algs[i].alg.rng);
- break;
-#endif
- }
+
+error_rng_alg:
+ if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG)) {
+ for (i--; i >= 0; i--)
+ crypto_unregister_rng(&ss_rng_algs[i].alg.rng);
}
+ i = ARRAY_SIZE(ss_ahash_algs);
+error_ahash_alg:
+ for (i--; i >= 0; i--)
+ crypto_unregister_ahash(&ss_ahash_algs[i].alg.hash);
+ i = ARRAY_SIZE(ss_skcipher_algs);
+error_skcipher_alg:
+ for (i--; i >= 0; i--)
+ crypto_unregister_skcipher(&ss_skcipher_algs[i].alg.crypto);
error_pm:
sun4i_ss_pm_exit(ss);
return err;
@@ -518,21 +528,14 @@ static void sun4i_ss_remove(struct platform_device *pdev)
int i;
struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev);
- for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
- switch (ss_algs[i].type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
- crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
- break;
- case CRYPTO_ALG_TYPE_AHASH:
- crypto_unregister_ahash(&ss_algs[i].alg.hash);
- break;
-#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
- case CRYPTO_ALG_TYPE_RNG:
- crypto_unregister_rng(&ss_algs[i].alg.rng);
- break;
-#endif
- }
+ if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG)) {
+ for (i = ARRAY_SIZE(ss_rng_algs); i >= 0; i--)
+ crypto_unregister_rng(&ss_rng_algs[i].alg.rng);
}
+ for (i = ARRAY_SIZE(ss_ahash_algs); i >= 0; i--)
+ crypto_unregister_ahash(&ss_ahash_algs[i].alg.hash);
+ for (i = ARRAY_SIZE(ss_skcipher_algs) - 1; i >= 0; i--)
+ crypto_unregister_skcipher(&ss_skcipher_algs[i].alg.crypto);
sun4i_ss_pm_exit(ss);
}
^ permalink raw reply related
* Re: [PATCH 2/4] arm64: dts: imx95: switch usb3 controller to flattened model
From: Xu Yang @ 2026-04-23 10:26 UTC (permalink / raw)
To: Frank Li
Cc: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, devicetree,
imx, linux-arm-kernel, linux-kernel, jun.li
In-Reply-To: <aehGKE8qLXiBKvvB@lizhi-Precision-Tower-5810>
On Tue, Apr 21, 2026 at 11:53:12PM -0400, Frank Li wrote:
> On Tue, Apr 21, 2026 at 06:55:01PM +0800, Xu Yang wrote:
> > Switch to use flattened model for USB3 controller. To enable USB
> > controller with restricted DMA access range to work correctly, add a
> > pseudo simple-bus to constrain the dma address.
>
> i.mx95 should fix >4G dma space's problem. Does it impact other no-nxp
> boards?
Yes, i.MX95 has fixed >3G address DMA access problem.
It's another issue. HSIO domain only support 36 bit bus access. If not use smmu,
no any issue. If use smmu, it will allocate memory space of 36 bit < iova < 48bit.
HSIO can't handle this case.
>
> Need do break compatible judgement such as
>
> i.MX95 is new SoC and still is heave development. The break compatible is
> accepable at development early phase.
>
> You can rephrase it.
OK.
Thanks,
Xu Yang
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox