* Re: [PATCH 11/11] media: hantro: Add fdinfo callback
From: Nicolas Dufresne @ 2026-04-28 19:41 UTC (permalink / raw)
To: Detlev Casanova, linux-kernel
Cc: Benjamin Gaignard, Philipp Zabel, Mauro Carvalho Chehab,
Heiko Stuebner, Daniel Almeida, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Hans Verkuil, Laurent Pinchart,
Ricardo Ribalda, Yunke Cao, Sakari Ailus, Pavan Bobba,
James Cowgill, Ma Ke, Jacopo Mondi, Daniel Scally, linux-media,
linux-rockchip, linux-arm-kernel, linux-trace-kernel, kernel
In-Reply-To: <20260212162328.192217-12-detlev.casanova@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 4001 bytes --]
Le jeudi 12 février 2026 à 11:23 -0500, Detlev Casanova a écrit :
> The fdinfo shows the number of buffers in each queue and the total amount
> of video buffer memory.
>
> Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
Notice that the FD info is not linked with all the ftrace work, and could have
been kept separate. I think overall that this fdinfo implementation is a bit
limited, and lack helpers or introducing of common statistics that would be
opted in by other drivers. I would hold on that until we have a bigger and
robust plan.
Nicolas
> ---
> drivers/media/platform/verisilicon/hantro.h | 1 +
> drivers/media/platform/verisilicon/hantro_drv.c | 15 +++++++++++++++
> drivers/media/platform/verisilicon/hantro_v4l2.c | 10 +++++++++-
> 3 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/verisilicon/hantro.h
> b/drivers/media/platform/verisilicon/hantro.h
> index d5cddc783688..9e9fc0658586 100644
> --- a/drivers/media/platform/verisilicon/hantro.h
> +++ b/drivers/media/platform/verisilicon/hantro.h
> @@ -268,6 +268,7 @@ struct hantro_ctx {
> const struct hantro_codec_ops *codec_ops;
> struct hantro_postproc_ctx postproc;
> bool need_postproc;
> + u64 stats_buf_memory;
>
> /* Specific for particular codec modes. */
> union {
> diff --git a/drivers/media/platform/verisilicon/hantro_drv.c
> b/drivers/media/platform/verisilicon/hantro_drv.c
> index 8dd26ca32459..86d316a8a3e8 100644
> --- a/drivers/media/platform/verisilicon/hantro_drv.c
> +++ b/drivers/media/platform/verisilicon/hantro_drv.c
> @@ -17,6 +17,7 @@
> #include <linux/platform_device.h>
> #include <linux/pm.h>
> #include <linux/pm_runtime.h>
> +#include <linux/seq_file.h>
> #include <linux/slab.h>
> #include <linux/videodev2.h>
> #include <linux/workqueue.h>
> @@ -711,6 +712,19 @@ static int hantro_release(struct file *filp)
> return 0;
> }
>
> +static void hantro_show_fdinfo(struct seq_file *m, struct file *filp)
> +{
> + struct hantro_ctx *ctx =
> + container_of(filp->private_data, struct hantro_ctx, fh);
> +
> + struct vb2_queue *src_q = v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx);
> + struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
> +
> + seq_printf(m, "src-queued-count: %04u\n", src_q->queued_count);
> + seq_printf(m, "dst-queued-count: %04u\n", dst_q->queued_count);
> + seq_printf(m, "buf-size: %llu\n", ctx->stats_buf_memory);
> +}
> +
> static const struct v4l2_file_operations hantro_fops = {
> .owner = THIS_MODULE,
> .open = hantro_open,
> @@ -718,6 +732,7 @@ static const struct v4l2_file_operations hantro_fops = {
> .poll = v4l2_m2m_fop_poll,
> .unlocked_ioctl = video_ioctl2,
> .mmap = v4l2_m2m_fop_mmap,
> + .show_fdinfo = hantro_show_fdinfo,
> };
>
> static const struct of_device_id of_hantro_match[] = {
> diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c
> b/drivers/media/platform/verisilicon/hantro_v4l2.c
> index fcf3bd9bcda2..6d129613ea3d 100644
> --- a/drivers/media/platform/verisilicon/hantro_v4l2.c
> +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
> @@ -820,18 +820,26 @@ hantro_queue_setup(struct vb2_queue *vq, unsigned int
> *num_buffers,
> return -EINVAL;
> }
>
> + ctx->stats_buf_memory = 0;
> +
> if (*num_planes) {
> if (*num_planes != pixfmt->num_planes)
> return -EINVAL;
> - for (i = 0; i < pixfmt->num_planes; ++i)
> + for (i = 0; i < pixfmt->num_planes; ++i) {
> if (sizes[i] < pixfmt->plane_fmt[i].sizeimage)
> return -EINVAL;
> + ctx->stats_buf_memory += pixfmt-
> >plane_fmt[i].sizeimage;
> + }
> +
> + ctx->stats_buf_memory *= *num_buffers;
> +
> return 0;
> }
>
> *num_planes = pixfmt->num_planes;
> for (i = 0; i < pixfmt->num_planes; ++i)
> sizes[i] = pixfmt->plane_fmt[i].sizeimage;
> +
> return 0;
> }
>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v4 02/15] mm: Make empty_zero_page __ro_after_init
From: David Hildenbrand (Arm) @ 2026-04-28 19:51 UTC (permalink / raw)
To: Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, will, catalin.marinas, mark.rutland, Ard Biesheuvel,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, Andrew Morton, linux-mm,
linux-hardening
In-Reply-To: <20260427153416.2103979-19-ardb+git@google.com>
On 4/27/26 17:34, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> The empty zero page is used to back any kernel or user space mapping
> that is supposed to remain cleared, and so the page itself is never
> supposed to be modified.
>
> So make it __ro_after_init rather than __page_aligned_bss: on most
> architectures, this ensures that both the kernel's mapping of it and any
> aliases that are accessible via the kernel direct (linear) map are
> mapped read-only, and cannot be used (inadvertently or maliciously) to
> corrupt the contents of the zero page.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> mm/mm_init.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index f9f8e1af921c..6ca01ed2a5a4 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -57,7 +57,7 @@ unsigned long zero_page_pfn __ro_after_init;
> EXPORT_SYMBOL(zero_page_pfn);
>
> #ifndef __HAVE_COLOR_ZERO_PAGE
> -uint8_t empty_zero_page[PAGE_SIZE] __page_aligned_bss;
> +uint8_t empty_zero_page[PAGE_SIZE] __ro_after_init __aligned(PAGE_SIZE);
> EXPORT_SYMBOL(empty_zero_page);
>
> struct page *__zero_page __ro_after_init;
I am no expert on BSS etc, but from what I understand, we'll still get zeroed
page-aligned memory. I don't know if there is any other impact on not having it
in bss.page_aligned. I assume no
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 00/11] v4l2: Add tracing for stateless codecs
From: Nicolas Dufresne @ 2026-04-28 19:52 UTC (permalink / raw)
To: Detlev Casanova, linux-kernel
Cc: Benjamin Gaignard, Philipp Zabel, Mauro Carvalho Chehab,
Heiko Stuebner, Daniel Almeida, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Hans Verkuil, Laurent Pinchart,
Ricardo Ribalda, Yunke Cao, Sakari Ailus, Pavan Bobba,
James Cowgill, Ma Ke, Jacopo Mondi, Daniel Scally, linux-media,
linux-rockchip, linux-arm-kernel, linux-trace-kernel, kernel
In-Reply-To: <20260212162328.192217-1-detlev.casanova@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 5527 bytes --]
Le jeudi 12 février 2026 à 11:23 -0500, Detlev Casanova a écrit :
> Hi !
>
> This patchset aims to improve codec event tracing in v4l2.
>
> The traces added in visl by Daniel Almeida are moved to the global trace
> events and slightly reworked to be printed in a more consistent format.
>
> To each trace are also added a tgid and fd fields, helping userspace track
> different decoding sessions (contexts) based on the given file descriptor
> used by the given process id.
>
> Also for better tracking, stream on and stream off events are added as
> well as HW run and HW done events to track decoder core usage.
>
> Finally, add a show_fdinfo callback on video device files, allowing drivers
> to expose usage information.
> Currently only used for frame buffer memory usage.
>
> The main focus is to be able to generate perfetto traces to show VPU usage,
> a perfetto producer using this can be found at [1].
>
> [1]:
> https://gitlab.collabora.com/detlev/hantro-perf/-/tree/hantro-improved-info
I would recommend renaming this repo, as its not really evolving toward
something truly hantro specific anymore, same goes for the code below appart
from the run/done traces and the fdinfo that has to be opted in.
There is effectively a bit of an overlap with the v4l2-tracer, but there is also
advantages having it in the kernel, as you source all the event, for the entire
system, in one place, so I'm fine with that. Considering the possible large
overhead of the full trace, I'd like to see the ability to filter what we want
to trace, with some level of granularity. Maybe we only need decode_params for
specific use case to be debugged, and don't care about large scaling list/matrix
? I would also like to see some Documentation on the tracing, so that its usage
is not only explained in a tool.
To Hans, there is nice tools idea in there, the perfetto producer is simply C++,
and the v4l2top utility is Rust. Would you see these as tools v4l2-utils ? For
the rust part, we can either leave the build independent, and cargo would be
used to build and run, or we can implement a meson wrapper around cargo. But I
don't believe its a good idea to use native rustc support in meson for that one
because of the large number of third party crate needed.
I like the direction, hope the feedback suite you well.
Nicolas
>
> Detlev Casanova (11):
> media: Move visl traces to v4l2-core
> media: Reformat v4l2-requests trace event printk
> media: Add tgid and fd fields in v4l2_fh struct
> media: Add tgid and fd to the v4l2-requests trace fields
> media: Add missing types to v4l2_ctrl_ptr
> media: Trace the stateless controls when set in v4l2-ctrls-core.c
> media: Add stream on/off traces and run them in the ioctl
> media: Add HW run/done trace events
> media: hantro: Add v4l2_hw run/done traces
> media: v4l2: Add callback for show_fdinfo
> media: hantro: Add fdinfo callback
>
> drivers/media/platform/verisilicon/hantro.h | 2 +
> .../media/platform/verisilicon/hantro_drv.c | 25 +
> .../media/platform/verisilicon/hantro_v4l2.c | 10 +-
> .../verisilicon/rockchip_vpu981_regs.h | 1 +
> .../platform/verisilicon/rockchip_vpu_hw.c | 4 +
> drivers/media/test-drivers/visl/Makefile | 2 +-
> drivers/media/test-drivers/visl/visl-dec.c | 76 -
> .../media/test-drivers/visl/visl-trace-av1.h | 314 ---
> .../media/test-drivers/visl/visl-trace-fwht.h | 66 -
> .../media/test-drivers/visl/visl-trace-h264.h | 349 ----
> .../media/test-drivers/visl/visl-trace-hevc.h | 464 -----
> .../test-drivers/visl/visl-trace-mpeg2.h | 99 -
> .../test-drivers/visl/visl-trace-points.c | 11 -
> .../media/test-drivers/visl/visl-trace-vp8.h | 156 --
> .../media/test-drivers/visl/visl-trace-vp9.h | 292 ---
> drivers/media/v4l2-core/v4l2-ctrls-api.c | 10 +
> drivers/media/v4l2-core/v4l2-ctrls-core.c | 114 +
> drivers/media/v4l2-core/v4l2-dev.c | 10 +
> drivers/media/v4l2-core/v4l2-fh.c | 1 +
> drivers/media/v4l2-core/v4l2-ioctl.c | 37 +-
> drivers/media/v4l2-core/v4l2-trace.c | 48 +
> include/media/v4l2-ctrls.h | 19 +
> include/media/v4l2-dev.h | 1 +
> include/media/v4l2-fh.h | 4 +
> include/trace/events/v4l2.h | 58 +
> include/trace/events/v4l2_requests.h | 1836 +++++++++++++++++
> 26 files changed, 2178 insertions(+), 1831 deletions(-)
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-av1.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-fwht.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-h264.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-hevc.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-mpeg2.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-points.c
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-vp8.h
> delete mode 100644 drivers/media/test-drivers/visl/visl-trace-vp9.h
> create mode 100644 include/trace/events/v4l2_requests.h
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v18 3/8] ring-buffer: Skip invalid sub-buffers when validating persistent ring buffer
From: Steven Rostedt @ 2026-04-28 19:55 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Catalin Marinas, Will Deacon, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel, Ian Rogers, linux-arm-kernel
In-Reply-To: <177701354681.2223789.14633430761021638378.stgit@mhiramat.tok.corp.google.com>
On Fri, 24 Apr 2026 15:52:27 +0900
"Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> @@ -5648,11 +5668,12 @@ __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
> again:
> /*
> * This should normally only loop twice. But because the
> - * start of the reader inserts an empty page, it causes
> - * a case where we will loop three times. There should be no
> - * reason to loop four times (that I know of).
> + * start of the reader inserts an empty page, it causes a
> + * case where we will loop three times. There should be no
> + * reason to loop four times unless the ring buffer is a
> + * recovered persistent ring buffer.
Can you explain more to why this is allowed for persistent ring buffer?
Note, I do not like any loops that can go into an infinite loop and lock up
the machine. If something goes wrong with a persistent ring buffer, then
this could possibly go into an infinite loop.
I want to understand why this is allowed, and possibly add a check that
prevents this from never ending.
-- Steve
> */
> - if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3)) {
> + if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3 && !cpu_buffer->ring_meta)) {
> reader = NULL;
> goto out;
> }
^ permalink raw reply
* [PATCH 5.10.y] arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
From: Sasha Levin @ 2026-04-28 20:05 UTC (permalink / raw)
To: stable
Cc: Anshuman Khandual, Will Deacon, linux-arm-kernel, linux-kernel,
David Hildenbrand (Arm), Ryan Roberts, Catalin Marinas,
Sasha Levin
In-Reply-To: <2026042729-abiding-helmet-8eef@gregkh>
From: Anshuman Khandual <anshuman.khandual@arm.com>
[ Upstream commit 48478b9f791376b4b89018d7afdfd06865498f65 ]
During a memory hot remove operation, both linear and vmemmap mappings for
the memory range being removed, get unmapped via unmap_hotplug_range() but
mapped pages get freed only for vmemmap mapping. This is just a sequential
operation where each table entry gets cleared, followed by a leaf specific
TLB flush, and then followed by memory free operation when applicable.
This approach was simple and uniform both for vmemmap and linear mappings.
But linear mapping might contain CONT marked block memory where it becomes
necessary to first clear out all entire in the range before a TLB flush.
This is as per the architecture requirement. Hence batch all TLB flushes
during the table tear down walk and finally do it in unmap_hotplug_range().
Prior to this fix, it was hypothetically possible for a speculative access
to a higher address in the contiguous block to fill the TLB with shattered
entries for the entire contiguous range after a lower address had already
been cleared and invalidated. Due to the table entries being shattered, the
subsequent TLB invalidation for the higher address would not then clear the
TLB entries for the lower address, meaning stale TLB entries could persist.
Besides it also helps in improving the performance via TLBI range operation
along with reduced synchronization instructions. The time spent executing
unmap_hotplug_range() improved 97% measured over a 2GB memory hot removal
in KVM guest.
This scheme is not applicable during vmemmap mapping tear down where memory
needs to be freed and hence a TLB flush is required after clearing out page
table entry.
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Closes: https://lore.kernel.org/all/aWZYXhrT6D2M-7-N@willie-the-truck/
Fixes: bbd6ec605c0f ("arm64/mm: Enable memory hot remove")
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ renamed `__pte_clear()` to `pte_clear()` and inlined `pmd_cont(pmd)` as `pmd_val(pmd) & PMD_SECT_CONT` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/mm/mmu.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b584bf200619f..ff16cc7251b40 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -862,10 +862,14 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
WARN_ON(!pte_present(pte));
pte_clear(&init_mm, addr, ptep);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pte_cont(pte));
+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
free_hotplug_page_range(pte_page(pte),
PAGE_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
} while (addr += PAGE_SIZE, addr < end);
}
@@ -886,15 +890,14 @@ static void unmap_hotplug_pmd_range(pud_t *pudp, unsigned long addr,
WARN_ON(!pmd_present(pmd));
if (pmd_sect(pmd)) {
pmd_clear(pmdp);
-
- /*
- * One TLBI should be sufficient here as the PMD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ /* CONT blocks are not supported in the vmemmap */
+ WARN_ON(pmd_val(pmd) & PMD_SECT_CONT);
+ flush_tlb_kernel_range(addr, addr + PMD_SIZE);
free_hotplug_page_range(pmd_page(pmd),
PMD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pmd_table(pmd));
@@ -919,15 +922,12 @@ static void unmap_hotplug_pud_range(p4d_t *p4dp, unsigned long addr,
WARN_ON(!pud_present(pud));
if (pud_sect(pud)) {
pud_clear(pudp);
-
- /*
- * One TLBI should be sufficient here as the PUD_SIZE
- * range is mapped with a single block entry.
- */
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- if (free_mapped)
+ if (free_mapped) {
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
free_hotplug_page_range(pud_page(pud),
PUD_SIZE, altmap);
+ }
+ /* unmap_hotplug_range() flushes TLB for !free_mapped */
continue;
}
WARN_ON(!pud_table(pud));
@@ -957,6 +957,7 @@ static void unmap_hotplug_p4d_range(pgd_t *pgdp, unsigned long addr,
static void unmap_hotplug_range(unsigned long addr, unsigned long end,
bool free_mapped, struct vmem_altmap *altmap)
{
+ unsigned long start = addr;
unsigned long next;
pgd_t *pgdp, pgd;
@@ -978,6 +979,9 @@ static void unmap_hotplug_range(unsigned long addr, unsigned long end,
WARN_ON(!pgd_present(pgd));
unmap_hotplug_p4d_range(pgdp, addr, next, free_mapped, altmap);
} while (addr = next, addr < end);
+
+ if (!free_mapped)
+ flush_tlb_kernel_range(start, end);
}
static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v6 1/6] docs: uapi: media: Clarify HEVC slice_param bit_size, data_byte_offset
From: Nicolas Dufresne @ 2026-04-28 20:07 UTC (permalink / raw)
To: Dave Stevenson, Sakari Ailus, Laurent Pinchart,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, John Cox, Dom Cobley,
review list, Ezequiel Garcia
Cc: John Cox, Stefan Wahren, linux-media, linux-kernel, devicetree,
linux-rpi-kernel, linux-arm-kernel
In-Reply-To: <20260304-media-rpi-hevc-dec-v6-1-93868ae6dff8@raspberrypi.com>
[-- Attachment #1: Type: text/plain, Size: 1744 bytes --]
Le mercredi 04 mars 2026 à 14:05 +0000, Dave Stevenson a écrit :
> From: John Cox <john.cox@raspberrypi.com>
>
> Clarify exactly what bit_size and data_byte_offset mean when there are
> multiple slices in the bitstream data.
>
> Signed-off-by: John Cox <john.cox@raspberrypi.com>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
> Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> index 3b1e05c6eb13..a54e8ea29440 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> @@ -2399,10 +2399,12 @@ This structure contains all loop filter related parameters. See sections
>
> * - __u32
> - ``bit_size``
> - - Size (in bits) of the current slice data.
> + - Size in bits of the slice_segment_data for the current slice including
> + any emulation prevention bytes.
> * - __u32
> - ``data_byte_offset``
> - - Offset (in byte) to the video data in the current slice data.
> + - Offset in bytes from the start of the current v4l2_buffer to the start
> + of the slice_segment_data for the current slice.
> * - __u32
> - ``num_entry_point_offsets``
> - Specifies the number of entry point offset syntax elements in the slice header.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH 0/7] dts: Add /firmware/#{address,size}-cells to Chromium-based DTs
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
## From a RK3399 Gru/Kevin Chromebook:
# find /sys/firmware/devicetree/base/firmware
/sys/firmware/devicetree/base/firmware
/sys/firmware/devicetree/base/firmware/coreboot
/sys/firmware/devicetree/base/firmware/coreboot/ram-code
/sys/firmware/devicetree/base/firmware/coreboot/compatible
/sys/firmware/devicetree/base/firmware/coreboot/board-id
/sys/firmware/devicetree/base/firmware/coreboot/reg
/sys/firmware/devicetree/base/firmware/coreboot/name
/sys/firmware/devicetree/base/firmware/chromeos
/sys/firmware/devicetree/base/firmware/chromeos/readonly-firmware-version
/sys/firmware/devicetree/base/firmware/chromeos/active-ec-firmware
/sys/firmware/devicetree/base/firmware/chromeos/firmware-version
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-storage
/sys/firmware/devicetree/base/firmware/chromeos/vboot-shared-data
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-size
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-offset
/sys/firmware/devicetree/base/firmware/chromeos/hardware-id
/sys/firmware/devicetree/base/firmware/chromeos/compatible
/sys/firmware/devicetree/base/firmware/chromeos/firmware-type
/sys/firmware/devicetree/base/firmware/chromeos/fmap-offset
/sys/firmware/devicetree/base/firmware/chromeos/name
/sys/firmware/devicetree/base/firmware/ranges
/sys/firmware/devicetree/base/firmware/name
The /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
This series adds appropriate #{address,size}-cells to the device trees
used on Arm Chromebooks to work around the problem.
Note that Google provides bootloader updates for some devices that add
{address,size}-cells [1], but these are only delivered via Google OS
updates. Not all users receive Google software updates, and even if they
do, not all devices still receive bootloader updates from Google.
This problem was first noticed in OpenWrt, where some Chromium-based
routers ran into the same issue:
https://github.com/openwrt/openwrt/issues/21243
Relevant OpenWrt fixes: https://github.com/openwrt/openwrt/pull/22951
There is also discussion at [2].
I've currently only tested:
1) the aforementioned OpenWrt routers (with non-upstream DTS/DTB)
2) RK3399 Gru/Kevin Chromebook (patch 1)
3) Qualcomm SC7280 Herobrine (patch 7)
I assume the others should follow the same pattern. I don't know if I've
covered every relevant Depthcharge-using device, but I've made a good
attempt to identify them all.
I reviewed Depthcharge code history and found that this problematic
bootloader behavior dates back to at least 2014, with the Tegra/Nyan
device. Older devices may have similar DTB structures, but I'm not sure
if they have the same address-cells problems. In any case, these changes
shouldn't hurt even if a device was not affected.
Brian
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
[2] [regression] of: mis-parsing Depthcharge's /firmware
https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Brian Norris (7):
arm64: dts: rockchip: Add #{address,size}-cells to Chromium-based
/firmware
ARM: dts: rockchip: Add #{address,size}-cells to Chromium-based
/firmware
ARM: dts: nvidia: Add #{address,size}-cells to Chromium-based
/firmware
ARM: dts: samsung: Add #{address,size}-cells to Chromium-based
/firmware
arm64: dts: mediatek: Add #{address,size}-cells to Chromium-based
/firmware
arm64: dts: nvidia: Add #{address,size}-cells to Chromium-based
/firmware
arm64: dts: qcom: Add #{address,size}-cells to Chromium-based
/firmware
arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi | 5 +++++
arch/arm/boot/dts/nvidia/tegra124-venice2.dts | 5 +++++
arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi | 5 +++++
arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi | 5 +++++
arch/arm/boot/dts/samsung/exynos5250-spring.dts | 5 +++++
arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts | 5 +++++
arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts | 5 +++++
arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 5 +++++
arch/arm64/boot/dts/nvidia/tegra132-norrin.dts | 5 +++++
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 5 +++++
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 5 +++++
arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 5 +++++
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 5 +++++
18 files changed, 90 insertions(+)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply
* [PATCH 1/7] arm64: dts: rockchip: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
## From a RK3399 Gru/Kevin Chromebook:
# find /sys/firmware/devicetree/base/firmware
/sys/firmware/devicetree/base/firmware
/sys/firmware/devicetree/base/firmware/coreboot
/sys/firmware/devicetree/base/firmware/coreboot/ram-code
/sys/firmware/devicetree/base/firmware/coreboot/compatible
/sys/firmware/devicetree/base/firmware/coreboot/board-id
/sys/firmware/devicetree/base/firmware/coreboot/reg
/sys/firmware/devicetree/base/firmware/coreboot/name
/sys/firmware/devicetree/base/firmware/chromeos
/sys/firmware/devicetree/base/firmware/chromeos/readonly-firmware-version
/sys/firmware/devicetree/base/firmware/chromeos/active-ec-firmware
/sys/firmware/devicetree/base/firmware/chromeos/firmware-version
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-storage
/sys/firmware/devicetree/base/firmware/chromeos/vboot-shared-data
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-size
/sys/firmware/devicetree/base/firmware/chromeos/nonvolatile-context-offset
/sys/firmware/devicetree/base/firmware/chromeos/hardware-id
/sys/firmware/devicetree/base/firmware/chromeos/compatible
/sys/firmware/devicetree/base/firmware/chromeos/firmware-type
/sys/firmware/devicetree/base/firmware/chromeos/fmap-offset
/sys/firmware/devicetree/base/firmware/chromeos/name
/sys/firmware/devicetree/base/firmware/ranges
/sys/firmware/devicetree/base/firmware/name
The /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 7eca1da78cff..2f9e39671efc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -18,6 +18,11 @@ chosen {
stdout-path = "serial2:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
/*
* Power Tree
*
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 2/7] ARM: dts: rockchip: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi
index 2d6cf08d00f9..ca8e8e735078 100644
--- a/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi
@@ -18,6 +18,11 @@ chosen {
stdout-path = "serial2:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
/*
* The default coreboot on veyron devices ignores memory@0 nodes
* and would instead create another memory node.
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 3/7] ARM: dts: nvidia: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi | 5 +++++
arch/arm/boot/dts/nvidia/tegra124-venice2.dts | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi b/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
index 974c76f007db..89a749cb8933 100644
--- a/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
+++ b/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
@@ -14,6 +14,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
/*
* Note that recent version of the device tree compiler (starting with
* version 1.4.2) warn about this node containing a reg property, but
diff --git a/arch/arm/boot/dts/nvidia/tegra124-venice2.dts b/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
index df98dc2a67b8..059ee6c5b13c 100644
--- a/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
@@ -18,6 +18,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
memory@80000000 {
reg = <0x0 0x80000000 0x0 0x80000000>;
};
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 4/7] ARM: dts: samsung: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi | 5 +++++
arch/arm/boot/dts/samsung/exynos5250-spring.dts | 5 +++++
arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts | 5 +++++
arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts | 5 +++++
4 files changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi
index 65b000df176e..a64cdec3a2ef 100644
--- a/arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5250-snow-common.dtsi
@@ -30,6 +30,11 @@ chosen {
stdout-path = "serial3:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/samsung/exynos5250-spring.dts b/arch/arm/boot/dts/samsung/exynos5250-spring.dts
index d126fccdcaf3..a337fd9e3473 100644
--- a/arch/arm/boot/dts/samsung/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/samsung/exynos5250-spring.dts
@@ -33,6 +33,11 @@ chosen {
stdout-path = "serial3:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts b/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
index 3759742d38ca..f24356784492 100644
--- a/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
@@ -50,6 +50,11 @@ chosen {
stdout-path = "serial3:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
fixed-rate-clocks {
oscclk {
compatible = "samsung,exynos5420-oscclk";
diff --git a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
index bb019868b996..3df27eddba15 100644
--- a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
@@ -49,6 +49,11 @@ chosen {
stdout-path = "serial3:115200n8";
};
+ firmware {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
fixed-rate-clocks {
oscclk {
compatible = "samsung,exynos5420-oscclk";
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 6/7] arm64: dts: nvidia: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm64/boot/dts/nvidia/tegra132-norrin.dts | 5 +++++
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
index 683ac124523b..1f5222d43e62 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
@@ -18,6 +18,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x80000000>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index f0b8c2c80aa5..a6d31650245d 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -25,6 +25,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0xc0000000>;
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 5/7] arm64: dts: mediatek: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 5 +++++
6 files changed, 30 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index a0573bc359fb..777da2129e77 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -16,6 +16,11 @@ aliases {
mmc2 = &mmc3;
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@40000000 {
device_type = "memory";
reg = <0 0x40000000 0 0x80000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index a8e257b21a88..a906ec1ce672 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -21,6 +21,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells <2>;
+ #size-cells <2>;
+ };
+
backlight_lcd0: backlight_lcd0 {
compatible = "pwm-backlight";
pwms = <&pwm0 0 500000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
index ff20376a44d7..2b327d9ef65e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -26,6 +26,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@40000000 {
device_type = "memory";
/* The size should be filled in by the bootloader. */
diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
index 8e423504ec05..ed63c74cf238 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
@@ -41,6 +41,11 @@ dmic-codec {
wakeup-delay-ms = <100>;
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@40000000 {
device_type = "memory";
/* The size will be filled in by the bootloader */
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index eadf1b2d156f..b3850be25594 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -25,6 +25,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@40000000 {
device_type = "memory";
reg = <0 0x40000000 0 0x80000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index f1ff64a84267..4992631dd504 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -42,6 +42,11 @@ dmic-codec {
wakeup-delay-ms = <50>;
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
memory@40000000 {
device_type = "memory";
reg = <0 0x40000000 0 0x80000000>;
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 7/7] arm64: dts: qcom: Add #{address,size}-cells to Chromium-based /firmware
From: Brian Norris @ 2026-04-28 20:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
Jonathan Hunter, Heiko Stuebner, Matthias Brugger,
AngeloGioacchino Del Regno, Bjorn Andersson, Konrad Dybcio
Cc: devicetree, Doug Anderson, linux-arm-kernel, Tzung-Bi Shih,
chrome-platform, Brian Norris, linux-rockchip, Julius Werner,
Alim Akhtar, cros-qcom-dts-watchers, linux-arm-msm, linux-tegra,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260428200712.2660635-1-briannorris@chromium.org>
Chromium/Depthcharge bootloaders may dynamically add a few device nodes
to a system's DTB under a /firmware node. A typical DT looks something
like the following:
/ {
firmware {
ranges;
coreboot {
compatible = "coreboot";
reg = <...>;
...;
};
};
};
Notably, the /firmware node has an empty 'ranges', but does not have
address/size-cells.
Commit 6e5773d52f4a ("of/address: Fix WARN when attempting translating
non-translatable addresses") started requiring #address-cells for a
device's parent if we want to use the reg resource in a device node.
This leads to errors like the following:
[ 7.763870] coreboot_table firmware:coreboot: probe with driver coreboot_table failed with error -22
Add appropriate #{address,size}-cells to work around the problem.
Note that Google has also patched the Depthcharge bootloader source to
add {address,size}-cells [1], but bootloader updates are typically
delivered only via Google OS updates. Not all users install Google
software updates, and even if they do, Google may not produce updated
binaries for all/older devices.
[1] https://lore.kernel.org/all/20241209092809.GA3246424@google.com/
https://crrev.com/c/6051580 ("coreboot: Insert #address-cells and
#size-cells for firmware node")
Closes: https://lore.kernel.org/all/aeKlYzTiL0OB1y3g@google.com/
Fixes: 6e5773d52f4a ("of/address: Fix WARN when attempting translating non-translatable addresses")
Signed-off-by: Brian Norris <briannorris@chromium.org>
---
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 5 +++++
arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index b398f69917f0..cd4a0e281cf8 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -99,6 +99,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
/* FIXED REGULATORS - parents above children */
/* This is the top level supply and variable voltage */
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
index 5c5e4f1dd221..58ea0532c0fb 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
@@ -25,6 +25,11 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ firmware {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ };
+
/*
* FIXED REGULATORS
*
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* Re: [PATCH v6 2/6] docs: uapi: media: Document Raspberry Pi NV12 column format
From: Nicolas Dufresne @ 2026-04-28 20:09 UTC (permalink / raw)
To: Dave Stevenson, Sakari Ailus, Laurent Pinchart,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, John Cox, Dom Cobley,
review list, Ezequiel Garcia
Cc: John Cox, Stefan Wahren, linux-media, linux-kernel, devicetree,
linux-rpi-kernel, linux-arm-kernel
In-Reply-To: <20260304-media-rpi-hevc-dec-v6-2-93868ae6dff8@raspberrypi.com>
[-- Attachment #1: Type: text/plain, Size: 3010 bytes --]
Le mercredi 04 mars 2026 à 14:05 +0000, Dave Stevenson a écrit :
> The Raspberry Pi HEVC decoder uses a tiled format based on
> columns for 8 and 10 bit YUV images, so document them as
> NV12MT_COL128 and NV12MT_10_COL128.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
> .../userspace-api/media/v4l/pixfmt-yuv-planar.rst | 46 ++++++++++++++++++++++
> 1 file changed, 46 insertions(+)
>
> diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> index 0631919bd667..1aa4182b8adc 100644
> --- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> +++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> @@ -957,6 +957,52 @@ Data in the 12 high bits, zeros in the 4 low bits, arranged in little endian ord
> - Cr\ :sub:`11`
>
>
> +.. _V4L2-PIX-FMT-NV12MT-COL128:
> +.. _V4L2-PIX-FMT-NV12MT-10-COL128:
> +
> +NV12MT_COL128 and NV12MT_10_COL128
> +----------------------------------
> +
> +``V4L2_PIX_FMT_NV12MT_COL128`` is a tiled version of
> +``V4L2_PIX_FMT_NV12M`` where the two planes are split into 128 byte wide columns
> +of Y or interleaved CbCr. The height is always aligned to a multiple of 8 lines.
> +
> +V4L2_PIX_FMT_NV12MT_10_COL128 expands that as a 10 bit format where 3 10 bit
> +values are packed into a 32bit word. A 128 byte wide column therefore holds 96
> +samples (either Y or interleaved CrCb). That effectively makes it 6 values in a
> +64 bit word for the CbCr plane, as the values always go in pairs.
> +
> +Bit-packed representation.
> +
> +.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 8 8 8 8
> +
> + * - Y'\ :sub:`00[7:0]`
> + - Y'\ :sub:`01[5:0] (bits 7--2)` Y'\ :sub:`00[9:8]`\ (bits 1--0)
> + - Y'\ :sub:`02[3:0] (bits 7--4)` Y'\ :sub:`01[9:6]`\ (bits 3--0)
> + - unused (bits 7--6)` Y'\ :sub:`02[9:4]`\ (bits 5--0)
> +
> +.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}|
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 12 12 12 12 12 12 12 12
> +
> + * - Cb\ :sub:`00[7:0]`
> + - Cr\ :sub:`00[5:0]`\ (bits 7--2) Cb\ :sub:`00[9:8]`\ (bits 1--0)
> + - Cb\ :sub:`01[3:0]`\ (bits 7--4) Cr\ :sub:`00[9:6]`\ (bits 3--0)
> + - unused (bits 7--6) Cb\ :sub:`02[9:4]`\ (bits 5--0)
> + - Cr\ :sub:`01[7:0]`
> + - Cb\ :sub:`02[5:0]`\ (bits 7--2) Cr\ :sub:`01[9:8]`\ (bits 1--0)
> + - Cr\ :sub:`02[3:0]`\ (bits 7--4) Cb\ :sub:`02[9:6]`\ (bits 3--0)
> + - unused (bits 7--6) Cr\ :sub:`02[9:4]`\ (bits 5--0)
> +
> +
> Fully Planar YUV Formats
> ========================
>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v6 3/6] media: ioctl: Add pixel formats NV12MT_COL128 and NV12MT_10_COL128
From: Nicolas Dufresne @ 2026-04-28 20:14 UTC (permalink / raw)
To: Dave Stevenson, Sakari Ailus, Laurent Pinchart,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Florian Fainelli,
Broadcom internal kernel review list, John Cox, Dom Cobley,
review list, Ezequiel Garcia
Cc: John Cox, Stefan Wahren, linux-media, linux-kernel, devicetree,
linux-rpi-kernel, linux-arm-kernel
In-Reply-To: <20260304-media-rpi-hevc-dec-v6-3-93868ae6dff8@raspberrypi.com>
[-- Attachment #1: Type: text/plain, Size: 4259 bytes --]
Le mercredi 04 mars 2026 à 14:05 +0000, Dave Stevenson a écrit :
> Add V4L2_PIXFMT_NV12MT_COL128 and V4L2_PIXFMT_NV12MT_10_COL128
> to describe the Raspberry Pi HEVC decoder NV12 multiplanar formats.
>
> NV12MT_COL128 has been added to v4l2_format_info.
> NV12MT_10_COL128 has not as the block width is not a power of 2,
> but the framework uses ALIGN with the value.
The performance of that code is not critical, any reason you can't just port
everything to round up to the next multiple of ? (to be done in its own patch).
Nicolas
p.s. we should really add a ktest for that table ...
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/v4l2-core/v4l2-common.c | 2 ++
> drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++
> include/uapi/linux/videodev2.h | 4 ++++
> 3 files changed, 8 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> index 554c591e1113..20a7066df570 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -311,6 +311,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
> { .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
> .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 }},
> { .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
> + { .format = V4L2_PIX_FMT_NV12MT_COL128, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
> + /* V4L2_PIX_FMT_NV12MT_10_COL128 can not be described within the current constraints of v4l2_format_info as 96 pixels is not a power of 2 */
>
> /* YUV planar formats, non contiguous variant */
> { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 37d33d4a363d..2fe8f591cdb3 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1379,7 +1379,9 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> case V4L2_PIX_FMT_NV16M: descr = "Y/UV 4:2:2 (N-C)"; break;
> case V4L2_PIX_FMT_NV61M: descr = "Y/VU 4:2:2 (N-C)"; break;
> case V4L2_PIX_FMT_NV12MT: descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
> + case V4L2_PIX_FMT_NV12MT_COL128: descr = "Y/CbCr 4:2:0 (128b cols)"; break;
> case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
> + case V4L2_PIX_FMT_NV12MT_10_COL128: descr = "10-bit Y/CbCr 4:2:0 (128b cols)"; break;
> case V4L2_PIX_FMT_P012M: descr = "12-bit Y/UV 4:2:0 (N-C)"; break;
> case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break;
> case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break;
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index eda4492e40dc..e466c816ff2f 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -697,6 +697,10 @@ struct v4l2_pix_format {
> #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 tiles */
> #define V4L2_PIX_FMT_NV12M_8L128 v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
> #define V4L2_PIX_FMT_NV12M_10BE_8L128 v4l2_fourcc_be('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
> +#define V4L2_PIX_FMT_NV12MT_COL128 v4l2_fourcc('N', 'c', '1', '2') /* 12 Y/CbCr 4:2:0 128 pixel wide column */
> +#define V4L2_PIX_FMT_NV12MT_10_COL128 v4l2_fourcc('N', 'c', '3', '0')
> + /* Y/CbCr 4:2:0 10bpc, 3x10 packed as 4 bytes in a 128 bytes / 96 pixel wide column */
> +
>
> /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
> #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH v3 02/15] firmware: arm_scmi: Add clock determine_rate operation
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Add a clock operation to help determining the effective rate, closest to
the required one, that a specific clock can support.
Calculation is currently performed kernel side and the logic is taken
directly from the SCMI Clock driver: embedding the determinate rate logic
in the protocol layer enables simplifications in the SCMI Clock protocol
interface and will more easily accommodate further evolutions where such
determine_rate logic into is optionally delegated to the platform SCMI
server.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- use the fixed rounding algo using div64_ul
Spoiler alert next SCMI spec will most probably include a new
CLOCK_DETERMINE_RATE command to delegate to the platform such calculations,
so this clock proto_ops will be needed anyway sooner or later
---
drivers/firmware/arm_scmi/clock.c | 42 +++++++++++++++++++++++++++++++
include/linux/scmi_protocol.h | 6 +++++
2 files changed, 48 insertions(+)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index ab36871650a1..54b55517b759 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -5,6 +5,7 @@
* Copyright (C) 2018-2022 ARM Ltd.
*/
+#include <linux/math64.h>
#include <linux/module.h>
#include <linux/limits.h>
#include <linux/sort.h>
@@ -624,6 +625,46 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
return ret;
}
+static int scmi_clock_determine_rate(const struct scmi_protocol_handle *ph,
+ u32 clk_id, unsigned long *rate)
+{
+ u64 fmin, fmax, ftmp;
+ struct scmi_clock_info *clk;
+ struct clock_info *ci = ph->get_priv(ph);
+
+ if (!rate)
+ return -EINVAL;
+
+ clk = scmi_clock_domain_lookup(ci, clk_id);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ /*
+ * If we can't figure out what rate it will be, so just return the
+ * rate back to the caller.
+ */
+ if (clk->rate_discrete)
+ return 0;
+
+ fmin = clk->range.min_rate;
+ fmax = clk->range.max_rate;
+ if (*rate <= fmin) {
+ *rate = fmin;
+ return 0;
+ } else if (*rate >= fmax) {
+ *rate = fmax;
+ return 0;
+ }
+
+ ftmp = *rate - fmin;
+ ftmp += clk->range.step_size - 1; /* to round up */
+ ftmp = div64_ul(ftmp, clk->range.step_size);
+
+ *rate = ftmp * clk->range.step_size + fmin;
+
+ return 0;
+}
+
static int
scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
enum clk_state state,
@@ -936,6 +977,7 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
.info_get = scmi_clock_info_get,
.rate_get = scmi_clock_rate_get,
.rate_set = scmi_clock_rate_set,
+ .determine_rate = scmi_clock_determine_rate,
.enable = scmi_clock_enable,
.disable = scmi_clock_disable,
.state_get = scmi_clock_state_get,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index aafaac1496b0..28579c145045 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -91,6 +91,10 @@ enum scmi_clock_oem_config {
* @info_get: get the information of the specified clock
* @rate_get: request the current clock rate of a clock
* @rate_set: set the clock rate of a clock
+ * @determine_rate: determine the effective rate that can be supported by a
+ * clock calculating the closest allowed rate.
+ * Note that @rate is an input/output parameter used both to
+ * describe the requested rate and report the closest match
* @enable: enables the specified clock
* @disable: disables the specified clock
* @state_get: get the status of the specified clock
@@ -108,6 +112,8 @@ struct scmi_clk_proto_ops {
u64 *rate);
int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
u64 rate);
+ int (*determine_rate)(const struct scmi_protocol_handle *ph, u32 clk_id,
+ unsigned long *rate);
int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id,
bool atomic);
int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id,
--
2.53.0
^ permalink raw reply related
* [PATCH v3 01/15] clk: scmi: Fix clock rate rounding
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Michael Turquette, Stephen Boyd
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
While the do_div() helper used for rounding expects its divisor argument
to be a 32bits quantity, the currently provided divisor parameter is a
64bit value that, as a consequence, is silently truncated and a possible
source of bugs.
Fix by using the proper div64_ul helper.
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: linux-clk@vger.kernel.org
Fixes: 7a8655e19bdb ("clk: scmi: Fix the rounding of clock rate")
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
drivers/clk/clk-scmi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 6b286ea6f121..b6a12f3bc123 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -10,9 +10,9 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/of.h>
+#include <linux/math64.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>
-#include <asm/div64.h>
#define NOT_ATOMIC false
#define ATOMIC true
@@ -83,7 +83,7 @@ static int scmi_clk_determine_rate(struct clk_hw *hw,
ftmp = req->rate - fmin;
ftmp += clk->info->range.step_size - 1; /* to round up */
- do_div(ftmp, clk->info->range.step_size);
+ ftmp = div64_ul(ftmp, clk->info->range.step_size);
req->rate = ftmp * clk->info->range.step_size + fmin;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 04/15] firmware: arm_scmi: Simplify clock rates exposed interface
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Peng Fan
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Introduce a new internal struct scmi_clock_desc so as to be able to hide,
in the future, some of the needlessly public fields currently kept inside
scmi_clock_info, while keeping exposed only the two new min_rate and
max_rate fields for each clock.
No functional change.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- removed useless parenthesis
- reworded comit message
---
drivers/firmware/arm_scmi/clock.c | 145 +++++++++++++++---------------
include/linux/scmi_protocol.h | 2 +
2 files changed, 74 insertions(+), 73 deletions(-)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 54b55517b759..467b13a3a18f 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -157,13 +157,27 @@ struct scmi_clock_rate_notify_payld {
__le32 rate_high;
};
+struct scmi_clock_desc {
+ u32 id;
+ bool rate_discrete;
+ unsigned int num_rates;
+ u64 rates[SCMI_MAX_NUM_RATES];
+#define RATE_MIN 0
+#define RATE_MAX 1
+#define RATE_STEP 2
+ struct scmi_clock_info info;
+};
+
+#define to_desc(p) (container_of(p, struct scmi_clock_desc, info))
+
struct clock_info {
int num_clocks;
int max_async_req;
bool notify_rate_changed_cmd;
bool notify_rate_change_requested_cmd;
atomic_t cur_async_req;
- struct scmi_clock_info *clk;
+ struct scmi_clock_desc *clkds;
+#define CLOCK_INFO(c, i) (&(((c)->clkds + (i))->info))
int (*clock_config_set)(const struct scmi_protocol_handle *ph,
u32 clk_id, enum clk_state state,
enum scmi_clock_oem_config oem_type,
@@ -185,7 +199,7 @@ scmi_clock_domain_lookup(struct clock_info *ci, u32 clk_id)
if (clk_id >= ci->num_clocks)
return ERR_PTR(-EINVAL);
- return ci->clk + clk_id;
+ return CLOCK_INFO(ci, clk_id);
}
static int
@@ -226,8 +240,7 @@ scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
struct scmi_clk_ipriv {
struct device *dev;
- u32 clk_id;
- struct scmi_clock_info *clk;
+ struct scmi_clock_desc *clkd;
};
static void iter_clk_possible_parents_prepare_message(void *message, unsigned int desc_index,
@@ -236,7 +249,7 @@ static void iter_clk_possible_parents_prepare_message(void *message, unsigned in
struct scmi_msg_clock_possible_parents *msg = message;
const struct scmi_clk_ipriv *p = priv;
- msg->id = cpu_to_le32(p->clk_id);
+ msg->id = cpu_to_le32(p->clkd->id);
/* Set the number of OPPs to be skipped/already read */
msg->skip_parents = cpu_to_le32(desc_index);
}
@@ -246,7 +259,6 @@ static int iter_clk_possible_parents_update_state(struct scmi_iterator_state *st
{
const struct scmi_msg_resp_clock_possible_parents *r = response;
struct scmi_clk_ipriv *p = priv;
- struct device *dev = ((struct scmi_clk_ipriv *)p)->dev;
u32 flags;
flags = le32_to_cpu(r->num_parent_flags);
@@ -258,12 +270,13 @@ static int iter_clk_possible_parents_update_state(struct scmi_iterator_state *st
* assume it's returned+remaining on first call.
*/
if (!st->max_resources) {
- p->clk->num_parents = st->num_returned + st->num_remaining;
- p->clk->parents = devm_kcalloc(dev, p->clk->num_parents,
- sizeof(*p->clk->parents),
- GFP_KERNEL);
- if (!p->clk->parents) {
- p->clk->num_parents = 0;
+ p->clkd->info.num_parents = st->num_returned + st->num_remaining;
+ p->clkd->info.parents = devm_kcalloc(p->dev,
+ p->clkd->info.num_parents,
+ sizeof(*p->clkd->info.parents),
+ GFP_KERNEL);
+ if (!p->clkd->info.parents) {
+ p->clkd->info.num_parents = 0;
return -ENOMEM;
}
st->max_resources = st->num_returned + st->num_remaining;
@@ -280,29 +293,27 @@ static int iter_clk_possible_parents_process_response(const struct scmi_protocol
const struct scmi_msg_resp_clock_possible_parents *r = response;
struct scmi_clk_ipriv *p = priv;
- u32 *parent = &p->clk->parents[st->desc_index + st->loop_idx];
+ u32 *parent = &p->clkd->info.parents[st->desc_index + st->loop_idx];
*parent = le32_to_cpu(r->possible_parents[st->loop_idx]);
return 0;
}
-static int scmi_clock_possible_parents(const struct scmi_protocol_handle *ph, u32 clk_id,
- struct scmi_clock_info *clk)
+static int scmi_clock_possible_parents(const struct scmi_protocol_handle *ph,
+ u32 clk_id, struct clock_info *cinfo)
{
struct scmi_iterator_ops ops = {
.prepare_message = iter_clk_possible_parents_prepare_message,
.update_state = iter_clk_possible_parents_update_state,
.process_response = iter_clk_possible_parents_process_response,
};
-
+ struct scmi_clock_desc *clkd = &cinfo->clkds[clk_id];
struct scmi_clk_ipriv ppriv = {
- .clk_id = clk_id,
- .clk = clk,
+ .clkd = clkd,
.dev = ph->dev,
};
void *iter;
- int ret;
iter = ph->hops->iter_response_init(ph, &ops, 0,
CLOCK_POSSIBLE_PARENTS_GET,
@@ -311,9 +322,7 @@ static int scmi_clock_possible_parents(const struct scmi_protocol_handle *ph, u3
if (IS_ERR(iter))
return PTR_ERR(iter);
- ret = ph->hops->iter_response_run(iter);
-
- return ret;
+ return ph->hops->iter_response_run(iter);
}
static int
@@ -352,7 +361,7 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
u32 attributes;
struct scmi_xfer *t;
struct scmi_msg_resp_clock_attributes *attr;
- struct scmi_clock_info *clk = cinfo->clk + clk_id;
+ struct scmi_clock_info *clk = CLOCK_INFO(cinfo, clk_id);
ret = ph->xops->xfer_get_init(ph, CLOCK_ATTRIBUTES,
sizeof(clk_id), sizeof(*attr), &t);
@@ -394,7 +403,7 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
clk->rate_change_requested_notifications = true;
if (PROTOCOL_REV_MAJOR(ph->version) >= 0x3) {
if (SUPPORTS_PARENT_CLOCK(attributes))
- scmi_clock_possible_parents(ph, clk_id, clk);
+ scmi_clock_possible_parents(ph, clk_id, cinfo);
if (SUPPORTS_GET_PERMISSIONS(attributes))
scmi_clock_get_permissions(ph, clk_id, clk);
if (SUPPORTS_EXTENDED_CONFIG(attributes))
@@ -424,7 +433,7 @@ static void iter_clk_describe_prepare_message(void *message,
struct scmi_msg_clock_describe_rates *msg = message;
const struct scmi_clk_ipriv *p = priv;
- msg->id = cpu_to_le32(p->clk_id);
+ msg->id = cpu_to_le32(p->clkd->id);
/* Set the number of rates to be skipped/already read */
msg->rate_index = cpu_to_le32(desc_index);
}
@@ -457,14 +466,14 @@ iter_clk_describe_update_state(struct scmi_iterator_state *st,
flags = le32_to_cpu(r->num_rates_flags);
st->num_remaining = NUM_REMAINING(flags);
st->num_returned = NUM_RETURNED(flags);
- p->clk->rate_discrete = RATE_DISCRETE(flags);
+ p->clkd->rate_discrete = RATE_DISCRETE(flags);
/* Warn about out of spec replies ... */
- if (!p->clk->rate_discrete &&
+ if (!p->clkd->rate_discrete &&
(st->num_returned != 3 || st->num_remaining != 0)) {
dev_warn(p->dev,
"Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining:%d rx_len:%zd\n",
- p->clk->name, st->num_returned, st->num_remaining,
+ p->clkd->info.name, st->num_returned, st->num_remaining,
st->rx_len);
SCMI_QUIRK(clock_rates_triplet_out_of_spec,
@@ -479,38 +488,19 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph,
const void *response,
struct scmi_iterator_state *st, void *priv)
{
- int ret = 0;
struct scmi_clk_ipriv *p = priv;
const struct scmi_msg_resp_clock_describe_rates *r = response;
- if (!p->clk->rate_discrete) {
- switch (st->desc_index + st->loop_idx) {
- case 0:
- p->clk->range.min_rate = RATE_TO_U64(r->rate[0]);
- break;
- case 1:
- p->clk->range.max_rate = RATE_TO_U64(r->rate[1]);
- break;
- case 2:
- p->clk->range.step_size = RATE_TO_U64(r->rate[2]);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- } else {
- u64 *rate = &p->clk->list.rates[st->desc_index + st->loop_idx];
+ p->clkd->rates[st->desc_index + st->loop_idx] =
+ RATE_TO_U64(r->rate[st->loop_idx]);
+ p->clkd->num_rates++;
- *rate = RATE_TO_U64(r->rate[st->loop_idx]);
- p->clk->list.num_rates++;
- }
-
- return ret;
+ return 0;
}
static int
scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
- struct scmi_clock_info *clk)
+ struct clock_info *cinfo)
{
int ret;
void *iter;
@@ -519,9 +509,9 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
.update_state = iter_clk_describe_update_state,
.process_response = iter_clk_describe_process_response,
};
+ struct scmi_clock_desc *clkd = &cinfo->clkds[clk_id];
struct scmi_clk_ipriv cpriv = {
- .clk_id = clk_id,
- .clk = clk,
+ .clkd = clkd,
.dev = ph->dev,
};
@@ -536,16 +526,23 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
if (ret)
return ret;
- if (!clk->rate_discrete) {
+ /* empty set ? */
+ if (!clkd->num_rates)
+ return 0;
+
+ if (!clkd->rate_discrete) {
+ clkd->info.max_rate = clkd->rates[RATE_MAX];
dev_dbg(ph->dev, "Min %llu Max %llu Step %llu Hz\n",
- clk->range.min_rate, clk->range.max_rate,
- clk->range.step_size);
- } else if (clk->list.num_rates) {
- sort(clk->list.rates, clk->list.num_rates,
- sizeof(clk->list.rates[0]), rate_cmp_func, NULL);
+ clkd->rates[RATE_MIN], clkd->rates[RATE_MAX],
+ clkd->rates[RATE_STEP]);
+ } else {
+ sort(clkd->rates, clkd->num_rates,
+ sizeof(clkd->rates[0]), rate_cmp_func, NULL);
+ clkd->info.max_rate = clkd->rates[clkd->num_rates - 1];
}
+ clkd->info.min_rate = clkd->rates[RATE_MIN];
- return ret;
+ return 0;
}
static int
@@ -630,6 +627,7 @@ static int scmi_clock_determine_rate(const struct scmi_protocol_handle *ph,
{
u64 fmin, fmax, ftmp;
struct scmi_clock_info *clk;
+ struct scmi_clock_desc *clkd;
struct clock_info *ci = ph->get_priv(ph);
if (!rate)
@@ -639,15 +637,17 @@ static int scmi_clock_determine_rate(const struct scmi_protocol_handle *ph,
if (IS_ERR(clk))
return PTR_ERR(clk);
+ clkd = to_desc(clk);
+
/*
* If we can't figure out what rate it will be, so just return the
* rate back to the caller.
*/
- if (clk->rate_discrete)
+ if (clkd->rate_discrete)
return 0;
- fmin = clk->range.min_rate;
- fmax = clk->range.max_rate;
+ fmin = clk->min_rate;
+ fmax = clk->max_rate;
if (*rate <= fmin) {
*rate = fmin;
return 0;
@@ -657,10 +657,10 @@ static int scmi_clock_determine_rate(const struct scmi_protocol_handle *ph,
}
ftmp = *rate - fmin;
- ftmp += clk->range.step_size - 1; /* to round up */
- ftmp = div64_ul(ftmp, clk->range.step_size);
+ ftmp += clkd->rates[RATE_STEP] - 1; /* to round up */
+ ftmp = div64_ul(ftmp, clkd->rates[RATE_STEP]);
- *rate = ftmp * clk->range.step_size + fmin;
+ *rate = ftmp * clkd->rates[RATE_STEP] + fmin;
return 0;
}
@@ -1122,17 +1122,16 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
if (ret)
return ret;
- cinfo->clk = devm_kcalloc(ph->dev, cinfo->num_clocks,
- sizeof(*cinfo->clk), GFP_KERNEL);
- if (!cinfo->clk)
+ cinfo->clkds = devm_kcalloc(ph->dev, cinfo->num_clocks,
+ sizeof(*cinfo->clkds), GFP_KERNEL);
+ if (!cinfo->clkds)
return -ENOMEM;
for (clkid = 0; clkid < cinfo->num_clocks; clkid++) {
- struct scmi_clock_info *clk = cinfo->clk + clkid;
-
+ cinfo->clkds[clkid].id = clkid;
ret = scmi_clock_attributes_get(ph, clkid, cinfo);
if (!ret)
- scmi_clock_describe_rates_get(ph, clkid, clk);
+ scmi_clock_describe_rates_get(ph, clkid, cinfo);
}
if (PROTOCOL_REV_MAJOR(ph->version) >= 0x3) {
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 28579c145045..7283302b0c85 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -51,6 +51,8 @@ struct scmi_clock_info {
bool rate_ctrl_forbidden;
bool parent_ctrl_forbidden;
bool extended_config;
+ u64 min_rate;
+ u64 max_rate;
union {
struct {
int num_rates;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 05/15] clk: scmi: Use new simplified per-clock rate properties
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Michael Turquette, Stephen Boyd, Peng Fan
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Use the new min_rate and max_rate unified properties that provide the
proper values without having to consider the clock type.
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: linux-clk@vger.kernel.org
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- Collected Peng Reviewed-by tag
---
drivers/clk/clk-scmi.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index c223e4ef1dd1..7c562559ad8b 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -202,7 +202,6 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
const struct clk_ops *scmi_ops)
{
int ret;
- unsigned long min_rate, max_rate;
struct clk_init_data init = {
.flags = CLK_GET_RATE_NOCACHE,
@@ -217,20 +216,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
if (ret)
return ret;
- if (sclk->info->rate_discrete) {
- int num_rates = sclk->info->list.num_rates;
-
- if (num_rates <= 0)
- return -EINVAL;
-
- min_rate = sclk->info->list.rates[0];
- max_rate = sclk->info->list.rates[num_rates - 1];
- } else {
- min_rate = sclk->info->range.min_rate;
- max_rate = sclk->info->range.max_rate;
- }
-
- clk_hw_set_rate_range(&sclk->hw, min_rate, max_rate);
+ clk_hw_set_rate_range(&sclk->hw, sclk->info->min_rate,
+ sclk->info->max_rate);
return ret;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 00/15] SCMI Clock rates discovery rework
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi
Hi,
it was a known limitation, in the SCMI Clock protocol support, the lack of
dynamic allocation around per-clock rates discovery: fixed size statically
per-clock rates arrays did not scale and was increasingly a waste of memory
(see [1]).
This series aim at solving this in successive steps:
- simplify and reduce to the minimum possible the rates data info exposed
to the SCMI driver by scmi_clock_info
- move away from static fixed allocation of per-clock rates arrays in
favour of a completely dynamic runtime allocation: just allocate what
is needed based on the effectively discovered
This is done in patches 2-6.
A further bigger optimization suggested in a past series [2] by Etienne
would be, whenever allowed by the spec, to limit upfront the number of
queries in order to simply retrieve min and max rate, that are indeed the
only rates needed by the CLK SCMI driver.
The approach proposed in [1] was open coding and duplicating some of the
functionalities already provided by SCMI iterators, though.
Patch 7-14 implement such optimization instead by:
- reworking core SCMI iterators to support bound enumerations
- use such new bound iterators to perform the minimum number of queries
in order to only retrieve min an max rate
As a final result now the rates enumeration triggered by the CLK SCMI
driver, while still allocating for all the existent rates, miminize the
number of SCMI CLK_DESCRIBE_RATE messages needed to obtain min and max.
Finally, patch 15 introduces a new clock protocol operation to be able to
trigger anytime on demand a full enumeration and obtain the full list of
rates when needed, not only min/max: this latter method is really only used
currently by some dowstream SCMI Test driver of mine.
Most notably in this V3 I had:
- picked up Geert fixes on V2: these could have been squashed in the
original series while maintaining proper Geert's authorship but as of
now I have simply picked them up and changed their order to be near the
commit they fix
- dropped the "Harden Clock protocol initialization" patch that caused a
number of out-of-spec vendor FW to break
Based on v7.1-rc1.
Tested on ARM/JUNO, RADXA/ROCK5B and an emulated environment.
Any feeback welcome.
Thanks,
Cristian
[1]: https://lore.kernel.org/arm-scmi/aZsX-oplR6fiLBBN@pluto/T/#t
[2]: https://lore.kernel.org/20241203173908.3148794-2-etienne.carriere@foss.st.com
---
v2 --> v3
- Rebased on v7.1-rc1
- Picked up Geert fixes
- Dropped patch breaking out-of-spec FW (Harden Clock Protocol init)
- Collected Reviewed tags
v1 --> v2
- Rebased on v7.0-rc3
- Added a Fixes patch to rectify bug in rounding algo
- Removed useless parenthesis in macros
- Collected a few Reviewed-by tags
- Clarified commit message
Cristian Marussi (12):
clk: scmi: Fix clock rate rounding
firmware: arm_scmi: Add clock determine_rate operation
clk: scmi: Use new determine_rate clock operation
firmware: arm_scmi: Simplify clock rates exposed interface
clk: scmi: Use new simplified per-clock rate properties
firmware: arm_scmi: Drop unused clock rate interfaces
firmware: arm_scmi: Make clock rates allocation dynamic
firmware: arm_scmi: Harden clock parents discovery
firmware: arm_scmi: Refactor iterators internal allocation
firmware: arm_scmi: Add bound iterators support
firmware: arm_scmi: Use bound iterators to minimize discovered rates
firmware: arm_scmi: Introduce all_rates_get clock operation
Geert Uytterhoeven (3):
firmware: arm_scmi: Fix bound iterators returning too many items
firmware: arm_scmi: Use proper iter_response_bound_cleanup() name
firmware: arm_scmi: Fix OOB in scmi_clock_describe_rates_get_lazy()
drivers/clk/clk-scmi.c | 48 +---
drivers/firmware/arm_scmi/clock.c | 301 ++++++++++++++++++++------
drivers/firmware/arm_scmi/driver.c | 80 +++++--
drivers/firmware/arm_scmi/protocols.h | 13 +-
include/linux/scmi_protocol.h | 29 ++-
5 files changed, 324 insertions(+), 147 deletions(-)
--
2.53.0
^ permalink raw reply
* [PATCH v3 03/15] clk: scmi: Use new determine_rate clock operation
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Brian Masney, Michael Turquette, Stephen Boyd
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Use the Clock protocol layer determine_rate logic to calculate the closest
rate that can be supported by a specific clock.
No functional change.
Cc: Brian Masney <bmasney@redhat.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: linux-clk@vger.kernel.org
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
@brian: I'd modify further this clk-scmi driver, with a patch on top of
this series, to properly use your new CLK_ROUNDING_NOOP flag once your
series AND another (already reviewed) series on clk-scmi from Peng are in.
---
drivers/clk/clk-scmi.c | 31 ++++++-------------------------
1 file changed, 6 insertions(+), 25 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index b6a12f3bc123..c223e4ef1dd1 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -10,7 +10,6 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/of.h>
-#include <linux/math64.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>
@@ -57,35 +56,17 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
static int scmi_clk_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
- u64 fmin, fmax, ftmp;
+ int ret;
struct scmi_clk *clk = to_scmi_clk(hw);
/*
- * We can't figure out what rate it will be, so just return the
- * rate back to the caller. scmi_clk_recalc_rate() will be called
- * after the rate is set and we'll know what rate the clock is
+ * If we could not get a better rate scmi_clk_recalc_rate() will be
+ * called after the rate is set and we'll know what rate the clock is
* running at then.
*/
- if (clk->info->rate_discrete)
- return 0;
-
- fmin = clk->info->range.min_rate;
- fmax = clk->info->range.max_rate;
- if (req->rate <= fmin) {
- req->rate = fmin;
-
- return 0;
- } else if (req->rate >= fmax) {
- req->rate = fmax;
-
- return 0;
- }
-
- ftmp = req->rate - fmin;
- ftmp += clk->info->range.step_size - 1; /* to round up */
- ftmp = div64_ul(ftmp, clk->info->range.step_size);
-
- req->rate = ftmp * clk->info->range.step_size + fmin;
+ ret = scmi_proto_clk_ops->determine_rate(clk->ph, clk->id, &req->rate);
+ if (ret)
+ return ret;
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 08/15] firmware: arm_scmi: Harden clock parents discovery
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Peng Fan
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Fix clock parents enumeration to account only for effectively discovered
parents during enumeration, avoiding to trust the total number of parents
declared upfront by the platform.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v2 --> v3
- collected Reviewed-by tags
---
drivers/firmware/arm_scmi/clock.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index c9b62edce4fd..d07cfef243fd 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -270,15 +270,15 @@ static int iter_clk_possible_parents_update_state(struct scmi_iterator_state *st
* assume it's returned+remaining on first call.
*/
if (!st->max_resources) {
- p->clkd->info.num_parents = st->num_returned + st->num_remaining;
- p->clkd->info.parents = devm_kcalloc(p->dev,
- p->clkd->info.num_parents,
+ int num_parents = st->num_returned + st->num_remaining;
+
+ p->clkd->info.parents = devm_kcalloc(p->dev, num_parents,
sizeof(*p->clkd->info.parents),
GFP_KERNEL);
- if (!p->clkd->info.parents) {
- p->clkd->info.num_parents = 0;
+ if (!p->clkd->info.parents)
return -ENOMEM;
- }
+
+ /* max_resources is used by the iterators to control bounds */
st->max_resources = st->num_returned + st->num_remaining;
}
@@ -293,9 +293,11 @@ static int iter_clk_possible_parents_process_response(const struct scmi_protocol
const struct scmi_msg_resp_clock_possible_parents *r = response;
struct scmi_clk_ipriv *p = priv;
- u32 *parent = &p->clkd->info.parents[st->desc_index + st->loop_idx];
+ p->clkd->info.parents[st->desc_index + st->loop_idx] =
+ le32_to_cpu(r->possible_parents[st->loop_idx]);
- *parent = le32_to_cpu(r->possible_parents[st->loop_idx]);
+ /* Count only effectively discovered parents */
+ p->clkd->info.num_parents++;
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 07/15] firmware: arm_scmi: Make clock rates allocation dynamic
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Peng Fan
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Leveraging SCMI Clock protocol dynamic discovery capabilities, move away
from the static per-clock rates allocation model in favour of a dynamic
runtime allocation based on effectively discovered resources.
No functional change.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v2 --> v3
- collected Review-by tags
---
drivers/firmware/arm_scmi/clock.c | 19 ++++++++++++++++---
include/linux/scmi_protocol.h | 1 -
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 467b13a3a18f..c9b62edce4fd 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -161,7 +161,7 @@ struct scmi_clock_desc {
u32 id;
bool rate_discrete;
unsigned int num_rates;
- u64 rates[SCMI_MAX_NUM_RATES];
+ u64 *rates;
#define RATE_MIN 0
#define RATE_MAX 1
#define RATE_STEP 2
@@ -480,6 +480,18 @@ iter_clk_describe_update_state(struct scmi_iterator_state *st,
QUIRK_OUT_OF_SPEC_TRIPLET);
}
+ if (!st->max_resources) {
+ int num_rates = st->num_returned + st->num_remaining;
+
+ p->clkd->rates = devm_kcalloc(p->dev, num_rates,
+ sizeof(*p->clkd->rates), GFP_KERNEL);
+ if (!p->clkd->rates)
+ return -ENOMEM;
+
+ /* max_resources is used by the iterators to control bounds */
+ st->max_resources = st->num_returned + st->num_remaining;
+ }
+
return 0;
}
@@ -493,6 +505,8 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph,
p->clkd->rates[st->desc_index + st->loop_idx] =
RATE_TO_U64(r->rate[st->loop_idx]);
+
+ /* Count only effectively discovered rates */
p->clkd->num_rates++;
return 0;
@@ -515,8 +529,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
.dev = ph->dev,
};
- iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES,
- CLOCK_DESCRIBE_RATES,
+ iter = ph->hops->iter_response_init(ph, &ops, 0, CLOCK_DESCRIBE_RATES,
sizeof(struct scmi_msg_clock_describe_rates),
&cpriv);
if (IS_ERR(iter))
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index d97b4e734744..5552ac04c820 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -15,7 +15,6 @@
#define SCMI_MAX_STR_SIZE 64
#define SCMI_SHORT_NAME_MAX_SIZE 16
-#define SCMI_MAX_NUM_RATES 16
/**
* struct scmi_revision_info - version information structure
--
2.53.0
^ permalink raw reply related
* [PATCH v3 06/15] firmware: arm_scmi: Drop unused clock rate interfaces
From: Cristian Marussi @ 2026-04-28 20:15 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-clk,
linux-renesas-soc
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
geert+renesas, kuninori.morimoto.gx, marek.vasut+renesas,
Cristian Marussi, Peng Fan
In-Reply-To: <20260428201522.903875-1-cristian.marussi@arm.com>
Only the unified interface exposing min_rate/max_rate is now used.
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- Collected Peng Reviewed-by tag
---
include/linux/scmi_protocol.h | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 7283302b0c85..d97b4e734744 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -53,17 +53,6 @@ struct scmi_clock_info {
bool extended_config;
u64 min_rate;
u64 max_rate;
- union {
- struct {
- int num_rates;
- u64 rates[SCMI_MAX_NUM_RATES];
- } list;
- struct {
- u64 min_rate;
- u64 max_rate;
- u64 step_size;
- } range;
- };
int num_parents;
u32 *parents;
};
--
2.53.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