* Re: [PATCH v2] raid6: arm64: add SVE optimized implementation for syndrome generation
From: Ard Biesheuvel @ 2026-03-24 8:00 UTC (permalink / raw)
To: Demian Shulhan, Song Liu, Yu Kuai, Will Deacon, Catalin Marinas,
Mark Rutland, broonie, linux-arm-kernel, robin.murphy,
Christoph Hellwig
Cc: Li Nan, linux-raid, linux-kernel
In-Reply-To: <20260318150245.3080719-1-demyansh@gmail.com>
Hi Damian,
On Wed, 18 Mar 2026, at 16:02, Demian Shulhan wrote:
> Implement Scalable Vector Extension (SVE) optimized routines for RAID6
> syndrome generation and recovery on ARM64.
>
> The SVE instruction set allows for variable vector lengths (from 128 to
> 2048 bits), scaling automatically with the hardware capabilities. This
> implementation handles arbitrary SVE vector lengths using the `cntb`
> instruction to determine the runtime vector length.
>
> The implementation introduces `svex1`, `svex2`, and `svex4` algorithms.
> The `svex4` algorithm utilizes loop unrolling by 4 blocks per iteration
> and manual software pipelining (interleaving memory loads with XORs)
> to minimize instruction dependency stalls and maximize CPU pipeline
> utilization and memory bandwidth.
>
> Performance was tested on an AWS Graviton3 (Neoverse-V1) instance which
> features 256-bit SVE vector length. The `svex4` implementation outperforms
> the existing 128-bit `neonx4` baseline for syndrome generation:
>
> raid6: svex4 gen() 19688 MB/s
...
> raid6: neonx4 gen() 19612 MB/s
You're being very generous characterising a 0.3% speedup as 'outperforms'
But the real problem here is that the kernel-mode SIMD API only supports NEON and not SVE, and preserves/restores only the 128-bit view on the NEON/SVE register file. So any context switch or softirq that uses kernel-mode SIMD too, and your SVE register values will get truncated.
Once we encounter a good use case for SVE in the kernel, we might reconsider this, but as it stands, this patch should not be applied.
(leaving the reply untrimmed for the benefit of the cc'ees I added)
> raid6: neonx2 gen() 16248 MB/s
> raid6: neonx1 gen() 13591 MB/s
> raid6: using algorithm svex4 gen() 19688 MB/s
> raid6: .... xor() 11212 MB/s, rmw enabled
> raid6: using neon recovery algorithm
>
> Note that for the recovery path (`xor_syndrome`), NEON may still be
> selected dynamically by the algorithm benchmark, as the recovery
> workload is heavily memory-bound.
>
> Signed-off-by: Demian Shulhan <demyansh@gmail.com>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes:
> https://lore.kernel.org/oe-kbuild-all/202603181940.cFwYmYoi-lkp@intel.com/
> ---
> include/linux/raid/pq.h | 3 +
> lib/raid6/Makefile | 5 +
> lib/raid6/algos.c | 5 +
> lib/raid6/sve.c | 675 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 688 insertions(+)
> create mode 100644 lib/raid6/sve.c
>
> diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
> index 2467b3be15c9..787cc57aea9d 100644
> --- a/include/linux/raid/pq.h
> +++ b/include/linux/raid/pq.h
> @@ -140,6 +140,9 @@ extern const struct raid6_calls raid6_neonx1;
> extern const struct raid6_calls raid6_neonx2;
> extern const struct raid6_calls raid6_neonx4;
> extern const struct raid6_calls raid6_neonx8;
> +extern const struct raid6_calls raid6_svex1;
> +extern const struct raid6_calls raid6_svex2;
> +extern const struct raid6_calls raid6_svex4;
>
> /* Algorithm list */
> extern const struct raid6_calls * const raid6_algos[];
> diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile
> index 5be0a4e60ab1..6cdaa6f206fb 100644
> --- a/lib/raid6/Makefile
> +++ b/lib/raid6/Makefile
> @@ -8,6 +8,7 @@ raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o
> mmx.o sse1.o sse2.o avx2.o
> raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o
> altivec8.o \
> vpermxor1.o vpermxor2.o vpermxor4.o
> vpermxor8.o
> raid6_pq-$(CONFIG_KERNEL_MODE_NEON) += neon.o neon1.o neon2.o neon4.o
> neon8.o recov_neon.o recov_neon_inner.o
> +raid6_pq-$(CONFIG_ARM64_SVE) += sve.o
> raid6_pq-$(CONFIG_S390) += s390vx8.o recov_s390xc.o
> raid6_pq-$(CONFIG_LOONGARCH) += loongarch_simd.o recov_loongarch_simd.o
> raid6_pq-$(CONFIG_RISCV_ISA_V) += rvv.o recov_rvv.o
> @@ -67,6 +68,10 @@ CFLAGS_REMOVE_neon2.o += $(CC_FLAGS_NO_FPU)
> CFLAGS_REMOVE_neon4.o += $(CC_FLAGS_NO_FPU)
> CFLAGS_REMOVE_neon8.o += $(CC_FLAGS_NO_FPU)
> CFLAGS_REMOVE_recov_neon_inner.o += $(CC_FLAGS_NO_FPU)
> +
> +CFLAGS_sve.o += $(CC_FLAGS_FPU)
> +CFLAGS_REMOVE_sve.o += $(CC_FLAGS_NO_FPU)
> +
> targets += neon1.c neon2.c neon4.c neon8.c
> $(obj)/neon%.c: $(src)/neon.uc $(src)/unroll.awk FORCE
> $(call if_changed,unroll)
> diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
> index 799e0e5eac26..0ae73c3a4be3 100644
> --- a/lib/raid6/algos.c
> +++ b/lib/raid6/algos.c
> @@ -66,6 +66,11 @@ const struct raid6_calls * const raid6_algos[] = {
> &raid6_neonx2,
> &raid6_neonx1,
> #endif
> +#ifdef CONFIG_ARM64_SVE
> + &raid6_svex4,
> + &raid6_svex2,
> + &raid6_svex1,
> +#endif
> #ifdef CONFIG_LOONGARCH
> #ifdef CONFIG_CPU_HAS_LASX
> &raid6_lasx,
> diff --git a/lib/raid6/sve.c b/lib/raid6/sve.c
> new file mode 100644
> index 000000000000..d52937f806d4
> --- /dev/null
> +++ b/lib/raid6/sve.c
> @@ -0,0 +1,675 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * RAID-6 syndrome calculation using ARM SVE instructions
> + */
> +
> +#include <linux/raid/pq.h>
> +
> +#ifdef __KERNEL__
> +#include <asm/simd.h>
> +#include <linux/cpufeature.h>
> +#else
> +#define scoped_ksimd()
> +#define system_supports_sve() (1)
> +#endif
> +
> +static void raid6_sve1_gen_syndrome_real(int disks, unsigned long
> bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = disks - 3;
> +
> + p = dptr[z0 + 1];
> + q = dptr[z0 + 2];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z0.b, p0/z, [x6, x5]\n"
> + "mov z1.d, z0.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, #0\n"
> + "blt 2f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> +
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> +
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> +
> + "add x5, x5, x3\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4"
> + );
> +}
> +
> +static void raid6_sve1_xor_syndrome_real(int disks, int start, int
> stop,
> + unsigned long bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = stop;
> +
> + p = dptr[disks - 2];
> + q = dptr[disks - 1];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z1.b, p0/z, [x6, x5]\n"
> + "ld1b z0.b, p0/z, [%[p], x5]\n"
> + "eor z0.d, z0.d, z1.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, %w[start]\n"
> + "blt 2f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> +
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "mov w7, %w[start]\n"
> + "sub w7, w7, #1\n"
> + "3:\n"
> + "cmp w7, #0\n"
> + "blt 4f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 3b\n"
> + "4:\n"
> +
> + "ld1b z2.b, p0/z, [%[q], x5]\n"
> + "eor z1.d, z1.d, z2.d\n"
> +
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> +
> + "add x5, x5, x3\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q), [start] "r" (start)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4"
> + );
> +}
> +
> +static void raid6_sve2_gen_syndrome_real(int disks, unsigned long
> bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = disks - 3;
> +
> + p = dptr[z0 + 1];
> + q = dptr[z0 + 2];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z0.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z5.b, p0/z, [x6, x8]\n"
> + "mov z1.d, z0.d\n"
> + "mov z6.d, z5.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, #0\n"
> + "blt 2f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> +
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [x6, x8]\n"
> +
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + "eor z6.d, z6.d, z7.d\n"
> + "eor z5.d, z5.d, z7.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> + "add x8, x5, x3\n"
> + "st1b z5.b, p0, [%[p], x8]\n"
> + "st1b z6.b, p0, [%[q], x8]\n"
> +
> + "add x5, x5, x3\n"
> + "add x5, x5, x3\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4",
> + "z5", "z6", "z7", "z8"
> + );
> +}
> +
> +static void raid6_sve2_xor_syndrome_real(int disks, int start, int
> stop,
> + unsigned long bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = stop;
> +
> + p = dptr[disks - 2];
> + q = dptr[disks - 1];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z1.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z6.b, p0/z, [x6, x8]\n"
> +
> + "ld1b z0.b, p0/z, [%[p], x5]\n"
> + "ld1b z5.b, p0/z, [%[p], x8]\n"
> +
> + "eor z0.d, z0.d, z1.d\n"
> + "eor z5.d, z5.d, z6.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, %w[start]\n"
> + "blt 2f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> +
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [x6, x8]\n"
> +
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + "eor z6.d, z6.d, z7.d\n"
> + "eor z5.d, z5.d, z7.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "mov w7, %w[start]\n"
> + "sub w7, w7, #1\n"
> + "3:\n"
> + "cmp w7, #0\n"
> + "blt 4f\n"
> +
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 3b\n"
> + "4:\n"
> +
> + "ld1b z2.b, p0/z, [%[q], x5]\n"
> + "eor z1.d, z1.d, z2.d\n"
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> +
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [%[q], x8]\n"
> + "eor z6.d, z6.d, z7.d\n"
> + "st1b z5.b, p0, [%[p], x8]\n"
> + "st1b z6.b, p0, [%[q], x8]\n"
> +
> + "add x5, x5, x3\n"
> + "add x5, x5, x3\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q), [start] "r" (start)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4",
> + "z5", "z6", "z7", "z8"
> + );
> +}
> +
> +static void raid6_sve4_gen_syndrome_real(int disks, unsigned long
> bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = disks - 3;
> +
> + p = dptr[z0 + 1];
> + q = dptr[z0 + 2];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z0.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z5.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z10.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z15.b, p0/z, [x6, x8]\n"
> +
> + "mov z1.d, z0.d\n"
> + "mov z6.d, z5.d\n"
> + "mov z11.d, z10.d\n"
> + "mov z16.d, z15.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, #0\n"
> + "blt 2f\n"
> +
> + // software pipelining: load data early
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z12.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z17.b, p0/z, [x6, x8]\n"
> +
> + // math block 1
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + // math block 2
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> + "eor z6.d, z6.d, z7.d\n"
> + "eor z5.d, z5.d, z7.d\n"
> +
> + // math block 3
> + "mov z13.d, z11.d\n"
> + "asr z13.b, p0/m, z13.b, #7\n"
> + "lsl z11.b, p0/m, z11.b, #1\n"
> + "and z13.d, z13.d, z4.d\n"
> + "eor z11.d, z11.d, z13.d\n"
> + "eor z11.d, z11.d, z12.d\n"
> + "eor z10.d, z10.d, z12.d\n"
> +
> + // math block 4
> + "mov z18.d, z16.d\n"
> + "asr z18.b, p0/m, z18.b, #7\n"
> + "lsl z16.b, p0/m, z16.b, #1\n"
> + "and z18.d, z18.d, z4.d\n"
> + "eor z16.d, z16.d, z18.d\n"
> + "eor z16.d, z16.d, z17.d\n"
> + "eor z15.d, z15.d, z17.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> + "add x8, x5, x3\n"
> + "st1b z5.b, p0, [%[p], x8]\n"
> + "st1b z6.b, p0, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "st1b z10.b, p0, [%[p], x8]\n"
> + "st1b z11.b, p0, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "st1b z15.b, p0, [%[p], x8]\n"
> + "st1b z16.b, p0, [%[q], x8]\n"
> +
> + "add x8, x3, x3\n"
> + "add x5, x5, x8, lsl #1\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4",
> + "z5", "z6", "z7", "z8",
> + "z10", "z11", "z12", "z13",
> + "z15", "z16", "z17", "z18"
> + );
> +}
> +
> +static void raid6_sve4_xor_syndrome_real(int disks, int start, int
> stop,
> + unsigned long bytes, void **ptrs)
> +{
> + u8 **dptr = (u8 **)ptrs;
> + u8 *p, *q;
> + long z0 = stop;
> +
> + p = dptr[disks - 2];
> + q = dptr[disks - 1];
> +
> + asm volatile(
> + ".arch armv8.2-a+sve\n"
> + "ptrue p0.b\n"
> + "cntb x3\n"
> + "mov w4, #0x1d\n"
> + "dup z4.b, w4\n"
> + "mov x5, #0\n"
> +
> + "0:\n"
> + "ldr x6, [%[dptr], %[z0], lsl #3]\n"
> + "ld1b z1.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z6.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z11.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z16.b, p0/z, [x6, x8]\n"
> +
> + "ld1b z0.b, p0/z, [%[p], x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z5.b, p0/z, [%[p], x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z10.b, p0/z, [%[p], x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z15.b, p0/z, [%[p], x8]\n"
> +
> + "eor z0.d, z0.d, z1.d\n"
> + "eor z5.d, z5.d, z6.d\n"
> + "eor z10.d, z10.d, z11.d\n"
> + "eor z15.d, z15.d, z16.d\n"
> +
> + "mov w7, %w[z0]\n"
> + "sub w7, w7, #1\n"
> +
> + "1:\n"
> + "cmp w7, %w[start]\n"
> + "blt 2f\n"
> +
> + // software pipelining: load data early
> + "sxtw x8, w7\n"
> + "ldr x6, [%[dptr], x8, lsl #3]\n"
> + "ld1b z2.b, p0/z, [x6, x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z12.b, p0/z, [x6, x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z17.b, p0/z, [x6, x8]\n"
> +
> + // math block 1
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z0.d, z0.d, z2.d\n"
> +
> + // math block 2
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> + "eor z6.d, z6.d, z7.d\n"
> + "eor z5.d, z5.d, z7.d\n"
> +
> + // math block 3
> + "mov z13.d, z11.d\n"
> + "asr z13.b, p0/m, z13.b, #7\n"
> + "lsl z11.b, p0/m, z11.b, #1\n"
> + "and z13.d, z13.d, z4.d\n"
> + "eor z11.d, z11.d, z13.d\n"
> + "eor z11.d, z11.d, z12.d\n"
> + "eor z10.d, z10.d, z12.d\n"
> +
> + // math block 4
> + "mov z18.d, z16.d\n"
> + "asr z18.b, p0/m, z18.b, #7\n"
> + "lsl z16.b, p0/m, z16.b, #1\n"
> + "and z18.d, z18.d, z4.d\n"
> + "eor z16.d, z16.d, z18.d\n"
> + "eor z16.d, z16.d, z17.d\n"
> + "eor z15.d, z15.d, z17.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 1b\n"
> + "2:\n"
> +
> + "mov w7, %w[start]\n"
> + "sub w7, w7, #1\n"
> + "3:\n"
> + "cmp w7, #0\n"
> + "blt 4f\n"
> +
> + // math block 1
> + "mov z3.d, z1.d\n"
> + "asr z3.b, p0/m, z3.b, #7\n"
> + "lsl z1.b, p0/m, z1.b, #1\n"
> + "and z3.d, z3.d, z4.d\n"
> + "eor z1.d, z1.d, z3.d\n"
> +
> + // math block 2
> + "mov z8.d, z6.d\n"
> + "asr z8.b, p0/m, z8.b, #7\n"
> + "lsl z6.b, p0/m, z6.b, #1\n"
> + "and z8.d, z8.d, z4.d\n"
> + "eor z6.d, z6.d, z8.d\n"
> +
> + // math block 3
> + "mov z13.d, z11.d\n"
> + "asr z13.b, p0/m, z13.b, #7\n"
> + "lsl z11.b, p0/m, z11.b, #1\n"
> + "and z13.d, z13.d, z4.d\n"
> + "eor z11.d, z11.d, z13.d\n"
> +
> + // math block 4
> + "mov z18.d, z16.d\n"
> + "asr z18.b, p0/m, z18.b, #7\n"
> + "lsl z16.b, p0/m, z16.b, #1\n"
> + "and z18.d, z18.d, z4.d\n"
> + "eor z16.d, z16.d, z18.d\n"
> +
> + "sub w7, w7, #1\n"
> + "b 3b\n"
> + "4:\n"
> +
> + // Load q and XOR
> + "ld1b z2.b, p0/z, [%[q], x5]\n"
> + "add x8, x5, x3\n"
> + "ld1b z7.b, p0/z, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z12.b, p0/z, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "ld1b z17.b, p0/z, [%[q], x8]\n"
> +
> + "eor z1.d, z1.d, z2.d\n"
> + "eor z6.d, z6.d, z7.d\n"
> + "eor z11.d, z11.d, z12.d\n"
> + "eor z16.d, z16.d, z17.d\n"
> +
> + // Store results
> + "st1b z0.b, p0, [%[p], x5]\n"
> + "st1b z1.b, p0, [%[q], x5]\n"
> + "add x8, x5, x3\n"
> + "st1b z5.b, p0, [%[p], x8]\n"
> + "st1b z6.b, p0, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "st1b z10.b, p0, [%[p], x8]\n"
> + "st1b z11.b, p0, [%[q], x8]\n"
> + "add x8, x8, x3\n"
> + "st1b z15.b, p0, [%[p], x8]\n"
> + "st1b z16.b, p0, [%[q], x8]\n"
> +
> + "add x8, x3, x3\n"
> + "add x5, x5, x8, lsl #1\n"
> + "cmp x5, %[bytes]\n"
> + "blt 0b\n"
> + :
> + : [dptr] "r" (dptr), [z0] "r" (z0), [bytes] "r" (bytes),
> + [p] "r" (p), [q] "r" (q), [start] "r" (start)
> + : "memory", "p0", "x3", "x4", "x5", "x6", "x7", "x8",
> + "z0", "z1", "z2", "z3", "z4",
> + "z5", "z6", "z7", "z8",
> + "z10", "z11", "z12", "z13",
> + "z15", "z16", "z17", "z18"
> + );
> +}
> +
> +#define RAID6_SVE_WRAPPER(_n) \
> + static void raid6_sve ## _n ## _gen_syndrome(int disks, \
> + size_t bytes, void **ptrs) \
> + { \
> + scoped_ksimd() \
> + raid6_sve ## _n ## _gen_syndrome_real(disks, \
> + (unsigned long)bytes, ptrs); \
> + } \
> + static void raid6_sve ## _n ## _xor_syndrome(int disks, \
> + int start, int stop, \
> + size_t bytes, void **ptrs) \
> + { \
> + scoped_ksimd() \
> + raid6_sve ## _n ## _xor_syndrome_real(disks, \
> + start, stop, (unsigned long)bytes, ptrs);\
> + } \
> + struct raid6_calls const raid6_svex ## _n = { \
> + raid6_sve ## _n ## _gen_syndrome, \
> + raid6_sve ## _n ## _xor_syndrome, \
> + raid6_have_sve, \
> + "svex" #_n, \
> + 0 \
> + }
> +
> +static int raid6_have_sve(void)
> +{
> + return system_supports_sve();
> +}
> +
> +RAID6_SVE_WRAPPER(1);
> +RAID6_SVE_WRAPPER(2);
> +RAID6_SVE_WRAPPER(4);
> --
> 2.43.0
^ permalink raw reply
* Re: [PATCH 0/6] media: synopsys: Add imx93 support
From: Sakari Ailus @ 2026-03-24 8:01 UTC (permalink / raw)
To: Frank Li
Cc: Michael Riesch, Mauro Carvalho Chehab, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Laurent Pinchart, linux-media, linux-kernel, devicetree,
linux-arm-kernel, linux-rockchip, Guoniu Zhou, imx
In-Reply-To: <acGQNIUKqfh8eWNB@lizhi-Precision-Tower-5810>
Hi Frank,
On Mon, Mar 23, 2026 at 03:10:44PM -0400, Frank Li wrote:
> On Tue, Feb 10, 2026 at 12:11:07PM -0500, Frank Li wrote:
> > This 3rd time try to support DW CSI2RX support for imx93.
> >
>
> Laurent Pinchart and Sakari Ailus:
>
> I am not who will take care this patch?
> original drivers/media/platform/synopsys/dw-mipi-csi2rx.c picked
> by Sakari Ailus
I'll review them soonish; please cc me in the future.
Thanks.
--
Sakari Ailus
^ permalink raw reply
* Re: [PATCH 3/6] media: synopsys: implement .get_frame_desc() callback
From: Sakari Ailus @ 2026-03-24 8:02 UTC (permalink / raw)
To: Frank Li
Cc: Michael Riesch, Mauro Carvalho Chehab, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, linux-media,
linux-kernel, devicetree, linux-arm-kernel, linux-rockchip,
Guoniu Zhou, Laurent Pinchart, imx
In-Reply-To: <20260210-imx93-dw-csi2-v1-3-69667bb86bfa@nxp.com>
Hi Frank,
On Tue, Feb 10, 2026 at 12:11:10PM -0500, Frank Li wrote:
> Implement the .get_frame_desc() callback to fetch information from the
> remote endpoint.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 25 ++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 61cd7f491b3d5b8a37707b23ca03ce709b40a79f..4ad4e3b23448affeeaa932a706653818ba4019ba 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> @@ -70,6 +70,8 @@ struct dw_mipi_csi2rx_device {
> struct v4l2_async_notifier notifier;
> struct v4l2_subdev sd;
>
> + struct v4l2_subdev *remote_source;
> +
> enum v4l2_mbus_type bus_type;
> u32 lanes_num;
> };
> @@ -431,10 +433,31 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
> return ret;
> }
>
> +static int
> +dw_mipi_csi2rx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
> + struct v4l2_mbus_frame_desc *fd)
> +{
> + struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd);
> + struct media_pad *remote_pad;
> +
> + if (!csi2->remote_source)
> + return -ENODEV;
> +
> + remote_pad = media_pad_remote_pad_unique(&csi2->pads[DW_MIPI_CSI2RX_PAD_SINK]);
> + if (IS_ERR(remote_pad)) {
> + dev_err(csi2->dev, "can't get source pad of %s (%pe)\n",
> + csi2->remote_source->name, remote_pad);
> + return PTR_ERR(remote_pad);
> + }
> + return v4l2_subdev_call(csi2->remote_source, pad, get_frame_desc,
> + remote_pad->index, fd);
> +}
Can you use v4l2_subdev_get_frame_desc_passthrough()?
> +
> static const struct v4l2_subdev_pad_ops dw_mipi_csi2rx_pad_ops = {
> .enum_mbus_code = dw_mipi_csi2rx_enum_mbus_code,
> .get_fmt = v4l2_subdev_get_fmt,
> .set_fmt = dw_mipi_csi2rx_set_fmt,
> + .get_frame_desc = dw_mipi_csi2rx_get_frame_desc,
> .set_routing = dw_mipi_csi2rx_set_routing,
> .enable_streams = dw_mipi_csi2rx_enable_streams,
> .disable_streams = dw_mipi_csi2rx_disable_streams,
> @@ -487,6 +510,8 @@ static int dw_mipi_csi2rx_notifier_bound(struct v4l2_async_notifier *notifier,
> return ret;
> }
>
> + csi2->remote_source = sd;
> +
> return 0;
> }
>
>
--
Regards,
Sakari Ailus
^ permalink raw reply
* Re: [PATCH v1 1/1] scsi: ufs: rockchip: Drop unused include
From: Shawn Lin @ 2026-03-24 7:31 UTC (permalink / raw)
To: Andy Shevchenko, linux-scsi, linux-arm-kernel, linux-rockchip,
linux-kernel
Cc: shawn.lin, James E.J. Bottomley, Martin K. Petersen,
Heiko Stuebner
In-Reply-To: <20260320215606.3236516-1-andriy.shevchenko@linux.intel.com>
在 2026/03/21 星期六 5:56, Andy Shevchenko 写道:
> This driver includes the legacy header <linux/gpio.h> but does
> not use any symbols from it. Drop the inclusion.
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> drivers/ufs/host/ufs-rockchip.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
> index 7fff34513a60..bac68f238e1c 100644
> --- a/drivers/ufs/host/ufs-rockchip.c
> +++ b/drivers/ufs/host/ufs-rockchip.c
> @@ -6,7 +6,6 @@
> */
>
> #include <linux/clk.h>
> -#include <linux/gpio.h>
> #include <linux/gpio/consumer.h>
> #include <linux/mfd/syscon.h>
> #include <linux/of.h>
^ permalink raw reply
* Re: [PATCH] media: cedrus: validate H.264 reference list indices
From: Pengpeng Hou @ 2026-03-24 8:08 UTC (permalink / raw)
To: Maxime Ripard
Cc: Pengpeng Hou, Paul Kocialkowski, Mauro Carvalho Chehab,
Greg Kroah-Hartman, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Nicolas Dufresne, linux-media, linux-staging, linux-arm-kernel,
linux-sunxi, linux-kernel
In-Reply-To: <20260324020431.1800-1-pengpeng@iscas.ac.cn>
Hi Jernej,
Thanks, that makes sense.
You're right that rejecting the H.264 slice control in cedrus_try_ctrl()
would have the same userspace compatibility problem as the HEVC case.
I'll drop that approach and respin this as a separate Cedrus patch that
skips out-of-range reference list indices at the point where
_cedrus_write_ref_list() resolves them into decode->dpb[] entries.
Best regards,
Pengpeng
^ permalink raw reply
* [PATCH] media: cedrus: skip invalid H.264 reference list entries
From: Pengpeng Hou @ 2026-03-24 8:08 UTC (permalink / raw)
To: mripard
Cc: paulk, mchehab, gregkh, wens, jernej.skrabec, samuel,
nicolas.dufresne, linux-media, linux-staging, linux-arm-kernel,
linux-sunxi, linux-kernel, pengpeng
Cedrus consumes H.264 ref_pic_list0/ref_pic_list1 entries from the
stateless slice control and later uses their indices to look up
decode->dpb[] in _cedrus_write_ref_list().
Rejecting such controls in cedrus_try_ctrl() would break existing
userspace, since stateless H.264 reference lists may legitimately carry
out-of-range indices for missing references. Instead, guard the actual
DPB lookup in Cedrus and skip entries whose indices do not fit the fixed
V4L2_H264_NUM_DPB_ENTRIES array.
This keeps the fix local to the driver use site and avoids out-of-bounds
reads from malformed or unsupported reference list entries.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
@@ -210,6 +210,9 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
u8 dpb_idx;
dpb_idx = ref_list[i].index;
+ if (dpb_idx >= V4L2_H264_NUM_DPB_ENTRIES)
+ continue;
+
dpb = &decode->dpb[dpb_idx];
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
--
2.50.1
^ permalink raw reply
* Re: [PATCH 12/13] arm64: dts: mediatek: mt8188-geralt: Add MT6359 PMIC supplies
From: Fei Shao @ 2026-03-24 8:08 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Matthias Brugger, AngeloGioacchino Del Regno, linux-mediatek,
devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260320084351.2461060-13-wenst@chromium.org>
On Fri, Mar 20, 2026 at 4:44 PM Chen-Yu Tsai <wenst@chromium.org> wrote:
>
> The MT6359 PMIC has a number of power inputs for its various buck and
> LDO regulators. The binding recently gained property definitions for
> them.
>
> Add the supplies for the PMIC regulators to the common design dtsi file.
>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> .../boot/dts/mediatek/mt8188-geralt.dtsi | 21 +++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
Reviewed-by: Fei Shao <fshao@chromium.org>
^ permalink raw reply
* Re: [PATCH 12/12] driver core: remove driver_set_override()
From: Greg Kroah-Hartman @ 2026-03-24 8:09 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Russell King, Rafael J. Wysocki, Ioana Ciornei, Nipun Gupta,
Nikhil Agarwal, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Bjorn Helgaas, Armin Wolf, Bjorn Andersson,
Mathieu Poirier, Vineeth Vijayan, Peter Oberparleiter,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Harald Freudenberger,
Holger Dengler, Mark Brown, Michael S. Tsirkin, Jason Wang,
Xuan Zhuo, Eugenio Pérez, Alex Williamson, Juergen Gross,
Stefano Stabellini, Oleksandr Tyshchenko,
Christophe Leroy (CS GROUP), linux-kernel, driver-core,
linuxppc-dev, linux-hyperv, linux-pci, platform-driver-x86,
linux-arm-msm, linux-remoteproc, linux-s390, linux-spi,
virtualization, kvm, xen-devel, linux-arm-kernel
In-Reply-To: <20260324005919.2408620-13-dakr@kernel.org>
On Tue, Mar 24, 2026 at 01:59:16AM +0100, Danilo Krummrich wrote:
> All buses have been converted from driver_set_override() to the generic
> driver_override infrastructure introduced in commit cb3d1049f4ea
> ("driver core: generalize driver_override in struct device").
>
> Buses now either opt into the generic sysfs callbacks via the
> bus_type::driver_override flag, or use device_set_driver_override() /
> __device_set_driver_override() directly.
>
> Thus, remove the now-unused driver_set_override() helper.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=220789
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---
> drivers/base/driver.c | 75 -----------------------------------
> include/linux/device/driver.h | 2 -
> 2 files changed, 77 deletions(-)
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH 13/13] arm64: dts: mediatek: mt8188-geralt: Add little core CPU power supplies
From: Fei Shao @ 2026-03-24 8:09 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Matthias Brugger, AngeloGioacchino Del Regno, linux-mediatek,
devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260320084351.2461060-14-wenst@chromium.org>
On Fri, Mar 20, 2026 at 4:44 PM Chen-Yu Tsai <wenst@chromium.org> wrote:
>
> The device tree for the MT8188 Geralt is missing power supplies for all
> the CPU cores. Power for the little cores is fed from the MT6359 PMIC.
> Power for the big cores is fed from an MT6319 PMIC on SPMI. The latter
> is currently not working in Linux.
>
> Add the power supplies for the little cores.
>
> Supplies for the big cores will be added once the issue with SPMI is
> resolved.
>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> .../boot/dts/mediatek/mt8188-geralt.dtsi | 24 +++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
Reviewed-by: Fei Shao <fshao@chromium.org>
^ permalink raw reply
* Re: [PATCH v8 5/5] arm64: dts: imx943-evk: Add pcie[0,1] and pcie-ep[0,1] support
From: Manivannan Sadhasivam @ 2026-03-24 8:10 UTC (permalink / raw)
To: Richard Zhu
Cc: robh, krzk+dt, conor+dt, bhelgaas, frank.li, l.stach, lpieralisi,
kwilczynski, s.hauer, kernel, festevam, linux-pci,
linux-arm-kernel, devicetree, imx, linux-kernel
In-Reply-To: <20260324023036.784466-6-hongxing.zhu@nxp.com>
On Tue, Mar 24, 2026 at 10:30:36AM +0800, Richard Zhu wrote:
> Add pcie[0,1] and pcie-ep[0,1] support.
>
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
> arch/arm64/boot/dts/freescale/Makefile | 4 +
> arch/arm64/boot/dts/freescale/imx943-evk.dts | 83 ++++++++++++++++++++
> 2 files changed, 87 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index bae24b53bce6..1366e25a9efd 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -465,6 +465,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb
> dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb
> dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb
>
> +imx943-evk-pcie0-ep-dtbs += imx943-evk.dtb imx-pcie0-ep.dtbo
> +imx943-evk-pcie1-ep-dtbs += imx943-evk.dtb imx-pcie1-ep.dtbo
> +dtb-$(CONFIG_ARCH_MXC) += imx943-evk-pcie0-ep.dtb imx943-evk-pcie1-ep.dtb
> +
> imx95-15x15-evk-pcie0-ep-dtbs = imx95-15x15-evk.dtb imx-pcie0-ep.dtbo
> dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-evk-pcie0-ep.dtb
> imx95-19x19-evk-pcie0-ep-dtbs += imx95-19x19-evk.dtb imx-pcie0-ep.dtbo
> diff --git a/arch/arm64/boot/dts/freescale/imx943-evk.dts b/arch/arm64/boot/dts/freescale/imx943-evk.dts
> index 1d834379f602..ea0100b37d5c 100644
> --- a/arch/arm64/boot/dts/freescale/imx943-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx943-evk.dts
> @@ -51,6 +51,20 @@ chosen {
> stdout-path = &lpuart1;
> };
>
> + pcie_ref_clk: clock-pcie-ref {
> + compatible = "gpio-gate-clock";
> + clocks = <&xtal25m>;
> + #clock-cells = <0>;
> + enable-gpios = <&pca9670_i2c3 7 GPIO_ACTIVE_LOW>;
> + };
> +
> + xtal25m: clock-xtal25m {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <25000000>;
> + clock-output-names = "xtal_25MHz";
> + };
> +
> dmic: dmic {
> compatible = "dmic-codec";
> #sound-dai-cells = <0>;
> @@ -72,6 +86,15 @@ reg_m2_pwr: regulator-m2-pwr {
> startup-delay-us = <5000>;
> };
>
> + reg_slot_pwr: regulator-slot-pwr {
> + compatible = "regulator-fixed";
> + regulator-name = "PCIe slot-power";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + gpio = <&pcal6416_i2c3_u46 0 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> +
> reg_m2_wlan: regulator-wlan {
> compatible = "regulator-fixed";
> regulator-name = "WLAN_EN";
> @@ -704,6 +727,18 @@ IMX94_PAD_GPIO_IO28__LPI2C6_SCL 0x40000b9e
> >;
> };
>
> + pinctrl_pcie0: pcie0grp {
> + fsl,pins = <
> + IMX94_PAD_GPIO_IO20__PCIE1_CLKREQ_B 0x4000031e
> + >;
> + };
> +
> + pinctrl_pcie1: pcie1grp {
> + fsl,pins = <
> + IMX94_PAD_GPIO_IO23__PCIE2_CLKREQ_B 0x4000031e
> + >;
> + };
> +
> pinctrl_pdm: pdmgrp {
> fsl,pins = <
> IMX94_PAD_PDM_CLK__PDM_CLK 0x31e
> @@ -878,6 +913,54 @@ IMX94_PAD_XSPI1_DQS__XSPI1_A_DQS 0x3fe
> };
> };
>
> +&pcie0 {
> + pinctrl-0 = <&pinctrl_pcie0>;
> + pinctrl-names = "default";
> + clocks = <&scmi_clk IMX94_CLK_HSIO>,
> + <&scmi_clk IMX94_CLK_HSIOPLL>,
> + <&scmi_clk IMX94_CLK_HSIOPLL_VCO>,
> + <&scmi_clk IMX94_CLK_HSIOPCIEAUX>,
> + <&hsio_blk_ctl 0>,
> + <&pcie_ref_clk>;
> + clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
> + "ref", "extref";
> + reset-gpio = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>;
> + vpcie3v3aux-supply = <®_m2_wlan>;
> + supports-clkreq;
> + status = "okay";
> +};
> +
> +&pcie0_ep {
> + pinctrl-0 = <&pinctrl_pcie0>;
> + pinctrl-names = "default";
> + vpcie-supply = <®_m2_wlan>;
> + status = "disabled";
> +};
> +
> +&pcie1 {
> + pinctrl-0 = <&pinctrl_pcie1>;
> + pinctrl-names = "default";
> + clocks = <&scmi_clk IMX94_CLK_HSIO>,
> + <&scmi_clk IMX94_CLK_HSIOPLL>,
> + <&scmi_clk IMX94_CLK_HSIOPLL_VCO>,
> + <&scmi_clk IMX94_CLK_HSIOPCIEAUX>,
> + <&hsio_blk_ctl 0>,
> + <&pcie_ref_clk>;
> + clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
> + "ref", "extref";
> + reset-gpio = <&pcal6416_i2c3_u46 1 GPIO_ACTIVE_LOW>;
> + vpcie3v3aux-supply = <®_slot_pwr>;
I'd strongly recommend you to switch to Root Port binding and make use of
PWRCTRL_GENERIC driver to handle this supply. But this can be done later.
- Mani
> + supports-clkreq;
> + status = "okay";
> +};
> +
> +&pcie1_ep {
> + pinctrl-0 = <&pinctrl_pcie1>;
> + pinctrl-names = "default";
> + vpcie-supply = <®_slot_pwr>;
> + status = "disabled";
> +};
> +
> &usb2 {
> dr_mode = "otg";
> disable-over-current;
> --
> 2.37.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v2 net-next 11/14] net: dsa: netc: add phylink MAC operations
From: Paolo Abeni @ 2026-03-24 8:13 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, robh, krzk+dt, conor+dt, f.fainelli,
frank.li, chleroy, horms, andrew, netdev, linux-kernel,
devicetree, linuxppc-dev, linux-arm-kernel, imx, Wei Fang
In-Reply-To: <acEIQqI-_oyCym8O@shell.armlinux.org.uk>
On 3/23/26 10:30 AM, Russell King (Oracle) wrote:
> On Mon, Mar 23, 2026 at 02:07:49PM +0800, Wei Fang wrote:
>> +static void netc_port_set_mac_mode(struct netc_port *np,
>> + unsigned int mode,
>> + phy_interface_t phy_mode)
>> +{
>> + u32 mask = PM_IF_MODE_IFMODE | PM_IF_MODE_REVMII | PM_IF_MODE_ENA;
>> + u32 val = 0;
>> +
>> + switch (phy_mode) {
>> + case PHY_INTERFACE_MODE_RGMII:
>> + case PHY_INTERFACE_MODE_RGMII_ID:
>> + case PHY_INTERFACE_MODE_RGMII_RXID:
>> + case PHY_INTERFACE_MODE_RGMII_TXID:
>> + val |= IFMODE_RGMII;
>> + /* Enable auto-negotiation for the MAC if its
>> + * RGMII interface supports In-Band status.
>> + */
>> + if (phylink_autoneg_inband(mode))
>> + val |= PM_IF_MODE_ENA;
>
> I would prefer newer drivers not to use phylink_autoneg_inband()
> anymore. Note that there is no need to support RGMII inband in the
> kernel (nor is there any proper support without a "phylink_pcs"
> being present to provide the inband status.)
Would you mind sharing a patch adding a comment nearby
phylink_autoneg_inband(), explaining the above for future memory?
Thanks,
Paolo
^ permalink raw reply
* Re: [PATCH 4/6] media: synopsys: use struct dw_mipi_csi2rx_regs to describe register offsets
From: Sakari Ailus @ 2026-03-24 8:16 UTC (permalink / raw)
To: Frank Li
Cc: Michael Riesch, Mauro Carvalho Chehab, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, linux-media,
linux-kernel, devicetree, linux-arm-kernel, linux-rockchip,
Guoniu Zhou, Laurent Pinchart, imx
In-Reply-To: <20260210-imx93-dw-csi2-v1-4-69667bb86bfa@nxp.com>
Hi Frank,
On Tue, Feb 10, 2026 at 12:11:11PM -0500, Frank Li wrote:
> Use struct dw_mipi_csi2rx_regs to describe register offsets and support
> new IP versions with differing register layouts.
>
> Add rk3568_regs, matching the previous macro definitions, and pass it as
> driver data retrieved during probe.
>
> No functional change.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 96 +++++++++++++++++-------
> 1 file changed, 69 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> index 4ad4e3b23448affeeaa932a706653818ba4019ba..6a2966c9e3a2eac661fa1f8610c9f021d6e26cf8 100644
> --- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> +++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
> @@ -24,14 +24,39 @@
> #include <media/v4l2-mc.h>
> #include <media/v4l2-subdev.h>
>
> -#define DW_MIPI_CSI2RX_N_LANES 0x04
> -#define DW_MIPI_CSI2RX_RESETN 0x10
> -#define DW_MIPI_CSI2RX_PHY_STATE 0x14
> -#define DW_MIPI_CSI2RX_ERR1 0x20
> -#define DW_MIPI_CSI2RX_ERR2 0x24
> -#define DW_MIPI_CSI2RX_MSK1 0x28
> -#define DW_MIPI_CSI2RX_MSK2 0x2c
> -#define DW_MIPI_CSI2RX_CONTROL 0x40
> +struct dw_mipi_csi2rx_regs {
> + u32 n_lanes;
> + u32 resetn;
> + u32 phy_state;
> + u32 err1;
> + u32 err2;
> + u32 msk1;
> + u32 msk2;
> + u32 control;
> +};
> +
> +struct dw_mipi_csi2rx_drvdata {
> + const struct dw_mipi_csi2rx_regs *regs;
> +};
> +
> +/* Help check wrong access unexisted register at difference IP version */
> +#define DW_REG_EXIST BIT(31)
> +#define DW_REG(x) (DW_REG_EXIST | (x))
> +
> +static const struct dw_mipi_csi2rx_regs rk3568_regs = {
> + .n_lanes = DW_REG(0x4),
> + .resetn = DW_REG(0x10),
> + .phy_state = DW_REG(0x14),
> + .err1 = DW_REG(0x20),
> + .err2 = DW_REG(0x24),
> + .msk1 = DW_REG(0x28),
> + .msk2 = DW_REG(0x2c),
> + .control = DW_REG(0x40),
> +};
> +
> +static const struct dw_mipi_csi2rx_drvdata rk3568_drvdata = {
"drvdata" is typically used of driver's context struct related to a given
device. This is something else. How about calling it rk3568_devinfo for
instance?
> + .regs = &rk3568_regs,
> +};
>
> #define SW_CPHY_EN(x) ((x) << 0)
> #define SW_DSI_EN(x) ((x) << 4)
> @@ -74,8 +99,35 @@ struct dw_mipi_csi2rx_device {
>
> enum v4l2_mbus_type bus_type;
> u32 lanes_num;
> +
> + const struct dw_mipi_csi2rx_drvdata *drvdata;
> };
>
> +static int
> +dw_mipi_csi2rx_reg_err(struct dw_mipi_csi2rx_device *csi2, const char *name)
> +{
> + dev_err_once(csi2->dev, "access to non-existent register: %s\n", name);
> + return 0;
> +}
> +
> +#define __dw_reg_exist(offset) ((offset) & DW_REG_EXIST)
> +
> +#define dw_reg_exist(csi2, __name) __dw_reg_exist((csi2)->drvdata->regs->__name)
Can you use the same dw_mipi_csi2rx prefix here?
> +
> +#define dw_mipi_csi2rx_write(csi2, __name, value) \
> +({ auto __csi2 = csi2; \
Are there different types being used for csi2? As this there's a single
driver here I'd suppose no?
> + u32 offset = __csi2->drvdata->regs->__name; \
> + __dw_reg_exist(offset) ? \
> + writel(value, __csi2->base_addr + (offset & ~DW_REG_EXIST)) : \
> + dw_mipi_csi2rx_reg_err(__csi2, #__name); })
> +
> +#define dw_mipi_csi2rx_read(csi2, __name) \
> +({ auto __csi2 = csi2; \
> + u32 offset = __csi2->drvdata->regs->__name; \
> + __dw_reg_exist(offset) ? \
> + readl(__csi2->base_addr + (offset & ~DW_REG_EXIST)) : \
> + dw_mipi_csi2rx_reg_err(__csi2, #__name); })
> +
> static const struct v4l2_mbus_framefmt default_format = {
> .width = 3840,
> .height = 2160,
> @@ -188,18 +240,6 @@ static inline struct dw_mipi_csi2rx_device *to_csi2(struct v4l2_subdev *sd)
> return container_of(sd, struct dw_mipi_csi2rx_device, sd);
> }
>
> -static inline void dw_mipi_csi2rx_write(struct dw_mipi_csi2rx_device *csi2,
> - unsigned int addr, u32 val)
> -{
> - writel(val, csi2->base_addr + addr);
> -}
> -
> -static inline u32 dw_mipi_csi2rx_read(struct dw_mipi_csi2rx_device *csi2,
> - unsigned int addr)
> -{
> - return readl(csi2->base_addr + addr);
> -}
> -
> static const struct dw_mipi_csi2rx_format *
> dw_mipi_csi2rx_find_format(struct dw_mipi_csi2rx_device *csi2, u32 mbus_code)
> {
> @@ -265,9 +305,9 @@ static int dw_mipi_csi2rx_start(struct dw_mipi_csi2rx_device *csi2)
> control |= SW_DATATYPE_FS(0x00) | SW_DATATYPE_FE(0x01) |
> SW_DATATYPE_LS(0x02) | SW_DATATYPE_LE(0x03);
>
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_N_LANES, lanes - 1);
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_CONTROL, control);
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_RESETN, 1);
> + dw_mipi_csi2rx_write(csi2, n_lanes, lanes - 1);
> + dw_mipi_csi2rx_write(csi2, control, control);
> + dw_mipi_csi2rx_write(csi2, resetn, 1);
>
> return phy_power_on(csi2->phy);
> }
> @@ -276,9 +316,9 @@ static void dw_mipi_csi2rx_stop(struct dw_mipi_csi2rx_device *csi2)
> {
> phy_power_off(csi2->phy);
>
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_RESETN, 0);
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_MSK1, ~0);
> - dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_MSK2, ~0);
> + dw_mipi_csi2rx_write(csi2, resetn, 0);
> + dw_mipi_csi2rx_write(csi2, msk1, ~0);
> + dw_mipi_csi2rx_write(csi2, msk2, ~0);
> }
>
> static const struct media_entity_operations dw_mipi_csi2rx_media_ops = {
> @@ -632,7 +672,7 @@ static void dw_mipi_csi2rx_unregister(struct dw_mipi_csi2rx_device *csi2)
>
> static const struct of_device_id dw_mipi_csi2rx_of_match[] = {
> {
> - .compatible = "rockchip,rk3568-mipi-csi2",
> + .compatible = "rockchip,rk3568-mipi-csi2", .data = &rk3568_drvdata,
> },
> {}
> };
> @@ -654,6 +694,8 @@ static int dw_mipi_csi2rx_probe(struct platform_device *pdev)
> if (IS_ERR(csi2->base_addr))
> return PTR_ERR(csi2->base_addr);
>
> + csi2->drvdata = device_get_match_data(dev);
> +
> ret = devm_clk_bulk_get_all(dev, &csi2->clks);
> if (ret < 0)
> return dev_err_probe(dev, -ENODEV, "failed to get clocks\n");
>
--
Regards,
Sakari Ailus
^ permalink raw reply
* Re: [PATCH 0/6] media: synopsys: Add imx93 support
From: Sakari Ailus @ 2026-03-24 8:18 UTC (permalink / raw)
To: Frank Li
Cc: Michael Riesch, Mauro Carvalho Chehab, Philipp Zabel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Laurent Pinchart, Sakari Ailus, linux-media, linux-kernel,
devicetree, linux-arm-kernel, linux-rockchip, Guoniu Zhou, imx
In-Reply-To: <acGQNIUKqfh8eWNB@lizhi-Precision-Tower-5810>
On Mon, Mar 23, 2026 at 03:10:44PM -0400, Frank Li wrote:
> On Tue, Feb 10, 2026 at 12:11:07PM -0500, Frank Li wrote:
> > This 3rd time try to support DW CSI2RX support for imx93.
> >
>
> Laurent Pinchart and Sakari Ailus:
>
> I am not who will take care this patch?
> original drivers/media/platform/synopsys/dw-mipi-csi2rx.c picked
> by Sakari Ailus
Michael seems to have questions on the last patch, too.
--
Sakari Ailus
^ permalink raw reply
* Re: [PATCH] firmware: arm_scmi: clock: Relax check in scmi_clock_protocol_init
From: Cristian Marussi @ 2026-03-24 8:18 UTC (permalink / raw)
To: Sudeep Holla
Cc: Peng Fan (OSS), Cristian Marussi, Jacky Bai, arm-scmi,
linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260324-lean-bobcat-of-reputation-6628b5@sudeepholla>
On Tue, Mar 24, 2026 at 07:49:22AM +0000, Sudeep Holla wrote:
> On Tue, Mar 24, 2026 at 02:24:14PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan@nxp.com>
> >
Hi,
> > On i.MX95, the SCMI Clock protocol defines several reserved clock IDs that
> > are not backed by real clock devices
> > (see arch/arm64/boot/dts/freescale/imx95-clock.h).
> >
> > For these reserved IDs, the SCMI firmware correctly returns NOT_FOUND in
> > response to the CLOCK_ATTRIBUTES command. According to the SCMI Clock
> > specification, NOT_FOUND is expected when a clock_id does not correspond to
> > a valid clock device.
> >
> > The recent hardening added in scmi_clock_protocol_init() treats any error
> > return as fatal, causing SCMI clock probe to fail and preventing i.MX9
> > platforms from booting.
> >
> > Relax the check so that -ENOENT is treated as a non-fatal condition.
> >
>
> I understand the use-case and the fix here, but still wonder if this
> should be treated as quirk or handle it in the core. I am inclined to
> latter as reserved SCMI clock/resource ID seems to be trend in its usage
> and hard to classify as quirks.
>
> Cristain, agree or have a different view ?
>
I was just replying...
Looking at the spec 3.6.2.5 CLOCK_ATTRIBUTES
"This command returns the attributes that are associated with a specific clock. An agent might be allowed access to only
a subset of the clocks available in the system. The platform must thus guarantee that clocks that an agent cannot access
are not visible to it."
...not sure if this sheds some light or it is ambiguos anyway...I'd say that
NOT_FOUND does NOT equate to be invisible...
...BUT at the same time I think that this practice of exposing a non-contiguos
set of resources IDs (a set with holes in it) is the a well-known spec-loophole
used by many vendors to deploy one single FW image across all of their platforms
without having to reconfigure their reosurces IDs ro expose a common set of
contiguos IDs like the spec would suggest...
Having said that, since we unfortunately left this door open in the
implementation, now this loophole has become common practice
apparently...
...I am more concerned about the impact that this COULD have on underlying
resources allocations that at the driver level was certainly conceived
to manage a contiguos set of IDs, even though it was certanly the
usecase until my harden patches...so it could be safe but to be double
checked...
Quirk or core I suppose it depends on how much we want to 'legalize' this
trick for the future (thinking also about other protocols)...
...a middle ground could be to implement it as an always-on quirk that
matches any FW (like the existing out_of_spec_triplet quirk)... as a way
to keep on allowing the existing behaviour but sort of discouraging it...
Not really strong opinions about this, BUT at this point, in general I
would keep all of this series on hold for further testing, given these
issues together the bugs fixed by Geert on iterators and the lack of
clock-MAINTs acks...
...also Geert was investigating the need of a different quirks in these
regards for the Renesas boards...
Thanks,
Cristian
^ permalink raw reply
* [PATCH v3 2/3] dt-bindings: media: mediatek-jpeg-encoder: add MT8189 compatible string
From: Jianhua Lin @ 2026-03-24 8:21 UTC (permalink / raw)
To: nicolas, mchehab, robh, krzk+dt, conor+dt, matthias.bgg,
angelogioacchino.delregno
Cc: devicetree, linux-kernel, linux-media, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, sirius.wang,
vince-wl.liu, jh.hsu, Jianhua Lin
In-Reply-To: <20260324082141.31292-1-jianhua.lin@mediatek.com>
Add the compatible string for the JPEG encoder block found in the
MediaTek MT8189 SoC.
Unlike some previous SoCs, the MT8189 JPEG encoder requires 34-bit IOVA
address space support. Therefore, it is added as a standalone compatible
string without falling back to the generic "mediatek,mtk-jpgenc" to
ensure the driver applies the correct hardware-specific configurations.
Signed-off-by: Jianhua Lin <jianhua.lin@mediatek.com>
---
.../bindings/media/mediatek-jpeg-encoder.yaml | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
index 5b15f8977f67..476b7122d3fc 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
@@ -14,13 +14,15 @@ description: |-
properties:
compatible:
- items:
- - enum:
- - mediatek,mt2701-jpgenc
- - mediatek,mt8183-jpgenc
- - mediatek,mt8186-jpgenc
- - mediatek,mt8188-jpgenc
- - const: mediatek,mtk-jpgenc
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt2701-jpgenc
+ - mediatek,mt8183-jpgenc
+ - mediatek,mt8186-jpgenc
+ - mediatek,mt8188-jpgenc
+ - const: mediatek,mtk-jpgenc
+ - const: mediatek,mt8189-jpgenc
reg:
maxItems: 1
@@ -34,6 +36,10 @@ properties:
items:
- const: jpgenc
+ mediatek,larb:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: a phandle to the smi_larb node.
+
power-domains:
maxItems: 1
--
2.45.2
^ permalink raw reply related
* [PATCH v3 1/3] dt-bindings: media: mediatek-jpeg-decoder: add MT8189 compatible string
From: Jianhua Lin @ 2026-03-24 8:21 UTC (permalink / raw)
To: nicolas, mchehab, robh, krzk+dt, conor+dt, matthias.bgg,
angelogioacchino.delregno
Cc: devicetree, linux-kernel, linux-media, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, sirius.wang,
vince-wl.liu, jh.hsu, Jianhua Lin
In-Reply-To: <20260324082141.31292-1-jianhua.lin@mediatek.com>
Add the compatible string for the JPEG decoder block found in the
MediaTek MT8189 SoC.
Compared to previous generation ICs, the MT8189 JPEG decoder requires
34-bit IOVA address space support and only needs a single clock
("jpgdec") instead of two. Therefore, it is added as a standalone
compatible string without falling back to older SoCs.
Update the binding schema to include the new compatible string and add
an `allOf` block with conditional checks. This enforces the single clock
requirement for MT8189 while preserving the two-clock requirement
("jpgdec-smi", "jpgdec") for older SoCs.
Signed-off-by: Jianhua Lin <jianhua.lin@mediatek.com>
---
.../bindings/media/mediatek-jpeg-decoder.yaml | 39 ++++++++++++++++---
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
index a4aacd3eb189..91c9b2a4687b 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
@@ -17,13 +17,14 @@ properties:
oneOf:
- items:
- enum:
- - mediatek,mt8173-jpgdec
- mediatek,mt2701-jpgdec
+ - mediatek,mt8173-jpgdec
- items:
- enum:
- mediatek,mt7623-jpgdec
- mediatek,mt8188-jpgdec
- const: mediatek,mt2701-jpgdec
+ - const: mediatek,mt8189-jpgdec
reg:
maxItems: 1
@@ -32,13 +33,22 @@ properties:
maxItems: 1
clocks:
+ minItems: 1
maxItems: 2
- minItems: 2
clock-names:
- items:
- - const: jpgdec-smi
- - const: jpgdec
+ minItems: 1
+ maxItems: 2
+ oneOf:
+ - items:
+ - const: jpgdec
+ - items:
+ - const: jpgdec-smi
+ - const: jpgdec
+
+ mediatek,larb:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: a phandle to the smi_larb node.
power-domains:
maxItems: 1
@@ -60,6 +70,25 @@ required:
- power-domains
- iommus
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: mediatek,mt8189-jpgdec
+ then:
+ properties:
+ clocks:
+ maxItems: 1
+ clock-names:
+ maxItems: 1
+ else:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
+
additionalProperties: false
examples:
--
2.45.2
^ permalink raw reply related
* [PATCH v3 3/3] media: mediatek: jpeg: add compatible for MT8189 SoC
From: Jianhua Lin @ 2026-03-24 8:21 UTC (permalink / raw)
To: nicolas, mchehab, robh, krzk+dt, conor+dt, matthias.bgg,
angelogioacchino.delregno
Cc: devicetree, linux-kernel, linux-media, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group, sirius.wang,
vince-wl.liu, jh.hsu, Jianhua Lin
In-Reply-To: <20260324082141.31292-1-jianhua.lin@mediatek.com>
Compared to the previous generation ICs, the MT8189 uses a 34-bit IOVA
address space (16GB) and requires a single clock configuration.
Therefore, add new compatible strings ("mediatek,mt8189-jpgenc" and
"mediatek,mt8189-jpgdec") along with their specific driver data to
support the JPEG encoder and decoder of the MT8189 SoC.
Signed-off-by: Jianhua Lin <jianhua.lin@mediatek.com>
---
.../platform/mediatek/jpeg/mtk_jpeg_core.c | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index c01124a349f6..c6fc5d228e20 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1866,6 +1866,10 @@ static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {
{ .id = "jpgdec" },
};
+static struct clk_bulk_data mtk_jpeg_dec_clocks[] = {
+ { .id = "jpgdec" },
+};
+
static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = {
.clks = mt8173_jpeg_dec_clocks,
.num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
@@ -1897,6 +1901,38 @@ static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
.multi_core = false,
};
+static const struct mtk_jpeg_variant mtk8189_jpegenc_drvdata = {
+ .clks = mtk_jpeg_clocks,
+ .num_clks = ARRAY_SIZE(mtk_jpeg_clocks),
+ .formats = mtk_jpeg_enc_formats,
+ .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
+ .qops = &mtk_jpeg_enc_qops,
+ .irq_handler = mtk_jpeg_enc_irq,
+ .hw_reset = mtk_jpeg_enc_reset,
+ .m2m_ops = &mtk_jpeg_enc_m2m_ops,
+ .dev_name = "mtk-jpeg-enc",
+ .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
+ .support_34bit = true,
+};
+
+static const struct mtk_jpeg_variant mtk8189_jpegdec_drvdata = {
+ .clks = mtk_jpeg_dec_clocks,
+ .num_clks = ARRAY_SIZE(mtk_jpeg_dec_clocks),
+ .formats = mtk_jpeg_dec_formats,
+ .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
+ .qops = &mtk_jpeg_dec_qops,
+ .irq_handler = mtk_jpeg_dec_irq,
+ .hw_reset = mtk_jpeg_dec_reset,
+ .m2m_ops = &mtk_jpeg_dec_m2m_ops,
+ .dev_name = "mtk-jpeg-dec",
+ .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
+ .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
+ .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
+ .support_34bit = true,
+};
+
static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
.formats = mtk_jpeg_enc_formats,
.num_formats = MTK_JPEG_ENC_NUM_FORMATS,
@@ -1936,6 +1972,14 @@ static const struct of_device_id mtk_jpeg_match[] = {
.compatible = "mediatek,mtk-jpgenc",
.data = &mtk_jpeg_drvdata,
},
+ {
+ .compatible = "mediatek,mt8189-jpgenc",
+ .data = &mtk8189_jpegenc_drvdata,
+ },
+ {
+ .compatible = "mediatek,mt8189-jpgdec",
+ .data = &mtk8189_jpegdec_drvdata,
+ },
{
.compatible = "mediatek,mt8195-jpgenc",
.data = &mtk8195_jpegenc_drvdata,
--
2.45.2
^ permalink raw reply related
* [PATCH net] net: ethernet: mtk_ppe: avoid NULL deref when gmac0 is disabled
From: Sven Eckelmann (Plasma Cloud) @ 2026-03-24 8:36 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthias Brugger,
AngeloGioacchino Del Regno, Elad Yifee
Cc: netdev, linux-kernel, linux-arm-kernel, linux-mediatek, stable,
Sven Eckelmann (Plasma Cloud)
If the gmac0 is disabled, the precheck for a valid ingress device will
cause a NULL pointer deref and crash the system. This happens because
eth->netdev[0] will be NULL but the code will directly try to access
netdev_ops.
Instead of just checking for the first net_device, it must be checked if
any of the mtk_eth net_devices is matching the netdev_ops of the ingress
device.
Cc: stable@vger.kernel.org
Fixes: 73cfd947dbdb ("net: ethernet: mtk_eth_soc: ppe: prevent ppe update for non-mtk devices")
Signed-off-by: Sven Eckelmann (Plasma Cloud) <se@simonwunderlich.de>
---
drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
index cb30108f2bf6..cc8c4ef8038f 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -244,6 +244,25 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
return 0;
}
+static bool
+mtk_flow_is_valid_idev(const struct mtk_eth *eth, const struct net_device *idev)
+{
+ size_t i;
+
+ if (!idev)
+ return false;
+
+ for (i = 0; i < ARRAY_SIZE(eth->netdev); i++) {
+ if (!eth->netdev[i])
+ continue;
+
+ if (idev->netdev_ops == eth->netdev[i]->netdev_ops)
+ return true;
+ }
+
+ return false;
+}
+
static int
mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
int ppe_index)
@@ -270,7 +289,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
flow_rule_match_meta(rule, &match);
if (mtk_is_netsys_v2_or_greater(eth)) {
idev = __dev_get_by_index(&init_net, match.key->ingress_ifindex);
- if (idev && idev->netdev_ops == eth->netdev[0]->netdev_ops) {
+ if (mtk_flow_is_valid_idev(eth, idev)) {
struct mtk_mac *mac = netdev_priv(idev);
if (WARN_ON(mac->ppe_idx >= eth->soc->ppe_num))
---
base-commit: 70b439bf06f6a12e491f827fa81a9887a11501f9
change-id: 20260324-wed-crash-gmac0-disabled-ae3a551cb154
Best regards,
--
Sven Eckelmann (Plasma Cloud) <se@simonwunderlich.de>
^ permalink raw reply related
* Re: [PATCH] firmware: psci: Set pm_set_resume/suspend_via_firmware() for SYSTEM_SUSPEND
From: Lorenzo Pieralisi @ 2026-03-24 8:44 UTC (permalink / raw)
To: Manivannan Sadhasivam, arnd
Cc: mark.rutland, bjorn.andersson, konrad.dybcio, mani,
linux-arm-kernel, linux-kernel, Konrad Dybcio, Konrad Dybcio,
Sudeep Holla, soc
In-Reply-To: <20251231162126.7728-1-manivannan.sadhasivam@oss.qualcomm.com>
[+Arnd, arm-soc - to pick this up please]
On Wed, Dec 31, 2025 at 09:51:26PM +0530, Manivannan Sadhasivam wrote:
> From: Konrad Dybcio <konradybcio@kernel.org>
>
> PSCI specification defines the SYSTEM_SUSPEND feature which enables the
> firmware to implement the suspend to RAM (S2RAM) functionality by
> transitioning the system to a deeper low power state. When the system
> enters such state, the power to the peripheral devices might be removed. So
> the respective device drivers must prepare for the possible removal of the
> power by performing actions such as shutting down or resetting the device
> in their system suspend callbacks.
>
> The Linux PM framework allows the platform drivers to convey this info to
> device drivers by calling the pm_set_suspend_via_firmware() and
> pm_set_resume_via_firmware() APIs.
>
> Hence, if the PSCI firmware supports SYSTEM_SUSPEND feature, call the above
> mentioned APIs in the psci_system_suspend_begin() and
> psci_system_suspend_enter() callbacks.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
> [mani: reworded the description to be more elaborative]
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
>
> This patch was part of an old series that didn't make it to mainline due to
> objections in the binding and exposing CPU_SUSPEND as S2RAM patches:
> https://lore.kernel.org/all/20241028-topic-cpu_suspend_s2ram-v1-0-9fdd9a04b75c@oss.qualcomm.com/
>
> But this patch on its own is useful for platforms implementing the S2RAM
> feature in PSCI firmware. So I picked it up, tested on Qcom X1E T14s and
> resending it.
>
> drivers/firmware/psci/psci.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
Acked-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
> diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> index 38ca190d4a22..e73bae6cb23a 100644
> --- a/drivers/firmware/psci/psci.c
> +++ b/drivers/firmware/psci/psci.c
> @@ -539,12 +539,22 @@ static int psci_system_suspend(unsigned long unused)
>
> static int psci_system_suspend_enter(suspend_state_t state)
> {
> + pm_set_resume_via_firmware();
> +
> return cpu_suspend(0, psci_system_suspend);
> }
>
> +static int psci_system_suspend_begin(suspend_state_t state)
> +{
> + pm_set_suspend_via_firmware();
> +
> + return 0;
> +}
> +
> static const struct platform_suspend_ops psci_suspend_ops = {
> .valid = suspend_valid_only_mem,
> .enter = psci_system_suspend_enter,
> + .begin = psci_system_suspend_begin,
> };
>
> static void __init psci_init_system_reset2(void)
> --
> 2.48.1
>
^ permalink raw reply
* Re: [PATCH] firmware: psci: Set pm_set_resume/suspend_via_firmware() for SYSTEM_SUSPEND
From: Lorenzo Pieralisi @ 2026-03-24 8:45 UTC (permalink / raw)
To: Jon Hunter
Cc: Manivannan Sadhasivam, mark.rutland, bjorn.andersson,
konrad.dybcio, mani, linux-arm-kernel, linux-kernel,
Konrad Dybcio, Konrad Dybcio, Sudeep Holla,
linux-tegra@vger.kernel.org
In-Reply-To: <b5860d64-6eed-453e-8261-2c8b0c5571c4@nvidia.com>
On Mon, Mar 23, 2026 at 10:10:00AM +0000, Jon Hunter wrote:
> Hi Mark, Lorenzo,
>
> On 12/03/2026 19:00, Jon Hunter wrote:
> > Hi all,
> >
> > On 31/12/2025 16:21, Manivannan Sadhasivam wrote:
> > > From: Konrad Dybcio <konradybcio@kernel.org>
> > >
> > > PSCI specification defines the SYSTEM_SUSPEND feature which enables the
> > > firmware to implement the suspend to RAM (S2RAM) functionality by
> > > transitioning the system to a deeper low power state. When the system
> > > enters such state, the power to the peripheral devices might be
> > > removed. So
> > > the respective device drivers must prepare for the possible removal
> > > of the
> > > power by performing actions such as shutting down or resetting the device
> > > in their system suspend callbacks.
> > >
> > > The Linux PM framework allows the platform drivers to convey this info to
> > > device drivers by calling the pm_set_suspend_via_firmware() and
> > > pm_set_resume_via_firmware() APIs.
> > >
> > > Hence, if the PSCI firmware supports SYSTEM_SUSPEND feature, call
> > > the above
> > > mentioned APIs in the psci_system_suspend_begin() and
> > > psci_system_suspend_enter() callbacks.
> > >
> > > Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> > > Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
> > > [mani: reworded the description to be more elaborative]
> > > Signed-off-by: Manivannan Sadhasivam
> > > <manivannan.sadhasivam@oss.qualcomm.com>
> > > ---
> > >
> > > This patch was part of an old series that didn't make it to mainline
> > > due to
> > > objections in the binding and exposing CPU_SUSPEND as S2RAM patches:
> > > https://lore.kernel.org/all/20241028-topic-cpu_suspend_s2ram-
> > > v1-0-9fdd9a04b75c@oss.qualcomm.com/
> > >
> > > But this patch on its own is useful for platforms implementing the S2RAM
> > > feature in PSCI firmware. So I picked it up, tested on Qcom X1E T14s and
> > > resending it.
> > >
> > > drivers/firmware/psci/psci.c | 10 ++++++++++
> > > 1 file changed, 10 insertions(+)
> > >
> > > diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> > > index 38ca190d4a22..e73bae6cb23a 100644
> > > --- a/drivers/firmware/psci/psci.c
> > > +++ b/drivers/firmware/psci/psci.c
> > > @@ -539,12 +539,22 @@ static int psci_system_suspend(unsigned long
> > > unused)
> > > static int psci_system_suspend_enter(suspend_state_t state)
> > > {
> > > + pm_set_resume_via_firmware();
> > > +
> > > return cpu_suspend(0, psci_system_suspend);
> > > }
> > > +static int psci_system_suspend_begin(suspend_state_t state)
> > > +{
> > > + pm_set_suspend_via_firmware();
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static const struct platform_suspend_ops psci_suspend_ops = {
> > > .valid = suspend_valid_only_mem,
> > > .enter = psci_system_suspend_enter,
> > > + .begin = psci_system_suspend_begin,
> > > };
> > > static void __init psci_init_system_reset2(void)
> >
> >
> > I wanted to ask what the status of this patch is?
> >
> > It turns out that since commit f3ac2ff14834 ("PCI/ASPM: Enable all
> > ClockPM and ASPM states for devicetree platforms"), this fix is also
> > need for Tegra platforms that have NVMe devices to ensure that they are
> > suspended as needed. There is some more background in this thread [0].
>
>
> Any feedback on this? I am not sure if this patch is purposely being
> ignored, but if so, I would like to understand why.
It fell through the cracks, apologies.
Lorenzo
^ permalink raw reply
* Re: [PATCH v5 01/10] dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
From: Krzysztof Kozlowski @ 2026-03-24 8:47 UTC (permalink / raw)
To: Yu-Chun Lin
Cc: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou, devicetree, linux-clk, linux-kernel,
linux-arm-kernel, linux-realtek-soc, james.tai, cy.huang,
stanley_chang
In-Reply-To: <20260324025332.3416977-2-eleanor.lin@realtek.com>
On Tue, Mar 24, 2026 at 10:53:22AM +0800, Yu-Chun Lin wrote:
> Add DT binding schema for Realtek RTD1625 clock and reset controller
>
> Co-developed-by: Cheng-Yu Lee <cylee12@realtek.com>
> Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
> Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 1/2] drm/rockchip: dsi: Add maximum per lane bit rate calculation
From: Chaoyi Chen @ 2026-03-24 8:58 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guochun Huang
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Different chips have varying support for the maximum bit rate per lane.
Add calculation for the maximum per lane bit rate for various chip
platforms, and relax the bandwidth margin requirements.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 21 +++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 3547d91b25d3..d3bacfae174e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -268,6 +268,7 @@ struct rockchip_dw_dsi_chip_data {
unsigned int flags;
unsigned int max_data_lanes;
+ unsigned long max_bit_rate_per_lane;
};
struct dw_mipi_dsi_rockchip {
@@ -565,7 +566,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
int bpp;
unsigned long mpclk, tmp;
unsigned int target_mbps = 1000;
- unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
+ unsigned int max_mbps;
unsigned long best_freq = 0;
unsigned long fvco_min, fvco_max, fin, fout;
unsigned int min_prediv, max_prediv;
@@ -573,6 +574,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
unsigned long _fbdiv, best_fbdiv;
unsigned long min_delta = ULONG_MAX;
+ max_mbps = dsi->cdata->max_bit_rate_per_lane;
dsi->format = format;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -584,8 +586,8 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
if (mpclk) {
- /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
- tmp = mpclk * (bpp / lanes) * 10 / 8;
+ /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
+ tmp = mpclk * (bpp / lanes) * 10 / 9;
if (tmp < max_mbps)
target_mbps = tmp;
else
@@ -595,7 +597,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
/* for external phy only a the mipi_dphy_config is necessary */
if (dsi->phy) {
- phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
+ phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 9,
bpp, lanes,
&dsi->phy_opts.mipi_dphy);
dsi->lane_mbps = target_mbps;
@@ -1503,6 +1505,7 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
PX30_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
@@ -1515,6 +1518,7 @@ static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
RK3128_DSI_FORCERXMODE |
RK3128_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
@@ -1527,6 +1531,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI0_LCDC_SEL, 1),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{
.reg = 0xff964000,
@@ -1535,6 +1540,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI1_LCDC_SEL, 1),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1547,6 +1553,7 @@ static const struct rockchip_dw_dsi_chip_data rk3368_chip_data[] = {
RK3368_DSI_FORCETXSTOPMODE |
RK3368_DSI_FORCERXMODE), 0),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1634,6 +1641,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{
.reg = 0xff968000,
@@ -1658,6 +1666,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1500000000UL,
.dphy_rx_init = rk3399_dphy_tx1rx1_init,
.dphy_rx_power_on = rk3399_dphy_tx1rx1_power_on,
@@ -1674,6 +1683,7 @@ static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCERXMODE, 0) |
FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 2,
+ .max_bit_rate_per_lane = 1500000000UL,
},
{ /* sentinel */ }
};
@@ -1687,6 +1697,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI0_TURNDISABLE, 0) |
FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCERXMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1200000000UL,
},
{
.reg = 0xfe070000,
@@ -1696,6 +1707,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI1_TURNDISABLE, 0) |
FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCERXMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1200000000UL,
},
{ /* sentinel */ }
};
@@ -1708,6 +1720,7 @@ static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = {
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCERXMODE, 0) |
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 4,
+ .max_bit_rate_per_lane = 1000000000UL,
},
{ /* sentinel */ }
};
--
2.51.1
^ permalink raw reply related
* [PATCH 2/2] drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
From: Chaoyi Chen @ 2026-03-24 8:58 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Guochun Huang
Cc: dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel,
Chaoyi Chen
In-Reply-To: <20260324085838.90-1-kernel@airkyi.com>
From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Currently, there are generally two types of DPHY for Rockchip. One is
the DPHY used by RK3288/RK3399, whose timing is described by Table A-3
High-Speed Transition Times in the databook. The other is the DPHY used
by PX30 and its successors. If its timing is still described using
RK3288/RK3399, it may not perform correctly on some DSI panel.
Add dphy_get_timing for different D-PHY types to adapt to timing
differences.
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
---
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 45 ++++++++++++++++++-
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index d3bacfae174e..2d1c9e54ff85 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -247,6 +247,7 @@ enum {
BIASEXTR_127_7,
};
+struct dw_mipi_dsi_rockchip;
struct rockchip_dw_dsi_chip_data {
u32 reg;
@@ -262,6 +263,9 @@ struct rockchip_dw_dsi_chip_data {
u32 lanecfg2_grf_reg;
u32 lanecfg2;
+ int (*dphy_get_timing)(struct dw_mipi_dsi_rockchip *dsi, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing);
+
int (*dphy_rx_init)(struct phy *phy);
int (*dphy_rx_power_on)(struct phy *phy);
int (*dphy_rx_power_off)(struct phy *phy);
@@ -721,8 +725,9 @@ static struct hstt hstt_table[] = {
};
static int
-dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
- struct dw_mipi_dsi_dphy_timing *timing)
+dw_mipi_dsi_phy_rk3288_get_timing(struct dw_mipi_dsi_rockchip *dsi,
+ unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
{
int i;
@@ -738,6 +743,32 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
return 0;
}
+static const struct dw_mipi_dsi_dphy_timing dphy_timing_px30 = {
+ .clk_lp2hs = 0x40,
+ .clk_hs2lp = 0x40,
+ .data_lp2hs = 0x10,
+ .data_hs2lp = 0x14,
+};
+
+static int
+dw_mipi_dsi_phy_px30_get_timing(struct dw_mipi_dsi_rockchip *dsi,
+ unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ *timing = dphy_timing_px30;
+
+ return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ struct dw_mipi_dsi_rockchip *dsi = priv_data;
+
+ return dsi->cdata->dphy_get_timing(dsi, lane_mbps, timing);
+}
+
static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
.init = dw_mipi_dsi_phy_init,
.power_on = dw_mipi_dsi_phy_power_on,
@@ -1506,6 +1537,7 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1519,6 +1551,7 @@ static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
RK3128_DSI_FORCETXSTOPMODE), 0),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1532,6 +1565,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{
.reg = 0xff964000,
@@ -1541,6 +1575,7 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{ /* sentinel */ }
};
@@ -1554,6 +1589,7 @@ static const struct rockchip_dw_dsi_chip_data rk3368_chip_data[] = {
RK3368_DSI_FORCERXMODE), 0),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1642,6 +1678,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1500000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{
.reg = 0xff968000,
@@ -1671,6 +1708,7 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
.dphy_rx_init = rk3399_dphy_tx1rx1_init,
.dphy_rx_power_on = rk3399_dphy_tx1rx1_power_on,
.dphy_rx_power_off = rk3399_dphy_tx1rx1_power_off,
+ .dphy_get_timing = dw_mipi_dsi_phy_rk3288_get_timing,
},
{ /* sentinel */ }
};
@@ -1698,6 +1736,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCERXMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1200000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{
.reg = 0xfe070000,
@@ -1708,6 +1747,7 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCERXMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1200000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
@@ -1721,6 +1761,7 @@ static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = {
FIELD_PREP_WM16_CONST(RV1126_DSI_FORCETXSTOPMODE, 0)),
.max_data_lanes = 4,
.max_bit_rate_per_lane = 1000000000UL,
+ .dphy_get_timing = dw_mipi_dsi_phy_px30_get_timing,
},
{ /* sentinel */ }
};
--
2.51.1
^ permalink raw reply related
* Re: (subset) [PATCH v2 0/9] gpio: remove uneeded Kconfig dependencies on OF_GPIO
From: Bartosz Golaszewski @ 2026-03-24 9:04 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Andrew Lunn, Heiner Kallweit,
Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Linus Walleij, Lee Jones, Pavel Machek,
Wim Van Sebroeck, Guenter Roeck, Mauro Carvalho Chehab,
Greg Kroah-Hartman, Sebastian Reichel, Bartosz Golaszewski
Cc: brgl, linux-arm-kernel, linux-kernel, netdev, linux-gpio,
linux-leds, linux-watchdog, linux-media, linux-staging, linux-pm
In-Reply-To: <20260316-gpio-of-kconfig-v2-0-de2f4b00a0e4@oss.qualcomm.com>
On Mon, 16 Mar 2026 10:45:20 +0100, Bartosz Golaszewski wrote:
> NOTE: Each patch in this series can be picked up independently into
> maintainer trees.
>
> CONFIG_OF_GPIO is a switch that enables the compilation of the gpiolib-of
> module. The module itself handles GPIO lookup via the OF-node tree and
> is automatically enabled on all OF systems. It does not export any
> public symbols to drivers. There is no reason for them to select or
> depend on it in Kconfig.
>
> [...]
Applied, thanks!
[3/9] gpio: drop unneeded Kconfig dependencies on OF_GPIO
https://git.kernel.org/brgl/c/7803501e5754dc4b295ab22b20562e2b965358ba
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2 2/4] iio: adc: meson-saradc: add support for Meson S4
From: Jonathan Cameron @ 2026-03-24 9:06 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Nick Xie, neil.armstrong, khilman, martin.blumenstingl, jbrunet,
dlechner, andy, krzk+dt, robh, conor+dt, linux-iio, linux-amlogic,
linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <171e30f3-e294-40fb-8731-476fb51d5a3c@kernel.org>
On Tue, 24 Mar 2026 08:07:15 +0100
Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On 23/03/2026 21:05, Jonathan Cameron wrote:
> > On Mon, 23 Mar 2026 08:54:21 +0100
> > Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> >> On Mon, Mar 23, 2026 at 09:34:06AM +0800, Nick Xie wrote:
> >>> Add support for the SARADC found on the Amlogic Meson S4 SoC.
> >>> According to the documentation and current testing, it is fully
> >>> compatible with the G12A parameter set, so we reuse
> >>> `meson_sar_adc_g12a_data` for this new compatible string.
> >>>
> >>> Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> >>> Signed-off-by: Nick Xie <nick@khadas.com>
> >>> ---
> >>> drivers/iio/adc/meson_saradc.c | 8 ++++++++
> >>> 1 file changed, 8 insertions(+)
> >>>
> >>> diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
> >>> index 47cd350498a0d..3ac48b7842c4f 100644
> >>> --- a/drivers/iio/adc/meson_saradc.c
> >>> +++ b/drivers/iio/adc/meson_saradc.c
> >>> @@ -1313,6 +1313,11 @@ static const struct meson_sar_adc_data meson_sar_adc_g12a_data = {
> >>> .name = "meson-g12a-saradc",
> >>> };
> >>>
> >>> +static const struct meson_sar_adc_data meson_sar_adc_s4_data = {
> >>> + .param = &meson_sar_adc_g12a_param,
> >>> + .name = "meson-s4-saradc",
> >>> +};
> >>> +
> >>> static const struct of_device_id meson_sar_adc_of_match[] = {
> >>> {
> >>> .compatible = "amlogic,meson8-saradc",
> >>> @@ -1341,6 +1346,9 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
> >>> }, {
> >>> .compatible = "amlogic,meson-g12a-saradc",
> >>> .data = &meson_sar_adc_g12a_data,
> >>> + }, {
> >>> + .compatible = "amlogic,meson-s4-saradc",
> >>
> >> The point of compatible devices is to not add such entries. Drop.
> > It's used for naming in the userspace ABI which is supposed to reflect the part number.
>
> Indeed, I saw this pattern in more places. Does userspace need it? There
> is no "compatible" entry shown?
Yes. Userspace uses this (+ a label) to identify which of multiple devices
it is talking to. Given some of these parts are very specific rather than
covering a general purpose, people tend to be looking at datasheets if there
are multiple parts and they want to know which is which. Knowing whether
it's compatible with something else doesn't help with that identification
part.
>
> If there is no, then probably this could be automated by taking the name
> from compatible after ',', but that would be out of scope for this set,
> so here it is fine.
For DT that works but not for other firmware types. We had a bunch of bugs
where people ended up putting out ACPI IDs (some of which we've had to leave
in place to avoid regressions). Hence I've always been nervous about not
encoding the string explicitly in the driver. Obviously this is a bit
paranoid for DT where it's reasonably tightly defined.
Jonathan
>
>
> Best regards,
> Krzysztof
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox