* Re: [PATCH 1/4] dt-bindings: phy: sc8280xp-qmp-pcie: Document Eliza PCIe phy
From: sashiko-bot @ 2026-05-21 14:21 UTC (permalink / raw)
To: Krishna Chaitanya Chundru
Cc: linux-pci, vkoul, conor+dt, linux-phy, olteanv, neil.armstrong,
robh, devicetree
In-Reply-To: <20260521-eliza-v1-1-97cdbe88389d@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The new Eliza PCIe PHY compatibles are placed in the wrong conditional blocks, incorrectly constraining them to require 6 clocks and 2 resets.
--
commit 8532696e8f5cf63303348c425688fe2c2383eed6
Author: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
dt-bindings: phy: sc8280xp-qmp-pcie: Document Eliza PCIe phy
Add compatibles for the Eliza PCIe QMP PHY's, which supports Gen3x1 and
Gen3x2 configurations.
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> index 3a35120a77ec0..be4bbc327982f 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
[ ... ]
> @@ -181,6 +183,8 @@ allOf:
> compatible:
> contains:
> enum:
> + - qcom,eliza-qmp-gen3x1-pcie-phy
> + - qcom,eliza-qmp-gen3x2-pcie-phy
> - qcom,glymur-qmp-gen4x2-pcie-phy
> - qcom,glymur-qmp-gen5x4-pcie-phy
> - qcom,qcs8300-qmp-gen4x2-pcie-phy
[Severity: High]
Are these compatibles placed in the correct conditional block?
By placing the Eliza compatibles in this group, the schema enforces a
minimum of 6 clocks and 2 resets. However, the driver implementation
introduced in the series expects only 1 reset.
This mismatch will prevent structurally correct device tree nodes from
passing schema validation.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-eliza-v1-0-97cdbe88389d@oss.qualcomm.com?part=1
^ permalink raw reply
* Re: [PATCH v7 14/28] media: rockchip: rga: move cmdbuf to rga_ctx
From: Michael Tretter @ 2026-05-21 14:20 UTC (permalink / raw)
To: Sven Püschel
Cc: Jacob Chen, Ezequiel Garcia, Mauro Carvalho Chehab,
Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans Verkuil, linux-media, linux-rockchip, linux-arm-kernel,
linux-kernel, devicetree, kernel, nicolas, sebastian.reichel,
p.zabel, Nicolas Dufresne
In-Reply-To: <20260521-spu-rga3-v7-14-3f33e8c7145f@pengutronix.de>
On Thu, 21 May 2026 00:44:19 +0200, Sven Püschel wrote:
> Move the command buffer to the rga_ctx struct in preparation to reuse
> an already prepared command buffer. This allows to split the command
> buffer setup in a further commit to setup a template for the command
> buffer at streamon and only update the buffer addresses in device_run
> and trigger the command stream. No sync point is added, as one command
> buffer should only be used for one conversion at a time.
>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
Reviewed-by: Michael Tretter <m.tretter@pengutronix.de>
> ---
> drivers/media/platform/rockchip/rga/rga-hw.c | 28 +++++++---------
> drivers/media/platform/rockchip/rga/rga.c | 48 ++++++++++++++++------------
> drivers/media/platform/rockchip/rga/rga.h | 5 +--
> 3 files changed, 41 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
> index 17f7a67c0b4bb..9881c14f908d5 100644
> --- a/drivers/media/platform/rockchip/rga/rga-hw.c
> +++ b/drivers/media/platform/rockchip/rga/rga-hw.c
> @@ -122,8 +122,7 @@ static struct rga_addr_offset *rga_lookup_draw_pos(struct
>
> static void rga_cmd_set_src_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
> {
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int reg;
>
> reg = RGA_MMU_SRC_BASE - RGA_MODE_BASE_REG;
> @@ -135,8 +134,7 @@ static void rga_cmd_set_src_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
>
> static void rga_cmd_set_src1_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
> {
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int reg;
>
> reg = RGA_MMU_SRC1_BASE - RGA_MODE_BASE_REG;
> @@ -148,8 +146,7 @@ static void rga_cmd_set_src1_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
>
> static void rga_cmd_set_dst_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
> {
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int reg;
>
> reg = RGA_MMU_DST_BASE - RGA_MODE_BASE_REG;
> @@ -162,7 +159,7 @@ static void rga_cmd_set_dst_addr(struct rga_ctx *ctx, dma_addr_t dma_addr)
> static void rga_cmd_set_trans_info(struct rga_ctx *ctx)
> {
> struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int scale_dst_w, scale_dst_h;
> unsigned int src_h, src_w, dst_h, dst_w;
> union rga_src_info src_info;
> @@ -322,8 +319,7 @@ static void rga_cmd_set_src_info(struct rga_ctx *ctx,
> struct rga_addr_offset *offset)
> {
> struct rga_corners_addr_offset src_offsets;
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int src_h, src_w, src_x, src_y;
>
> src_h = ctx->in.crop.height;
> @@ -350,8 +346,7 @@ static void rga_cmd_set_dst_info(struct rga_ctx *ctx,
> {
> struct rga_addr_offset *dst_offset;
> struct rga_corners_addr_offset offsets;
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> unsigned int dst_h, dst_w, dst_x, dst_y;
> unsigned int mir_mode = 0;
> unsigned int rot_mode = 0;
> @@ -397,8 +392,7 @@ static void rga_cmd_set_dst_info(struct rga_ctx *ctx,
>
> static void rga_cmd_set_mode(struct rga_ctx *ctx)
> {
> - struct rockchip_rga *rga = ctx->rga;
> - u32 *dest = rga->cmdbuf_virt;
> + u32 *dest = ctx->cmdbuf_virt;
> union rga_mode_ctrl mode;
> union rga_alpha_ctrl0 alpha_ctrl0;
> union rga_alpha_ctrl1 alpha_ctrl1;
> @@ -423,7 +417,7 @@ static void rga_cmd_set(struct rga_ctx *ctx,
> {
> struct rockchip_rga *rga = ctx->rga;
>
> - memset(rga->cmdbuf_virt, 0, RGA_CMDBUF_SIZE);
> + memset(ctx->cmdbuf_virt, 0, RGA_CMDBUF_SIZE);
>
> rga_cmd_set_src_addr(ctx, src->dma_desc_pa);
> /*
> @@ -439,11 +433,11 @@ static void rga_cmd_set(struct rga_ctx *ctx,
> rga_cmd_set_dst_info(ctx, &dst->offset);
> rga_cmd_set_trans_info(ctx);
>
> - rga_write(rga, RGA_CMD_BASE, rga->cmdbuf_phy);
> + rga_write(rga, RGA_CMD_BASE, ctx->cmdbuf_phy);
>
> /* sync CMD buf for RGA */
> - dma_sync_single_for_device(rga->dev, rga->cmdbuf_phy,
> - PAGE_SIZE, DMA_BIDIRECTIONAL);
> + dma_sync_single_for_device(rga->dev, ctx->cmdbuf_phy,
> + PAGE_SIZE, DMA_BIDIRECTIONAL);
> }
>
> static void rga_hw_start(struct rockchip_rga *rga,
> diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
> index 77b8c7ab74274..bf6bbcbfc869b 100644
> --- a/drivers/media/platform/rockchip/rga/rga.c
> +++ b/drivers/media/platform/rockchip/rga/rga.c
> @@ -219,6 +219,16 @@ static int rga_open(struct file *file)
> ctx = kzalloc_obj(*ctx);
> if (!ctx)
> return -ENOMEM;
> +
> + /* Create CMD buffer */
> + ctx->cmdbuf_virt = dma_alloc_attrs(rga->dev, rga->hw->cmdbuf_size,
> + &ctx->cmdbuf_phy, GFP_KERNEL,
> + DMA_ATTR_WRITE_COMBINE);
> + if (!ctx->cmdbuf_virt) {
> + ret = -ENOMEM;
> + goto rel_ctx;
> + }
> +
> ctx->rga = rga;
> /* Set default formats */
> ctx->in = def_frame;
> @@ -230,15 +240,13 @@ static int rga_open(struct file *file)
> ctx->out.fmt->fourcc, def_width, def_height);
>
> if (mutex_lock_interruptible(&rga->mutex)) {
> - kfree(ctx);
> - return -ERESTARTSYS;
> + ret = -ERESTARTSYS;
> + goto rel_cmdbuf;
> }
> ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rga->m2m_dev, ctx, &queue_init);
> if (IS_ERR(ctx->fh.m2m_ctx)) {
> ret = PTR_ERR(ctx->fh.m2m_ctx);
> - mutex_unlock(&rga->mutex);
> - kfree(ctx);
> - return ret;
> + goto unlock_mutex;
> }
> v4l2_fh_init(&ctx->fh, video_devdata(file));
> v4l2_fh_add(&ctx->fh, file);
> @@ -252,6 +260,15 @@ static int rga_open(struct file *file)
> mutex_unlock(&rga->mutex);
>
> return 0;
> +
> +unlock_mutex:
> + mutex_unlock(&rga->mutex);
> +rel_cmdbuf:
> + dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt,
> + ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
> +rel_ctx:
> + kfree(ctx);
> + return ret;
> }
>
> static int rga_release(struct file *file)
> @@ -266,6 +283,10 @@ static int rga_release(struct file *file)
> v4l2_ctrl_handler_free(&ctx->ctrl_handler);
> v4l2_fh_del(&ctx->fh, file);
> v4l2_fh_exit(&ctx->fh);
> +
> + dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt,
> + ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
> +
> kfree(ctx);
>
> mutex_unlock(&rga->mutex);
> @@ -720,19 +741,10 @@ static int rga_probe(struct platform_device *pdev)
>
> pm_runtime_put(rga->dev);
>
> - /* Create CMD buffer */
> - rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, rga->hw->cmdbuf_size,
> - &rga->cmdbuf_phy, GFP_KERNEL,
> - DMA_ATTR_WRITE_COMBINE);
> - if (!rga->cmdbuf_virt) {
> - ret = -ENOMEM;
> - goto rel_m2m;
> - }
> -
> ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
> if (ret) {
> v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
> - goto free_dma;
> + goto rel_m2m;
> }
>
> v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
> @@ -740,9 +752,6 @@ static int rga_probe(struct platform_device *pdev)
>
> return 0;
>
> -free_dma:
> - dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, rga->cmdbuf_virt,
> - rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
> rel_m2m:
> v4l2_m2m_release(rga->m2m_dev);
> rel_vdev:
> @@ -759,9 +768,6 @@ static void rga_remove(struct platform_device *pdev)
> {
> struct rockchip_rga *rga = platform_get_drvdata(pdev);
>
> - dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, rga->cmdbuf_virt,
> - rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
> -
> v4l2_info(&rga->v4l2_dev, "Removing\n");
>
> v4l2_m2m_release(rga->m2m_dev);
> diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
> index 27b3c9b4f220c..04aeb7b429523 100644
> --- a/drivers/media/platform/rockchip/rga/rga.h
> +++ b/drivers/media/platform/rockchip/rga/rga.h
> @@ -53,6 +53,9 @@ struct rga_ctx {
> struct rga_frame out;
> struct v4l2_ctrl_handler ctrl_handler;
>
> + void *cmdbuf_virt;
> + dma_addr_t cmdbuf_phy;
> +
> int osequence;
> int csequence;
>
> @@ -89,8 +92,6 @@ struct rockchip_rga {
> spinlock_t ctrl_lock;
>
> struct rga_ctx *curr;
> - dma_addr_t cmdbuf_phy;
> - void *cmdbuf_virt;
>
> const struct rga_hw *hw;
> };
>
> --
> 2.54.0
>
>
^ permalink raw reply
* Re: [PATCH v7 13/28] media: rockchip: rga: calculate x_div/y_div using v4l2_format_info
From: Michael Tretter @ 2026-05-21 14:17 UTC (permalink / raw)
To: Sven Püschel
Cc: Jacob Chen, Ezequiel Garcia, Mauro Carvalho Chehab,
Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans Verkuil, linux-media, linux-rockchip, linux-arm-kernel,
linux-kernel, devicetree, kernel, nicolas, sebastian.reichel,
p.zabel, Nicolas Dufresne
In-Reply-To: <20260521-spu-rga3-v7-13-3f33e8c7145f@pengutronix.de>
On Thu, 21 May 2026 00:44:18 +0200, Sven Püschel wrote:
> Calculate the x_div and y_div variables with the information from
> v4l2_format_info instead of storing these in the rga_fmt struct.
>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
Reviewed-by: Michael Tretter <m.tretter@pengutronix.de>
> ---
> drivers/media/platform/rockchip/rga/rga-hw.c | 45 +++++++---------------------
> drivers/media/platform/rockchip/rga/rga.h | 2 --
> 2 files changed, 11 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
> index 40498796507e0..17f7a67c0b4bb 100644
> --- a/drivers/media/platform/rockchip/rga/rga-hw.c
> +++ b/drivers/media/platform/rockchip/rga/rga-hw.c
> @@ -42,6 +42,7 @@ rga_get_addr_offset(struct rga_frame *frm, struct rga_addr_offset *offset,
> {
> struct rga_corners_addr_offset offsets;
> struct rga_addr_offset *lt, *lb, *rt, *rb;
> + const struct v4l2_format_info *format_info;
> unsigned int x_div = 0,
> y_div = 0, uv_stride = 0, pixel_width = 0;
>
> @@ -50,8 +51,16 @@ rga_get_addr_offset(struct rga_frame *frm, struct rga_addr_offset *offset,
> rt = &offsets.right_top;
> rb = &offsets.right_bottom;
>
> - x_div = frm->fmt->x_div;
> - y_div = frm->fmt->y_div;
> + format_info = v4l2_format_info(frm->pix.pixelformat);
> + /* x_div is only used for the u/v planes.
> + * When the format doesn't have these, use 1 to avoid a division by zero.
> + */
> + if (format_info->bpp[1])
> + x_div = format_info->hdiv * format_info->bpp_div[1] /
> + format_info->bpp[1];
> + else
> + x_div = 1;
> + y_div = format_info->vdiv;
> uv_stride = frm->stride / x_div;
> pixel_width = frm->stride / frm->pix.width;
>
> @@ -476,128 +485,96 @@ static struct rga_fmt formats[] = {
> .color_swap = RGA_COLOR_ALPHA_SWAP,
> .hw_format = RGA_COLOR_FMT_ABGR8888,
> .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_ABGR32,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_ABGR8888,
> .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_XBGR32,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_XBGR8888,
> .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_RGB24,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_RGB888,
> .depth = 24,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_BGR24,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_RGB888,
> .depth = 24,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_ARGB444,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_ABGR4444,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_ARGB555,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_ABGR1555,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_RGB565,
> .color_swap = RGA_COLOR_RB_SWAP,
> .hw_format = RGA_COLOR_FMT_BGR565,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_NV21,
> .color_swap = RGA_COLOR_UV_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV420SP,
> .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_NV61,
> .color_swap = RGA_COLOR_UV_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV422SP,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_NV12,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV420SP,
> .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_NV12M,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV420SP,
> .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_NV16,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV422SP,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> },
> {
> .fourcc = V4L2_PIX_FMT_YUV420,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV420P,
> .depth = 12,
> - .y_div = 2,
> - .x_div = 2,
> },
> {
> .fourcc = V4L2_PIX_FMT_YUV422P,
> .color_swap = RGA_COLOR_NONE_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV422P,
> .depth = 16,
> - .y_div = 1,
> - .x_div = 2,
> },
> {
> .fourcc = V4L2_PIX_FMT_YVU420,
> .color_swap = RGA_COLOR_UV_SWAP,
> .hw_format = RGA_COLOR_FMT_YUV420P,
> .depth = 12,
> - .y_div = 2,
> - .x_div = 2,
> },
> };
>
> diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
> index 640e510285341..27b3c9b4f220c 100644
> --- a/drivers/media/platform/rockchip/rga/rga.h
> +++ b/drivers/media/platform/rockchip/rga/rga.h
> @@ -20,8 +20,6 @@
> struct rga_fmt {
> u32 fourcc;
> int depth;
> - u8 y_div;
> - u8 x_div;
> u8 color_swap;
> u8 hw_format;
> };
>
> --
> 2.54.0
>
>
--
Pengutronix e.K. | Michael Tretter |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v12 5/5] mfd: Add support for MediaTek SPMI PMICs and MT6363/73
From: Lee Jones @ 2026-05-21 14:13 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: linux-mediatek, robh, krzk+dt, conor+dt, matthias.bgg, lgirdwood,
broonie, devicetree, linux-kernel, linux-arm-kernel, kernel,
wenst, Nícolas F. R. A. Prado
In-Reply-To: <20260511101355.122478-6-angelogioacchino.delregno@collabora.com>
On Mon, 11 May 2026, AngeloGioacchino Del Regno wrote:
> This driver adds support for the MediaTek SPMI PMICs and their
> interrupt controller (which is present in 95% of the cases).
>
> Other than probing all of the sub-devices of a SPMI PMIC, this
> sets up a regmap from the relevant SPMI bus and initializes an
> interrupt controller with its irq domain and irqchip to handle
> chained interrupts, with the SPMI bus itself being its parent
> irq controller, and the PMIC being the outmost device.
>
> This driver hence holds all of the information about a specific
> PMIC's interrupts and will properly handle them, calling the
> ISR for any subdevice that requested an interrupt.
>
> As for the interrupt spec, this driver wants either three or
> two interrupt cells, but in the case 3 were given it ignores
> the first one: this is because of how this first revision of
> of the MediaTek SPMI 2.0 Controller works, which doesn't hold
> hold irq number information in its register, but delegates
> that to the SPMI device - it's possible that this will change
> in the future with a newer revision of the controller IP, and
> this is the main reason for that.
>
> To make use of this implementation, this driver also adds the
> required bits to support MediaTek MT6363 and MT6373 SPMI PMICs.
>
> Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
> drivers/mfd/Kconfig | 16 +
> drivers/mfd/Makefile | 1 +
> drivers/mfd/mtk-spmi-pmic.c | 427 ++++++++++++++++++++++
> include/linux/mfd/mt63x3_spmi/registers.h | 34 ++
> 4 files changed, 478 insertions(+)
> create mode 100644 drivers/mfd/mtk-spmi-pmic.c
> create mode 100644 include/linux/mfd/mt63x3_spmi/registers.h
>
> diff --git "a/drivers/mfd/Kconfig" "b/drivers/mfd/Kconfig"
> index 7192c9d1d268..3e9acdf648b7 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1148,6 +1148,22 @@ config MFD_MT6397
> accessing the device; additional drivers must be enabled in order
> to use the functionality of the device.
>
> +config MFD_MTK_SPMI_PMIC
> + tristate "MediaTek SPMI PMICs"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + depends on OF
> + depends on SPMI
> + select REGMAP_SPMI
> + help
> + Say yes here to enable support for MediaTek's SPMI PMICs.
> + These PMICs made their first appearance in board designs using the
> + MediaTek Dimensity 9400 series of SoCs.
> + Note that this will only be useful when paired with descriptions
> + of the independent functions as child nodes in the device tree.
> +
> + Say M here if you want to include support for the MediaTek SPMI
> + PMICs as a module. The module will be called "mtk-spmi-pmic".
> +
> config MFD_MENF21BMC
> tristate "MEN 14F021P00 Board Management Controller Support"
> depends on I2C
> diff --git "a/drivers/mfd/Makefile" "b/drivers/mfd/Makefile"
> index e75e8045c28a..e00d283450c6 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -190,6 +190,7 @@ obj-$(CONFIG_MFD_MT6360) += mt6360-core.o
> obj-$(CONFIG_MFD_MT6370) += mt6370.o
> mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o
> obj-$(CONFIG_MFD_MT6397) += mt6397.o
> +obj-$(CONFIG_MFD_MTK_SPMI_PMIC) += mtk-spmi-pmic.o
>
> obj-$(CONFIG_RZ_MTU3) += rz-mtu3.o
> obj-$(CONFIG_ABX500_CORE) += abx500-core.o
> diff --git "a/drivers/mfd/mtk-spmi-pmic.c" "b/drivers/mfd/mtk-spmi-pmic.c
> new file mode 100644
> index 000000000000..d1fc8156e696
> --- /dev/null
> +++ b/drivers/mfd/mtk-spmi-pmic.c
> @@ -0,0 +1,427 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * MediaTek SPMI PMICs Driver
> + *
> + * Copyright (c) 2024 MediaTek Inc.
> + * Copyright (c) 2025 Collabora Ltd
> + *
> + * Authors:
> + * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/gfp.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/mt63x3_spmi/registers.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/regmap.h>
> +#include <linux/spmi.h>
> +#include <linux/types.h>
> +
> +#define MTK_SPMI_PMIC_VAL_BITS 8
> +#define MTK_SPMI_PMIC_REG_CHIP_ID 0xb
> +#define MTK_SPMI_PMIC_RCS_IRQ_DONE 0x41b
> +
> +/**
> + * struct mtk_spmi_pmic_irq_group - Group of interrupts in SPMI PMIC
> + * @num_int_regs: Number of registers for this group of interrupts
> + * @con_reg: PMIC Interrupt Group Control 0 register
> + * @sta_reg: PMIC Interrupt Group Status 0 register
> + * @group_num: PMIC Interrupt Group number - also corresponds to the
> + * status bit in the global IRQ Control register
> + */
> +struct mtk_spmi_pmic_irq_grp {
> + u8 hwirq_base;
> + u8 num_int_regs;
> + u16 con_reg;
> + u16 sta_reg;
> + u8 group_num;
> +};
> +
> +/**
> + * struct mtk_spmi_pmic_variant - SPMI PMIC variant-specific data
> + * @pmic_irq: Group of interrupts in SPMI PMIC
> + * @num_groups: Number of groups of interrupts
> + * @con_reg_len: Length in bytes of Control registers, depends on
> + * existence of SET and CLR registers in the layout
> + * @irq_grp_reg: Global interrupt status register, explains which
> + * group needs attention because of a group IRQ;
> + * if this is zero, it means that there is only one
> + * group and the device has no irqgroup register
> + * @chip_id_reg: Chip ID Register
> + */
> +struct mtk_spmi_pmic_variant {
> + const struct mtk_spmi_pmic_irq_grp *pmic_irq;
> + u8 num_groups;
> + u8 con_reg_len;
> + u8 irq_grp_reg;
> + u8 chip_id_reg;
> +};
Where is chip_id_reg used?
> +
> +/**
> + * struct mtk_spmi_pmic - Main driver structure
> + * @variant: SPMI PMIC variant-specific data
> + * @dev: Handle to SPMI Device
> + * @dom: IRQ Domain of the PMIC's interrupt controller
> + * @regmap: Handle to PMIC regmap
> + * @irq: PMIC chained interrupt
> + */
> +struct mtk_spmi_pmic {
> + const struct mtk_spmi_pmic_variant *variant;
> + struct device *dev;
> + struct irq_domain *dom;
> + struct regmap *regmap;
> + int irq;
> +};
> +
> +static void mtk_spmi_pmic_irq_set_unmasking(struct irq_data *d, bool unmask)
> +{
> + struct mtk_spmi_pmic *pmic = irq_data_get_irq_chip_data(d);
> + const struct mtk_spmi_pmic_variant *variant = pmic->variant;
> + struct regmap *regmap = pmic->regmap;
> + irq_hw_number_t hwirq = irqd_to_hwirq(d);
> + unsigned short i;
> +
> + for (i = 0; i < variant->num_groups; i++) {
for (ini i = 0; ...
Did I not bring this up last time?
> + const struct mtk_spmi_pmic_irq_grp *irq_grp = &variant->pmic_irq[i];
> + u32 con_reg;
> + u8 irq_en_bit;
> +
> + if (hwirq < irq_grp->hwirq_base)
> + continue;
> +
> + con_reg = irq_grp->con_reg + (variant->con_reg_len * i);
> + irq_en_bit = hwirq - irq_grp->hwirq_base;
> + regmap_assign_bits(regmap, con_reg, BIT(irq_en_bit), unmask);
> +
> + break;
> + }
> +}
> +
> +static void mtk_spmi_pmic_irq_mask(struct irq_data *d)
> +{
> + mtk_spmi_pmic_irq_set_unmasking(d, false);
> +}
> +
> +static void mtk_spmi_pmic_irq_unmask(struct irq_data *d)
> +{
> + mtk_spmi_pmic_irq_set_unmasking(d, true);
> +}
> +
> +static struct irq_chip mtk_spmi_pmic_irq_chip = {
> + .name = "mtk-spmi-pmic",
> + .irq_mask = mtk_spmi_pmic_irq_mask,
> + .irq_unmask = mtk_spmi_pmic_irq_unmask,
> + .flags = IRQCHIP_SKIP_SET_WAKE,
> +};
> +
> +static struct lock_class_key mtk_spmi_pmic_irq_lock_class, mtk_spmi_pmic_irq_request_class;
> +
> +static int mtk_spmi_pmic_irq_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + struct mtk_spmi_pmic *pmic = d->host_data;
> + u32 intsize = fwspec->param_count;
> + u32 *intspec = fwspec->param;
> + unsigned int irq_type_index;
> + unsigned int irq_num_index;
> +
> + /*
> + * Interrupt cell index - For interrupt size 3:
> + * [0] - SID Interrupt number
> + * [1] - SPMI PMIC (Sub-)Device Interrupt number
> + * [2] - Interrupt Type mask
> + *
> + * When only two cells are specified the SID Interrupt is not present.
> + */
> + if (intsize != 2 && intsize != 3) {
> + dev_err(pmic->dev, "Expected IRQ specifier of size 2 or 3, got %u\n", intsize);
> + return -EINVAL;
> + }
> +
> + /* irq_num_index refers to the SPMI (Sub-)Device Interrupt number */
> + irq_num_index = intsize - 2;
> + irq_type_index = irq_num_index + 1;
> +
> + /*
> + * For 3 cells, the IRQ number in intspec[0] is ignored on purpose here!
> + *
> + * This is because of how at least the first revision of the SPMI 2.0
> + * controller works in MediaTek SoCs: the controller will raise an
> + * interrupt for each SID (but doesn't know the details), and the
> + * specific IRQ number that got raised must be read from the PMIC or
> + * its sub-device driver.
> + * It's possible that this will change in the future with a newer
> + * revision of the SPMI controller, and this is why the device tree
> + * holds the full interrupt specifier.
> + *
> + * out_hwirq: SPMI PMIC (Sub-)Device Interrupt number
> + * out_type: Interrupt type sense mask
> + */
> + *out_hwirq = intspec[irq_num_index];
> + *out_type = intspec[irq_type_index] & IRQ_TYPE_SENSE_MASK;
> +
> + return 0;
> +}
> +
> +static int mtk_spmi_pmic_irq_alloc(struct irq_domain *d, unsigned int virq,
> + unsigned int nr_irqs, void *data)
> +{
> + struct mtk_spmi_pmic *pmic = d->host_data;
> + struct irq_fwspec *fwspec = data;
> + irq_hw_number_t hwirq;
> + unsigned int irqtype;
> + int i, ret;
> +
> + ret = mtk_spmi_pmic_irq_translate(d, fwspec, &hwirq, &irqtype);
> + if (ret)
> + return ret;
> +
> + for (i = 0; i < nr_irqs; i++) {
As above.
> + irq_set_lockdep_class(virq, &mtk_spmi_pmic_irq_lock_class,
> + &mtk_spmi_pmic_irq_request_class);
> + irq_domain_set_info(d, virq, hwirq, &mtk_spmi_pmic_irq_chip,
> + pmic, handle_level_irq, NULL, NULL);
> + }
> +
> + return 0;
> +}
> +
> +
> +static const struct irq_domain_ops mtk_spmi_pmic_irq_domain_ops = {
> + .alloc = mtk_spmi_pmic_irq_alloc,
> + .free = irq_domain_free_irqs_common,
> + .translate = mtk_spmi_pmic_irq_translate,
> +};
> +
> +static int mtk_spmi_pmic_handle_group_irq(struct mtk_spmi_pmic *pmic, int group)
> +{
> + const struct mtk_spmi_pmic_irq_grp *irq_grp = &pmic->variant->pmic_irq[group];
> + struct regmap *regmap = pmic->regmap;
> + struct device *dev = pmic->dev;
> + int i, ret;
Etc.
> +
> + for (i = 0; i < irq_grp->num_int_regs; i++) {
> + u32 status, saved_status;
> +
> + ret = regmap_read(regmap, irq_grp->sta_reg + i, &status);
> + if (ret) {
> + dev_err(dev, "Could not read IRQ status register: %d", ret);
> + return ret;
> + }
> +
> + if (status == 0)
> + continue;
> +
> + saved_status = status;
> + do {
> + irq_hw_number_t hwirq;
> + u8 bit = __ffs(status);
> +
> + /* Each register has 8 bits: this is the first IRQ of this group */
> + hwirq = MTK_SPMI_PMIC_VAL_BITS * i;
> +
> + /* Offset by this group's start interrupt */
> + hwirq += irq_grp->hwirq_base;
> +
> + /* Finally, offset by the fired IRQ's bit number */
> + hwirq += bit;
> +
> + status &= ~BIT(bit);
> +
> + generic_handle_domain_irq_safe(pmic->dom, hwirq);
> + } while (status);
> +
> + /* Clear the interrupts by writing the previous status */
> + regmap_write(regmap, irq_grp->sta_reg + i, saved_status);
> + }
> +
> + return 0;
> +}
> +
> +static void mtk_spmi_pmic_handle_chained_irq(struct irq_desc *desc)
> +{
> + struct mtk_spmi_pmic *pmic = irq_desc_get_handler_data(desc);
> + const struct mtk_spmi_pmic_variant *variant = pmic->variant;
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> + struct regmap *regmap = pmic->regmap;
> + bool irq_handled = false;
> + int i, ret;
> + u32 val;
> +
> + chained_irq_enter(chip, desc);
> +
> + /* If irq_grp_reg is present there are multiple IRQ groups */
> + if (variant->irq_grp_reg > 0) {
> + ret = regmap_read(regmap, variant->irq_grp_reg, &val);
> + if (ret)
> + handle_bad_irq(desc);
> +
> + /* This is very unlikely to happen */
> + if (val == 0) {
> + chained_irq_exit(chip, desc);
> + return;
> + }
> + } else {
> + val = BIT(0);
> + }
> +
> + for (i = 0; i < variant->num_groups; i++) {
> + const struct mtk_spmi_pmic_irq_grp *irq_grp = &variant->pmic_irq[i];
> + u8 group_bit = BIT(irq_grp[i].group_num);
Did you mean to index twice here?
irq_grp[i + i].group_num
> +
> + if (val & group_bit) {
> + ret = mtk_spmi_pmic_handle_group_irq(pmic, i);
> + if (ret == 0)
> + irq_handled = true;
> + }
> + }
> +
> + /* The RCS flag has to be cleared even if the IRQ was not handled. */
> + ret = regmap_write(regmap, MTK_SPMI_PMIC_RCS_IRQ_DONE, 1);
> + if (ret)
> + dev_warn(pmic->dev, "Could not clear RCS flag!\n");
> +
> + if (!irq_handled)
> + handle_bad_irq(desc);
> +
> + chained_irq_exit(chip, desc);
> +}
> +
> +static void mtk_spmi_pmic_irq_remove(void *data)
> +{
> + struct mtk_spmi_pmic *pmic = (struct mtk_spmi_pmic *)data;
You shouldn't need from a void.
> +
> + irq_set_chained_handler_and_data(pmic->irq, NULL, NULL);
> + irq_domain_remove(pmic->dom);
> +}
> +
> +static int mtk_spmi_pmic_irq_init(struct device *dev, struct regmap *regmap,
> + const struct mtk_spmi_pmic_variant *variant)
> +{
> + struct fwnode_handle *fwnode = of_fwnode_handle(dev->of_node);
> + struct mtk_spmi_pmic *pmic;
> + int ret;
> +
> + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
> + if (!pmic)
> + return -ENOMEM;
> +
> + pmic->irq = of_irq_get(dev->of_node, 0);
> + if (pmic->irq < 0)
> + return dev_err_probe(dev, pmic->irq, "Cannot get IRQ\n");
> +
> + pmic->dev = dev;
> + pmic->regmap = regmap;
> + pmic->variant = variant;
> +
> + pmic->dom = irq_domain_create_tree(fwnode, &mtk_spmi_pmic_irq_domain_ops, pmic);
> + if (!pmic->dom)
> + return dev_err_probe(dev, -ENOMEM, "Cannot create IRQ domain\n");
> +
> + ret = devm_add_action_or_reset(dev, mtk_spmi_pmic_irq_remove, pmic);
> + if (ret) {
> + irq_domain_remove(pmic->dom);
You just double-freed.
> + return ret;
> + }
> +
> + irq_set_chained_handler_and_data(pmic->irq, mtk_spmi_pmic_handle_chained_irq, pmic);
> +
> + return 0;
> +}
> +
> +#define MTK_SPMI_PMIC_IRQ_GROUP(pmic, group_name, group_index, first_irq, last_irq) \
> +{ \
> + .hwirq_base = first_irq, \
> + .num_int_regs = ((last_irq - first_irq) / MTK_SPMI_PMIC_VAL_BITS) + 1, \
> + .con_reg = pmic##_REG_##group_name##_TOP_INT_CON0, \
> + .sta_reg = pmic##_REG_##group_name##_TOP_INT_STATUS0, \
> + .group_num = group_index, \
> +}
> +
> +static const struct mtk_spmi_pmic_irq_grp mt6363_irq_groups[] = {
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, BUCK, 0, 0, 9),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, LDO, 1, 16, 40),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, PSC, 2, 48, 57),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, MISC, 3, 64, 79),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, HK, 4, 80, 87),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6363, BM, 6, 88, 107)
> +};
> +
> +static const struct mtk_spmi_pmic_irq_grp mt6373_irq_groups[] = {
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6373, BUCK, 0, 0, 9),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6373, LDO, 1, 16, 39),
> + MTK_SPMI_PMIC_IRQ_GROUP(MT6373, MISC, 3, 56, 71),
> +};
> +
> +static const struct mtk_spmi_pmic_variant mt6363_variant = {
> + .pmic_irq = mt6363_irq_groups,
> + .num_groups = ARRAY_SIZE(mt6363_irq_groups),
> + .con_reg_len = 3,
> + .irq_grp_reg = MT6363_REG_TOP_INT_STATUS1,
> + .chip_id_reg = MTK_SPMI_PMIC_REG_CHIP_ID,
> +};
> +
> +static const struct mtk_spmi_pmic_variant mt6373_variant = {
> + .pmic_irq = mt6373_irq_groups,
> + .num_groups = ARRAY_SIZE(mt6373_irq_groups),
> + .con_reg_len = 3,
> + .irq_grp_reg = MT6373_REG_TOP_INT_STATUS1,
> + .chip_id_reg = MTK_SPMI_PMIC_REG_CHIP_ID,
> +};
> +
> +static const struct regmap_config mtk_spmi_regmap_config = {
> + .reg_bits = 16,
> + .val_bits = MTK_SPMI_PMIC_VAL_BITS,
> + .max_register = 0xffff,
> + .fast_io = true,
> +};
> +
> +static int mtk_spmi_pmic_probe(struct spmi_device *sdev)
> +{
> + const struct mtk_spmi_pmic_variant *variant;
> + struct device *dev = &sdev->dev;
> + struct regmap *regmap;
> + int ret;
> +
> + regmap = devm_regmap_init_spmi_ext(sdev, &mtk_spmi_regmap_config);
> + if (IS_ERR(regmap))
> + return PTR_ERR(regmap);
> +
> + variant = (const struct mtk_spmi_pmic_variant *)device_get_match_data(dev);
Again, no casting required.
> + if (variant && variant->num_groups) {
> + ret = mtk_spmi_pmic_irq_init(dev, regmap, variant);
> + if (ret)
> + return ret;
> + }
> +
> + return devm_of_platform_populate(dev);
> +}
> +
> +static const struct of_device_id mtk_pmic_spmi_id_table[] = {
> + { .compatible = "mediatek,mt6363", .data = &mt6363_variant },
> + { .compatible = "mediatek,mt6373", .data = &mt6373_variant },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_pmic_spmi_id_table);
> +
> +static struct spmi_driver mtk_spmi_pmic_driver = {
> + .probe = mtk_spmi_pmic_probe,
> + .driver = {
> + .name = "mtk-spmi-pmic",
> + .of_match_table = mtk_pmic_spmi_id_table,
> + },
> +};
> +module_spmi_driver(mtk_spmi_pmic_driver);
> +
> +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
> +MODULE_DESCRIPTION("MediaTek SPMI PMIC driver");
> +MODULE_LICENSE("GPL");
> diff --git "a/include/linux/mfd/mt63x3_spmi/registers.h" "b/include/linux/mfd/mt63x3_spmi/registers.h
> new file mode 100644
> index 000000000000..808927280b40
> --- /dev/null
> +++ "b/include/linux/mfd/mt63x3_spmi/registers.h"
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Copyright (c) 2025 Collabora Ltd
> + */
> +
> +#ifndef __MFD_MT63X3_SPMI_REGISTERS_H__
> +#define __MFD_MT63X3_SPMI_REGISTERS_H__
> +
> +/* MT6363 PMIC Registers */
> +#define MT6363_REG_MISC_TOP_INT_CON0 0x37
> +#define MT6363_REG_MISC_TOP_INT_STATUS0 0x43
> +#define MT6363_REG_TOP_INT_STATUS1 0x4e
> +#define MT6363_REG_PSC_TOP_INT_CON0 0x90f
> +#define MT6363_REG_PSC_TOP_INT_STATUS0 0x91b
> +#define MT6363_REG_BM_TOP_INT_CON0 0xc24
> +#define MT6363_REG_BM_TOP_INT_STATUS0 0xc36
> +#define MT6363_REG_HK_TOP_INT_CON0 0xf92
> +#define MT6363_REG_HK_TOP_INT_STATUS0 0xf9e
> +#define MT6363_REG_BUCK_TOP_INT_CON0 0x1411
> +#define MT6363_REG_BUCK_TOP_INT_STATUS0 0x141d
> +#define MT6363_REG_LDO_TOP_INT_CON0 0x1b11
> +#define MT6363_REG_LDO_TOP_INT_STATUS0 0x1b29
> +
> +/* MT6373 PMIC Registers */
> +#define MT6373_REG_MISC_TOP_INT_CON0 0x3c
> +#define MT6373_REG_MISC_TOP_INT_STATUS0 0x48
> +#define MT6373_REG_TOP_INT_STATUS1 0x53
> +#define MT6373_REG_BUCK_TOP_INT_CON0 0x1411
> +#define MT6373_REG_BUCK_TOP_INT_STATUS0 0x141d
> +#define MT6373_REG_LDO_TOP_INT_CON0 0x1b10
> +#define MT6373_REG_LDO_TOP_INT_STATUS0 0x1b22
> +
> +#endif /* __MFD_MT63X3_SPMI_REGISTERS_H__ */
> --
> 2.53.0
>
--
Lee Jones
^ permalink raw reply
* Re: [PATCH v7 12/28] media: rockchip: rga: avoid odd frame sizes for YUV formats
From: Michael Tretter @ 2026-05-21 14:11 UTC (permalink / raw)
To: Sven Püschel
Cc: Jacob Chen, Ezequiel Garcia, Mauro Carvalho Chehab,
Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans Verkuil, linux-media, linux-rockchip, linux-arm-kernel,
linux-kernel, devicetree, kernel, nicolas, sebastian.reichel,
p.zabel, Nicolas Dufresne
In-Reply-To: <20260521-spu-rga3-v7-12-3f33e8c7145f@pengutronix.de>
On Thu, 21 May 2026 00:44:17 +0200, Sven Püschel wrote:
> Avoid odd frame sizes for YUV formats, as they may cause undefined
> behavior. This is done in preparation for the RGA3, which hangs when the
> output format is set to 129x129 pixel YUV420 SP (NV12).
>
> This requirement is documented explicitly for the RGA3 in section 5.6.3
> of the RK3588 TRM Part 2. For the RGA2 the RK3588 TRM Part 2
> (section 6.1.2) and RK3568 TRM Part 2 (section 14.2) only mentions the
> x/y offsets and stride aligning requirements. But the vendor driver for
> the RGA2 also contains checks for the width and height to be aligned to
> 2 bytes.
>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
> ---
> drivers/media/platform/rockchip/rga/rga.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
> index f599c992829dd..77b8c7ab74274 100644
> --- a/drivers/media/platform/rockchip/rga/rga.c
> +++ b/drivers/media/platform/rockchip/rga/rga.c
> @@ -337,6 +337,19 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
> struct rga_ctx *ctx = file_to_rga_ctx(file);
> const struct rga_hw *hw = ctx->rga->hw;
> struct rga_fmt *fmt;
> + struct v4l2_frmsize_stepwise frmsize = {
> + .min_width = hw->min_width,
> + .max_width = hw->max_width,
> + .min_height = hw->min_height,
> + .max_height = hw->max_height,
> + .step_width = 1,
> + .step_height = 1,
> + };
> +
> + if (v4l2_is_format_yuv(v4l2_format_info(pix_fmt->pixelformat))) {
> + frmsize.step_width = 2;
> + frmsize.step_height = 2;
If I understand correctly, this limitation may be a result of 4:2:0
chroma subsampling. Thus, formats with 4:2:2 subsampling would also work
with step_height = 1.
As this may be some hardware limitation, a comment that points to the
TRM (in addition to the commit message) may be beneficial, too.
Michael
> + }
>
> if (V4L2_TYPE_IS_CAPTURE(f->type)) {
> const struct rga_frame *frm;
> @@ -358,11 +371,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
> if (!fmt)
> fmt = &hw->formats[0];
>
> - pix_fmt->width = clamp(pix_fmt->width,
> - hw->min_width, hw->max_width);
> - pix_fmt->height = clamp(pix_fmt->height,
> - hw->min_height, hw->max_height);
> -
> + v4l2_apply_frmsize_constraints(&pix_fmt->width, &pix_fmt->height, &frmsize);
> v4l2_fill_pixfmt_mp(pix_fmt, fmt->fourcc, pix_fmt->width, pix_fmt->height);
> pix_fmt->field = V4L2_FIELD_NONE;
>
>
> --
> 2.54.0
>
>
^ permalink raw reply
* [PATCH v2 1/3] dt-bindings: display: bridge: analogix-dp: Add data-lanes support for endpoint
From: Damon Ding @ 2026-05-21 11:44 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260521114459.1394264-1-damon.ding@rock-chips.com>
Add data-lanes property support to the port@1 endpoint for physical
lane mapping configuration.
Lane mapping is mainly used for below scenarios:
1. Correct PCB lane swap and differential line routing crossover
without hardware changes;
2. Adapt mismatched lane pin definitions between SoC and eDP panel;
3. Support multiple panel hardware variants on the same board
by configuring data-lanes in device tree only.
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v2:
- Add lane mapping application scenarios in commit message.
- Remove redundant deprecated property 'data-lanes' for eDP node.
- Update port@1 $ref to /schemas/graph.yaml#/$defs/port-base.
---
.../bindings/display/bridge/analogix,dp.yaml | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
index 62f0521b0924..e34fdb21adb4 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
@@ -42,13 +42,20 @@ properties:
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
- description:
- Input node to receive pixel data.
+ description: Input node to receive pixel data.
port@1:
- $ref: /schemas/graph.yaml#/properties/port
- description:
- Port node with one endpoint connected to a dp-connector node.
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ description: Port node with one endpoint connected to sink device node.
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+ items:
+ enum: [ 0, 1, 2, 3 ]
required:
- port@0
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/2] cpufreq: qcom: Add cpufreq scaling support for Qualcomm Shikra SoC
From: Imran Shaik @ 2026-05-21 14:06 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-pm, devicetree,
linux-kernel, linux-arm-msm, Imran Shaik, Konrad Dybcio
In-Reply-To: <20260521-shikra-cpufreq-scaling-v3-0-883c13d1e514@oss.qualcomm.com>
From: Taniya Das <taniya.das@oss.qualcomm.com>
The Qualcomm Shikra cpufreq hardware is functionally identical to EPSS,
but supports only up to 12 frequency lookup table (LUT) entries. When all
12 entries are populated, the existing repetitive LUT entry check may read
beyond valid entries and expose incorrect frequencies. Hence, introduce
shikra_epss_soc_data that reuses EPSS configuration with appropriate LUT
entries limit.
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
drivers/cpufreq/qcom-cpufreq-hw.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index ea9a20d27b8fdceb9341ee53e5fa27b7a6d92483..3d5a865fb8a35e112cb4d040fb519e2c122a91dc 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitfield.h>
@@ -40,6 +41,7 @@ struct qcom_cpufreq_soc_data {
u32 reg_intr_clr;
u32 reg_current_vote;
u32 reg_perf_state;
+ u32 lut_max_entries;
u8 lut_row_size;
};
@@ -156,7 +158,7 @@ static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy)
soc_data = qcom_cpufreq.soc_data;
index = readl_relaxed(data->base + soc_data->reg_perf_state);
- index = min(index, LUT_MAX_ENTRIES - 1);
+ index = min(index, soc_data->lut_max_entries - 1);
return policy->freq_table[index].frequency;
}
@@ -211,7 +213,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
struct qcom_cpufreq_data *drv_data = policy->driver_data;
const struct qcom_cpufreq_soc_data *soc_data = qcom_cpufreq.soc_data;
- table = kzalloc_objs(*table, LUT_MAX_ENTRIES + 1);
+ table = kzalloc_objs(*table, soc_data->lut_max_entries + 1);
if (!table)
return -ENOMEM;
@@ -236,7 +238,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
icc_scaling_enabled = false;
}
- for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+ for (i = 0; i < soc_data->lut_max_entries; i++) {
data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut +
i * soc_data->lut_row_size);
src = FIELD_GET(LUT_SRC, data);
@@ -405,6 +407,7 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = {
.reg_current_vote = 0x704,
.reg_perf_state = 0x920,
.lut_row_size = 32,
+ .lut_max_entries = LUT_MAX_ENTRIES,
};
static const struct qcom_cpufreq_soc_data epss_soc_data = {
@@ -416,11 +419,25 @@ static const struct qcom_cpufreq_soc_data epss_soc_data = {
.reg_intr_clr = 0x308,
.reg_perf_state = 0x320,
.lut_row_size = 4,
+ .lut_max_entries = LUT_MAX_ENTRIES,
+};
+
+static const struct qcom_cpufreq_soc_data shikra_epss_soc_data = {
+ .reg_enable = 0x0,
+ .reg_domain_state = 0x20,
+ .reg_dcvs_ctrl = 0xb0,
+ .reg_freq_lut = 0x100,
+ .reg_volt_lut = 0x200,
+ .reg_intr_clr = 0x308,
+ .reg_perf_state = 0x320,
+ .lut_row_size = 4,
+ .lut_max_entries = 12,
};
static const struct of_device_id qcom_cpufreq_hw_match[] = {
{ .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data },
{ .compatible = "qcom,cpufreq-epss", .data = &epss_soc_data },
+ { .compatible = "qcom,shikra-epss", .data = &shikra_epss_soc_data },
{}
};
MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 1/2] dt-bindings: cpufreq: qcom-hw: Document Shikra CPUFREQ Hardware
From: Imran Shaik @ 2026-05-21 14:06 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-pm, devicetree,
linux-kernel, linux-arm-msm, Imran Shaik
In-Reply-To: <20260521-shikra-cpufreq-scaling-v3-0-883c13d1e514@oss.qualcomm.com>
The Qualcomm Shikra cpufreq hardware is functionally identical to EPSS,
but supports only up to 12 frequency lookup table (LUT) entries. Introduce
Shikra specific bindings to represent this constrained EPSS variant.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
.../bindings/cpufreq/qcom,shikra-epss.yaml | 96 ++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/Documentation/devicetree/bindings/cpufreq/qcom,shikra-epss.yaml b/Documentation/devicetree/bindings/cpufreq/qcom,shikra-epss.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8543fd00d82acdbb3422bde462417118aa4c49d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/qcom,shikra-epss.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/qcom,shikra-epss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CPUFREQ HW for Qualcomm Shikra SoC
+
+maintainers:
+ - Imran Shaik <imran.shaik@oss.qualcomm.com>
+ - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+ CPUFREQ HW is a hardware engine used by some Qualcomm SoCs to manage
+ frequency in hardware. It is capable of controlling frequency for
+ multiple clusters.
+
+ The Qualcomm Shikra CPUFREQ HW supports up to 12 frequency lookup table
+ (LUT) entries.
+
+properties:
+ compatible:
+ enum:
+ - qcom,shikra-epss
+
+ reg:
+ items:
+ - description: Frequency domain 0 register region
+ - description: Frequency domain 1 register region
+
+ reg-names:
+ items:
+ - const: freq-domain0
+ - const: freq-domain1
+
+ clocks:
+ items:
+ - description: XO Clock
+ - description: GPLL0 Clock
+
+ clock-names:
+ items:
+ - const: xo
+ - const: alternate
+
+ interrupts:
+ items:
+ - description: IRQ line for DCVSH 0
+ - description: IRQ line for DCVSH 1
+
+ interrupt-names:
+ items:
+ - const: dcvsh-irq-0
+ - const: dcvsh-irq-1
+
+ '#freq-domain-cells':
+ const: 1
+
+ '#clock-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+ - interrupt-names
+ - '#freq-domain-cells'
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,rpmcc.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpufreq@fd91000 {
+ compatible = "qcom,shikra-epss";
+ reg = <0x0fd91000 0x1000>, <0x0fd92000 0x1000>;
+ reg-names = "freq-domain0", "freq-domain1";
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gpll0>;
+ clock-names = "xo", "alternate";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1";
+ #freq-domain-cells = <1>;
+ #clock-cells = <1>;
+ };
+ };
+...
--
2.34.1
^ permalink raw reply related
* [PATCH v3 0/2] Add cpufreq scaling support for Qualcomm Shikra SoC
From: Imran Shaik @ 2026-05-21 14:06 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manivannan Sadhasivam
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-pm, devicetree,
linux-kernel, linux-arm-msm, Imran Shaik, Konrad Dybcio
This series adds cpufreq scaling support on Qualcomm Shikra SoC.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
Changes in v3:
- Updated bindings as per the review comments [Krzysztof]
- Updated driver patch commit text [Dmitry]
- Updated compatible in driver patch as per the bindings
- Link to v2: https://lore.kernel.org/r/20260519-shikra-cpufreq-scaling-v2-0-2b09f0e1c9d8@oss.qualcomm.com
Changes in v2:
- Dropped the generic compatible approach, and introduced Shikra
specific bindings [Krzysztof]
- Updated the driver patch as per the latest bindings changes
- Added R-By tag received in V1.
- Link to v1: https://lore.kernel.org/r/20260501-shikra-cpufreq-scaling-v1-0-c78b95f53b91@oss.qualcomm.com
---
Imran Shaik (1):
dt-bindings: cpufreq: qcom-hw: Document Shikra CPUFREQ Hardware
Taniya Das (1):
cpufreq: qcom: Add cpufreq scaling support for Qualcomm Shikra SoC
.../bindings/cpufreq/qcom,shikra-epss.yaml | 96 ++++++++++++++++++++++
drivers/cpufreq/qcom-cpufreq-hw.c | 23 +++++-
2 files changed, 116 insertions(+), 3 deletions(-)
---
base-commit: 0787c45ea08a13b5482e701fabc741877cf681f6
change-id: 20260430-shikra-cpufreq-scaling-aff690130063
Best regards,
--
Imran Shaik <imran.shaik@oss.qualcomm.com>
^ permalink raw reply
* [PATCH 4/4] phy: qcom: qmp-pcie: Add QMP PCIe PHY support for Eliza
From: Krishna Chaitanya Chundru @ 2026-05-21 14:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krishna Chaitanya Chundru
In-Reply-To: <20260521-eliza-v1-0-97cdbe88389d@oss.qualcomm.com>
Add QMP PCIe PHY support for the Eliza SoC. Introduce a new Gen3x1 PHY
configuration with Eliza-specific initialization tables, and reuse the
existing sm8550 Gen3x2 configuration for the Gen3x2 PHY instance.
Also add the missing QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1 register
definition to the PCIe V6 PCS header.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 139 ++++++++++++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h | 1 +
2 files changed, 140 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index fed2fc9bb311..113c5f8f1dbc 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -198,6 +198,112 @@ static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
};
+static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x93),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE1, 0xB4),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xA0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_3, 0x0F),
+};
+
+static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_REFGEN_REQ_CONFIG1, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_G3S2_PRE_GAIN, 0x2E),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_RX_SIGDET_LVL, 0x77),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_RATE_SLEW_CNTRL1, 0x0B),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_PCS_TX_RX_CONFIG, 0x0C),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG2, 0x0F),
+};
+
+static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_misc_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1D),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xC1),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27),
+};
+
+static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x15),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_4, 0x3F),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V6_TX_PI_QEC_CTRL, 0x02),
+};
+
+static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7F),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_PI_CONTROLS, 0xF0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xF0),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0F),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x0D),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4A),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0A),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIDGET_ENABLES, 0x0C),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3F),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xBF),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xBF),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xB7),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xEA),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xDC),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5C),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9C),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1A),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH, 0x94),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5B),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1A),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
+};
+
static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
@@ -3532,6 +3638,33 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
.txrxz = 0xd000,
};
+static const struct qmp_phy_cfg eliza_qmp_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = eliza_qmp_gen3x1_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_serdes_tbl),
+ .tx = eliza_qmp_gen3x1_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_tx_tbl),
+ .rx = eliza_qmp_gen3x1_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_rx_tbl),
+ .pcs = eliza_qmp_gen3x1_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_pcs_tbl),
+ .pcs_misc = eliza_qmp_gen3x1_pcie_misc_pcs_tbl,
+ .pcs_misc_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_misc_pcs_tbl),
+ },
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = pciephy_v6_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.lanes = 1,
@@ -5399,6 +5532,12 @@ static int qmp_pcie_probe(struct platform_device *pdev)
static const struct of_device_id qmp_pcie_of_match_table[] = {
{
+ .compatible = "qcom,eliza-qmp-gen3x1-pcie-phy",
+ .data = &eliza_qmp_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,eliza-qmp-gen3x2-pcie-phy",
+ .data = &sm8550_qmp_gen3x2_pciephy_cfg,
+ }, {
.compatible = "qcom,glymur-qmp-gen4x2-pcie-phy",
.data = &glymur_qmp_gen4x2_pciephy_cfg,
}, {
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
index 45397cb3c0c6..17a0f9d18acf 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
@@ -12,6 +12,7 @@
#define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
#define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4 0x14
#define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
+#define QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x54
#define QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
#define QPHY_PCIE_V6_PCS_LANE1_INSIG_SW_CTRL2 0x024
--
2.34.1
^ permalink raw reply related
* [PATCH 3/4] PCI: qcom: Add Support for Eliza
From: Krishna Chaitanya Chundru @ 2026-05-21 14:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krishna Chaitanya Chundru
In-Reply-To: <20260521-eliza-v1-0-97cdbe88389d@oss.qualcomm.com>
Add support for Eliza soc, which has two PCIe controllers capable
of 8GT/s X1 and 8GT/s X2, using the cfg_1_9_0 configuration.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index af6bf5cce65b..40f0a5f247eb 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -2123,6 +2123,7 @@ static int qcom_pcie_resume_noirq(struct device *dev)
static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
{ .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
+ { .compatible = "qcom,pcie-eliza", .data = &cfg_1_9_0 },
{ .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
{ .compatible = "qcom,pcie-ipq5018", .data = &cfg_2_9_0 },
{ .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
--
2.34.1
^ permalink raw reply related
* [PATCH 2/4] dt-bindings: PCI: qcom: Document the Eliza PCIe Controller
From: Krishna Chaitanya Chundru @ 2026-05-21 14:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krishna Chaitanya Chundru
In-Reply-To: <20260521-eliza-v1-0-97cdbe88389d@oss.qualcomm.com>
Add a dedicated schema for the PCIe root complex controller found on the
Qualcomm Eliza SoC. The controller is based on the Synopsis DesignWare PCIe
IP and requires a platform-specific set of clocks that differ from existing
Qcom PCIe schemas.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
.../devicetree/bindings/pci/qcom,pcie-eliza.yaml | 165 +++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-eliza.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-eliza.yaml
new file mode 100644
index 000000000000..826e2adf4fda
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-eliza.yaml
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/qcom,pcie-eliza.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Eliza PCI Express Root Complex
+
+maintainers:
+ - Bjorn Andersson <andersson@kernel.org>
+ - Manivannan Sadhasivam <mani@kernel.org>
+
+description:
+ Qualcomm ELIZA SoC (and compatible) PCIe root complex controller is based on
+ the Synopsis DesignWare PCIe IP.
+
+properties:
+ compatible:
+ const: qcom,pcie-eliza
+
+ reg:
+ minItems: 5
+ maxItems: 6
+
+ reg-names:
+ minItems: 5
+ items:
+ - const: parf # Qualcomm specific registers
+ - const: dbi # DesignWare PCIe registers
+ - const: elbi # External local bus interface registers
+ - const: atu # ATU address space
+ - const: config # PCIe configuration space
+ - const: mhi # MHI registers
+
+ clocks:
+ maxItems: 7
+
+ clock-names:
+ items:
+ - const: aux # Auxiliary clock
+ - const: cfg # Configuration clock
+ - const: bus_master # Master AXI clock
+ - const: bus_slave # Slave AXI clock
+ - const: slave_q2a # Slave Q2A clock
+ - const: ddrss_sf_tbu # PCIe SF TBU clock
+ - const: cnoc_sf_axi # Config NoC PCIe1 AXI clock
+
+ interrupts:
+ minItems: 8
+ maxItems: 9
+
+ interrupt-names:
+ minItems: 8
+ items:
+ - const: msi0
+ - const: msi1
+ - const: msi2
+ - const: msi3
+ - const: msi4
+ - const: msi5
+ - const: msi6
+ - const: msi7
+ - const: global
+
+ resets:
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: pci # PCIe core reset
+ - const: link_down # PCIe link down reset
+
+required:
+ - power-domains
+ - resets
+ - reset-names
+
+allOf:
+ - $ref: qcom,pcie-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,eliza-gcc.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interconnect/qcom,eliza-rpmh.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie@1c00000 {
+ compatible = "qcom,pcie-eliza";
+ reg = <0 0x01c00000 0 0x3000>,
+ <0 0x40000000 0 0xf1d>,
+ <0 0x40000f20 0 0xa8>,
+ <0 0x40001000 0 0x1000>,
+ <0 0x40100000 0 0x100000>;
+ reg-names = "parf", "dbi", "elbi", "atu", "config";
+ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+ <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x3d00000>;
+
+ bus-range = <0x00 0xff>;
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ num-lanes = <1>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+ <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+ <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+ <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a",
+ "ddrss_sf_tbu",
+ "cnoc_sf_axi";
+
+ dma-coherent;
+
+ interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 537 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 540 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0", "msi1", "msi2", "msi3",
+ "msi4", "msi5", "msi6", "msi7", "global";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 0 564 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+ <0 0 0 2 &intc 0 0 0 565 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+ <0 0 0 3 &intc 0 0 0 566 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+ <0 0 0 4 &intc 0 0 0 567 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+ interconnects = <&pcie_noc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>,
+ <&gem_noc MASTER_APPSS_PROC 0 &cnoc_main SLAVE_PCIE_0 0>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+
+ iommu-map = <0x0 &apps_smmu 0x1480 0x1>,
+ <0x100 &apps_smmu 0x1481 0x1>;
+
+ pinctrl-0 = <&pcie0_default_state>;
+ pinctrl-names = "default";
+
+ power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+ resets = <&gcc GCC_PCIE_0_BCR>,
+ <&gcc GCC_PCIE_0_LINK_DOWN_BCR>;
+ reset-names = "pci",
+ "link_down";
+
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH 1/4] dt-bindings: phy: sc8280xp-qmp-pcie: Document Eliza PCIe phy
From: Krishna Chaitanya Chundru @ 2026-05-21 14:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krishna Chaitanya Chundru
In-Reply-To: <20260521-eliza-v1-0-97cdbe88389d@oss.qualcomm.com>
Add compatibles for the Eliza PCIe QMP PHY's, which supports Gen3x1 and
Gen3x2 configurations.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
.../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
index 3a35120a77ec..be4bbc327982 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -16,6 +16,8 @@ description:
properties:
compatible:
enum:
+ - qcom,eliza-qmp-gen3x1-pcie-phy
+ - qcom,eliza-qmp-gen3x2-pcie-phy
- qcom,glymur-qmp-gen4x2-pcie-phy
- qcom,glymur-qmp-gen5x4-pcie-phy
- qcom,kaanapali-qmp-gen3x2-pcie-phy
@@ -181,6 +183,8 @@ allOf:
compatible:
contains:
enum:
+ - qcom,eliza-qmp-gen3x1-pcie-phy
+ - qcom,eliza-qmp-gen3x2-pcie-phy
- qcom,glymur-qmp-gen4x2-pcie-phy
- qcom,glymur-qmp-gen5x4-pcie-phy
- qcom,qcs8300-qmp-gen4x2-pcie-phy
@@ -206,6 +210,8 @@ allOf:
compatible:
contains:
enum:
+ - qcom,eliza-qmp-gen3x1-pcie-phy
+ - qcom,eliza-qmp-gen3x2-pcie-phy
- qcom,glymur-qmp-gen4x2-pcie-phy
- qcom,glymur-qmp-gen5x4-pcie-phy
- qcom,kaanapali-qmp-gen3x2-pcie-phy
--
2.34.1
^ permalink raw reply related
* [PATCH 0/4] PCI: qcom: Add support for Eliza
From: Krishna Chaitanya Chundru @ 2026-05-21 14:05 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krishna Chaitanya Chundru
This series adds PCIe support for the Qualcomm Eliza SoC. Eliza includes
two PCIe root complex controllers capable of 8GT/s x1 and 8GT/s x2,
both using the cfg_1_9_0 configuration.
The QMP PCIe PHY support adds a new Gen3x1 PHY configuration with
Eliza-specific initialization tables, and reuses the existing SM8550
Gen3x2 configuration for the x2 PHY instance.
The series consists of:
- dt-bindings for the Eliza PCIe QMP PHY
- dt-bindings schema for the Eliza PCIe controller
- Driver entry in the Qcom PCIe controller for Eliza
- QMP PCIe PHY initialization tables and configuration for Eliza
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
Krishna Chaitanya Chundru (4):
dt-bindings: phy: sc8280xp-qmp-pcie: Document Eliza PCIe phy
dt-bindings: PCI: qcom: Document the Eliza PCIe Controller
PCI: qcom: Add Support for Eliza
phy: qcom: qmp-pcie: Add QMP PCIe PHY support for Eliza
.../devicetree/bindings/pci/qcom,pcie-eliza.yaml | 165 +++++++++++++++++++++
.../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 6 +
drivers/pci/controller/dwc/pcie-qcom.c | 1 +
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 139 +++++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h | 1 +
5 files changed, 312 insertions(+)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260427-eliza-e53155ae8821
Best regards,
--
Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2 08/10] arm64: dts: renesas: r9a07g0{43,44,54}: remove TCIU8 interrupt from MTU3
From: Geert Uytterhoeven @ 2026-05-21 13:59 UTC (permalink / raw)
To: Cosmin-Gabriel Tanislav
Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, Biju Das, Daniel Lezcano,
Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <TYYPR01MB15615A925B2F724C51DD033EA850E2@TYYPR01MB15615.jpnprd01.prod.outlook.com>
Hi Cosmin,
On Thu, 21 May 2026 at 15:54, Cosmin-Gabriel Tanislav
<cosmin-gabriel.tanislav.xa@renesas.com> wrote:
> Hi Geert, is it too late in the cycle for this to be picked up for 7.2?
No, it is not.
> > From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> > Sent: Friday, April 10, 2026 7:35 PM
> >
> > The TCIU8 interrupt used to be documented in earlier revisions of the
> > user manuals, but has since been removed. The corresponding entry is now
> > marked as reserved in the interrupt mapping tables of all supported
> > SoCs.
> >
> > * Page 486, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/G2UL
> > Rev.1.40 User Manual
> > * Page 363, Table 8.2 Interrupt Mapping (6/13) in the Renesas RZ/Five
> > Rev.1.30 User Manual
> > * Page 528, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/G2L
> > and RZ/G2LC Rev.1.50 User Manual
> > * Page 540, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/V2L
> > Rev.1.50 User Manual
> >
> > Remove the TCIU8 interrupt. This does not cause any breakage as the
> > driver does not make use of the interrupts.
> >
> > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: (subset) [PATCH 0/4] power: sys-off: fix Pixel C shutdown via MAX77620
From: Diogo Ivo @ 2026-05-21 13:59 UTC (permalink / raw)
To: Lee Jones
Cc: Mark Rutland, Lorenzo Pieralisi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
linux-kernel, devicetree, linux-tegra
In-Reply-To: <20260521104136.GA2921053@google.com>
On 5/21/26 12:41, Lee Jones wrote:
> On Thu, 21 May 2026, Diogo Ivo wrote:
>
>> Hi Lee,
>>
>> On 5/20/26 18:25, Lee Jones wrote:
>>> On Thu, 14 May 2026 16:47:18 +0200, Diogo Ivo wrote:
>>>> This series migrates PSCI and MAX77620 poweroff handling to the
>>>> sys-off framework and fixes shutdown on the Pixel C (Smaug).
>>>>
>>>> The first two patches replace legacy pm_power_off usage in the PSCI
>>>> and MAX77620 drivers with sys-off handlers. Besides aligning both
>>>> drivers with the modern poweroff infrastructure, this removes the
>>>> global callback dependency and allows multiple handlers to coexist
>>>> with explicit priorities.
>>>>
>>>> [...]
>>>
>>> Applied, thanks!
>>
>> Thanks for applying the patches! Just a question and an observation:
>>
>> - I'm assuming you were ok with merging [2/4] despite the possible
>> deadlock since this risk is already present in mainline in the same
>> form so we're not actually making things worse, is that so?
>
> Did you see the text below?
Yes, but patch 3 is not addressing the possible deadlock hence my
question.
> Both patches 2 and 3 are applied.
>
>> - The observation is that the comment about overriding PSCI is only
>> true after (and if) a reworked [1/4] is actually merged.
>> If it isn't then patch [3/4] is actually working around another handler
>> in soc/tegra/pmc.c where a handler that only does work for the Nexus
>> 7 is actually registered at FIRMWARE level for all platforms that
>> probe that driver (I will send out a patch shortly to only register
>> the handler on the Nexus 7).
>
> I assume the other patches will be applied soon.
>
> If this causes some kind of issue - let me know later on in the cycle
> and I'll remove whatever patches you ask me to.
The PSCI patch [1/4] has a fundamental issue and needs a respin to be
applied.
In connection with this it might then become easier to quirk the PSCI
driver rather than the PMIC driver, so for the moment I'll ask you to
drop [3/4] until I propose the changes to the PSCI maintainers and see
the feedback and at that point we can either completely drop [3/4] or
reapply it; sorry for the noise.
Best regards,
Diogo
^ permalink raw reply
* Re: [PATCH v3 2/2] remoteproc: qcom: pas: Add Shikra remoteproc support
From: sashiko-bot @ 2026-05-21 13:56 UTC (permalink / raw)
To: Komal Bajaj; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260521-shikra-rproc-v3-2-2fca0bbe1ad7@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing `ssctl_id` initialization for `shikra_lpaicp_resource` causing graceful shutdown failure.
--
commit de542ab4b48a2146f6973ba793bbbd6328de204c
Author: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
remoteproc: qcom: pas: Add Shikra remoteproc support
This commit adds the CDSP, LPAICP and MPSS Peripheral Authentication Service
support for the Qualcomm Shikra SoC.
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index da27d1d3c9da6..0101f1db6458e 100644
> --- a/drivers/remoteproc/qcom_q6v5_pas.c
> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
[ ... ]
> @@ -1457,6 +1457,51 @@ static const struct qcom_pas_data sc7280_wpss_resource = {
[ ... ]
> +static const struct qcom_pas_data shikra_lpaicp_resource = {
> + .crash_reason_smem = 682,
> + .firmware_name = "lpaicp.mbn",
> + .dtb_firmware_name = "lpaicp_dtb.mbn",
> + .pas_id = 0x56,
> + .dtb_pas_id = 0x57,
> + .minidump_id = 0,
> + .auto_boot = true,
> + .ssr_name = "lpaicp",
> + .sysmon_name = "lpaicp",
> +};
[Severity: High]
Does this resource definition need an ssctl_id initialized?
The sysmon subdevice is enabled by setting .sysmon_name = "lpaicp", but it
fails to define .ssctl_id. Because .ssctl_id is uninitialized, it defaults
to 0, which means qcom_add_sysmon_subdev() will be passed 0 as the QMI
SSCTL instance ID.
Looking at ssctl_new_server() in drivers/remoteproc/qcom_sysmon.c, the
version 2 QMI service binding requires svc->instance ==
sysmon->ssctl_instance. Since modern Qualcomm PAS QMI SSCTL services
advertise non-zero instance IDs, could this cause the binding to fail?
If the remoteproc framework never establishes an SSCTL connection to the
LPAICP DSP, sysmon_stop() will explicitly skip waiting for the SSCTL service
connection since ssctl_instance == 0.
When the DSP needs to be stopped, will sysmon_stop() bypass
ssctl_request_shutdown() and forcefully power off the DSP instead of
gracefully shutting down?
Forceful shutdowns of active DSPs can lead to hardware state corruption
or SMMU faults, which often cascade into kernel panics on these platforms.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-shikra-rproc-v3-0-2fca0bbe1ad7@oss.qualcomm.com?part=2
^ permalink raw reply
* Re: [PATCH v7 11/28] media: rockchip: rga: move hw specific parts to a dedicated struct
From: Michael Tretter @ 2026-05-21 13:56 UTC (permalink / raw)
To: Sven Püschel
Cc: Jacob Chen, Ezequiel Garcia, Mauro Carvalho Chehab,
Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans Verkuil, linux-media, linux-rockchip, linux-arm-kernel,
linux-kernel, devicetree, kernel, nicolas, sebastian.reichel,
p.zabel, Nicolas Dufresne
In-Reply-To: <20260521-spu-rga3-v7-11-3f33e8c7145f@pengutronix.de>
On Thu, 21 May 2026 00:44:16 +0200, Sven Püschel wrote:
> In preparation for the RGA3 unit, move RGA2 specific parts from rga.c
> to rga-hw.c and create a struct to reference the RGA2 specific functions
> and formats. This also allows to remove the rga-hw.h reference from the
> include list of the rga driver.
>
> Also document the command finish interrupt with a dedicated define.
>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
A few nits below, but
Reviewed-by: Michael Tretter <m.tretter@pengutronix.de>
> ---
> drivers/media/platform/rockchip/rga/rga-hw.c | 166 ++++++++++++++++++++-
> drivers/media/platform/rockchip/rga/rga-hw.h | 5 +-
> drivers/media/platform/rockchip/rga/rga.c | 211 +++++----------------------
> drivers/media/platform/rockchip/rga/rga.h | 23 ++-
> 4 files changed, 227 insertions(+), 178 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
> index ec6c17504ca15..40498796507e0 100644
> --- a/drivers/media/platform/rockchip/rga/rga-hw.c
> +++ b/drivers/media/platform/rockchip/rga/rga-hw.c
> @@ -437,8 +437,8 @@ static void rga_cmd_set(struct rga_ctx *ctx,
> PAGE_SIZE, DMA_BIDIRECTIONAL);
> }
>
> -void rga_hw_start(struct rockchip_rga *rga,
> - struct rga_vb_buffer *src, struct rga_vb_buffer *dst)
> +static void rga_hw_start(struct rockchip_rga *rga,
> + struct rga_vb_buffer *src, struct rga_vb_buffer *dst)
> {
> struct rga_ctx *ctx = rga->curr;
>
> @@ -452,3 +452,165 @@ void rga_hw_start(struct rockchip_rga *rga,
>
> rga_write(rga, RGA_CMD_CTRL, 0x1);
> }
> +
> +static bool rga_handle_irq(struct rockchip_rga *rga)
Returning a bool for success prevents to report any error interrupts to
the core. I guess that's fine and can be changed later, if it may be
necessary.
> +{
> + int intr;
> +
> + intr = rga_read(rga, RGA_INT) & 0xf;
> +
> + rga_mod(rga, RGA_INT, intr << 4, 0xf << 4);
> +
> + return intr & RGA_INT_COMMAND_FINISHED;
> +}
> +
> +static void rga_get_version(struct rockchip_rga *rga)
> +{
> + rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
> + rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
> +}
> +
> +static struct rga_fmt formats[] = {
> + {
> + .fourcc = V4L2_PIX_FMT_ARGB32,
> + .color_swap = RGA_COLOR_ALPHA_SWAP,
> + .hw_format = RGA_COLOR_FMT_ABGR8888,
> + .depth = 32,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_ABGR32,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_ABGR8888,
> + .depth = 32,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_XBGR32,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_XBGR8888,
> + .depth = 32,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_RGB24,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_RGB888,
> + .depth = 24,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_BGR24,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_RGB888,
> + .depth = 24,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_ARGB444,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_ABGR4444,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_ARGB555,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_ABGR1555,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_RGB565,
> + .color_swap = RGA_COLOR_RB_SWAP,
> + .hw_format = RGA_COLOR_FMT_BGR565,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_NV21,
> + .color_swap = RGA_COLOR_UV_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV420SP,
> + .depth = 12,
> + .y_div = 2,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_NV61,
> + .color_swap = RGA_COLOR_UV_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV422SP,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_NV12,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV420SP,
> + .depth = 12,
> + .y_div = 2,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_NV12M,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV420SP,
> + .depth = 12,
> + .y_div = 2,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_NV16,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV422SP,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 1,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_YUV420,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV420P,
> + .depth = 12,
> + .y_div = 2,
> + .x_div = 2,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_YUV422P,
> + .color_swap = RGA_COLOR_NONE_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV422P,
> + .depth = 16,
> + .y_div = 1,
> + .x_div = 2,
> + },
> + {
> + .fourcc = V4L2_PIX_FMT_YVU420,
> + .color_swap = RGA_COLOR_UV_SWAP,
> + .hw_format = RGA_COLOR_FMT_YUV420P,
> + .depth = 12,
> + .y_div = 2,
> + .x_div = 2,
> + },
> +};
> +
> +const struct rga_hw rga2_hw = {
> + .formats = formats,
> + .num_formats = ARRAY_SIZE(formats),
> + .cmdbuf_size = RGA_CMDBUF_SIZE,
> + .min_width = MIN_WIDTH,
> + .max_width = MAX_WIDTH,
> + .min_height = MIN_HEIGHT,
> + .max_height = MAX_HEIGHT,
> +
> + .start = rga_hw_start,
> + .handle_irq = rga_handle_irq,
> + .get_version = rga_get_version,
> +};
> diff --git a/drivers/media/platform/rockchip/rga/rga-hw.h b/drivers/media/platform/rockchip/rga/rga-hw.h
> index 2b8537a5fd0d7..c2e34be751939 100644
> --- a/drivers/media/platform/rockchip/rga/rga-hw.h
> +++ b/drivers/media/platform/rockchip/rga/rga-hw.h
> @@ -15,9 +15,6 @@
> #define MIN_WIDTH 34
> #define MIN_HEIGHT 34
>
> -#define DEFAULT_WIDTH 100
> -#define DEFAULT_HEIGHT 100
> -
> #define RGA_TIMEOUT 500
>
> /* Registers address */
> @@ -178,6 +175,8 @@
> #define RGA_ALPHA_COLOR_NORMAL 0
> #define RGA_ALPHA_COLOR_MULTIPLY_CAL 1
>
> +#define RGA_INT_COMMAND_FINISHED 4
This is probably a bitfield in the interrupt register:
#define RGA_INT_COMMAND_FINISHED 0x4
or
#define RGA_INT_COMMAND_FINISHED BIT(2)
> +
> /* Registers union */
> union rga_mode_ctrl {
> unsigned int val;
> diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
> index 8c34f73d69764..f599c992829dd 100644
> --- a/drivers/media/platform/rockchip/rga/rga.c
> +++ b/drivers/media/platform/rockchip/rga/rga.c
> @@ -25,7 +25,6 @@
> #include <media/videobuf2-dma-sg.h>
> #include <media/videobuf2-v4l2.h>
>
> -#include "rga-hw.h"
> #include "rga.h"
>
> static int debug;
> @@ -47,7 +46,7 @@ static void device_run(void *prv)
>
> dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
>
> - rga_hw_start(rga, vb_to_rga(src), vb_to_rga(dst));
> + rga->hw->start(rga, vb_to_rga(src), vb_to_rga(dst));
>
> spin_unlock_irqrestore(&rga->ctrl_lock, flags);
> }
> @@ -55,13 +54,8 @@ static void device_run(void *prv)
> static irqreturn_t rga_isr(int irq, void *prv)
> {
> struct rockchip_rga *rga = prv;
> - int intr;
>
> - intr = rga_read(rga, RGA_INT) & 0xf;
> -
> - rga_mod(rga, RGA_INT, intr << 4, 0xf << 4);
> -
> - if (intr & 0x04) {
> + if (rga->hw->handle_irq(rga)) {
> struct vb2_v4l2_buffer *src, *dst;
> struct rga_ctx *ctx = rga->curr;
>
> @@ -184,158 +178,17 @@ static int rga_setup_ctrls(struct rga_ctx *ctx)
> return 0;
> }
>
> -static struct rga_fmt formats[] = {
> - {
> - .fourcc = V4L2_PIX_FMT_ARGB32,
> - .color_swap = RGA_COLOR_ALPHA_SWAP,
> - .hw_format = RGA_COLOR_FMT_ABGR8888,
> - .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_ABGR32,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_ABGR8888,
> - .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_XBGR32,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_XBGR8888,
> - .depth = 32,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_RGB24,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_RGB888,
> - .depth = 24,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_BGR24,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_RGB888,
> - .depth = 24,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_ARGB444,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_ABGR4444,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_ARGB555,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_ABGR1555,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_RGB565,
> - .color_swap = RGA_COLOR_RB_SWAP,
> - .hw_format = RGA_COLOR_FMT_BGR565,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_NV21,
> - .color_swap = RGA_COLOR_UV_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV420SP,
> - .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_NV61,
> - .color_swap = RGA_COLOR_UV_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV422SP,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_NV12,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV420SP,
> - .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_NV12M,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV420SP,
> - .depth = 12,
> - .y_div = 2,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_NV16,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV422SP,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 1,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_YUV420,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV420P,
> - .depth = 12,
> - .y_div = 2,
> - .x_div = 2,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_YUV422P,
> - .color_swap = RGA_COLOR_NONE_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV422P,
> - .depth = 16,
> - .y_div = 1,
> - .x_div = 2,
> - },
> - {
> - .fourcc = V4L2_PIX_FMT_YVU420,
> - .color_swap = RGA_COLOR_UV_SWAP,
> - .hw_format = RGA_COLOR_FMT_YUV420P,
> - .depth = 12,
> - .y_div = 2,
> - .x_div = 2,
> - },
> -};
> -
> -#define NUM_FORMATS ARRAY_SIZE(formats)
> -
> -static struct rga_fmt *rga_fmt_find(u32 pixelformat)
> +static struct rga_fmt *rga_fmt_find(struct rockchip_rga *rga, u32 pixelformat)
> {
> unsigned int i;
>
> - for (i = 0; i < NUM_FORMATS; i++) {
> - if (formats[i].fourcc == pixelformat)
> - return &formats[i];
> + for (i = 0; i < rga->hw->num_formats; i++) {
> + if (rga->hw->formats[i].fourcc == pixelformat)
> + return &rga->hw->formats[i];
> }
> return NULL;
> }
>
> -static struct rga_frame def_frame = {
> - .crop.left = 0,
> - .crop.top = 0,
> - .crop.width = DEFAULT_WIDTH,
> - .crop.height = DEFAULT_HEIGHT,
> - .fmt = &formats[0],
> -};
> -
> struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type)
> {
> if (V4L2_TYPE_IS_OUTPUT(type))
> @@ -350,6 +203,18 @@ static int rga_open(struct file *file)
> struct rockchip_rga *rga = video_drvdata(file);
> struct rga_ctx *ctx = NULL;
> int ret = 0;
> + u32 def_width = clamp(DEFAULT_WIDTH, rga->hw->min_width, rga->hw->max_width);
> + u32 def_height = clamp(DEFAULT_HEIGHT, rga->hw->min_height, rga->hw->max_height);
> + struct rga_frame def_frame = {
> + .crop.left = 0,
> + .crop.top = 0,
> + .crop.width = def_width,
> + .crop.height = def_height,
> + .fmt = &rga->hw->formats[0],
> + };
> +
> + def_frame.stride = (def_width * def_frame.fmt->depth) >> 3;
> + def_frame.size = def_frame.stride * def_height;
>
> ctx = kzalloc_obj(*ctx);
> if (!ctx)
> @@ -360,9 +225,9 @@ static int rga_open(struct file *file)
> ctx->out = def_frame;
>
> v4l2_fill_pixfmt_mp(&ctx->in.pix,
> - ctx->in.fmt->fourcc, DEFAULT_WIDTH, DEFAULT_HEIGHT);
> + ctx->in.fmt->fourcc, def_width, def_height);
> v4l2_fill_pixfmt_mp(&ctx->out.pix,
> - ctx->out.fmt->fourcc, DEFAULT_WIDTH, DEFAULT_HEIGHT);
> + ctx->out.fmt->fourcc, def_width, def_height);
>
> if (mutex_lock_interruptible(&rga->mutex)) {
> kfree(ctx);
> @@ -429,12 +294,13 @@ vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
>
> static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
> {
> + struct rockchip_rga *rga = video_drvdata(file);
> struct rga_fmt *fmt;
>
> - if (f->index >= NUM_FORMATS)
> + if (f->index >= rga->hw->num_formats)
> return -EINVAL;
>
> - fmt = &formats[f->index];
> + fmt = &rga->hw->formats[f->index];
> f->pixelformat = fmt->fourcc;
>
> if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
> @@ -469,6 +335,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
> {
> struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
> struct rga_ctx *ctx = file_to_rga_ctx(file);
> + const struct rga_hw *hw = ctx->rga->hw;
> struct rga_fmt *fmt;
>
> if (V4L2_TYPE_IS_CAPTURE(f->type)) {
> @@ -487,14 +354,14 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
> pix_fmt->xfer_func = frm->pix.xfer_func;
> }
>
> - fmt = rga_fmt_find(pix_fmt->pixelformat);
> + fmt = rga_fmt_find(ctx->rga, pix_fmt->pixelformat);
> if (!fmt)
> - fmt = &formats[0];
> + fmt = &hw->formats[0];
>
> pix_fmt->width = clamp(pix_fmt->width,
> - (u32)MIN_WIDTH, (u32)MAX_WIDTH);
> + hw->min_width, hw->max_width);
> pix_fmt->height = clamp(pix_fmt->height,
> - (u32)MIN_HEIGHT, (u32)MAX_HEIGHT);
> + hw->min_height, hw->max_height);
>
> v4l2_fill_pixfmt_mp(pix_fmt, fmt->fourcc, pix_fmt->width, pix_fmt->height);
> pix_fmt->field = V4L2_FIELD_NONE;
> @@ -529,7 +396,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
> frm->size = 0;
> for (i = 0; i < pix_fmt->num_planes; i++)
> frm->size += pix_fmt->plane_fmt[i].sizeimage;
> - frm->fmt = rga_fmt_find(pix_fmt->pixelformat);
> + frm->fmt = rga_fmt_find(rga, pix_fmt->pixelformat);
> frm->stride = pix_fmt->plane_fmt[0].bytesperline;
>
> /*
> @@ -660,7 +527,7 @@ static int vidioc_s_selection(struct file *file, void *priv,
>
> if (s->r.left + s->r.width > f->pix.width ||
> s->r.top + s->r.height > f->pix.height ||
> - s->r.width < MIN_WIDTH || s->r.height < MIN_HEIGHT) {
> + s->r.width < rga->hw->min_width || s->r.height < rga->hw->min_height) {
> v4l2_dbg(debug, 1, &rga->v4l2_dev, "unsupported crop value.\n");
> return -EINVAL;
> }
> @@ -770,6 +637,10 @@ static int rga_probe(struct platform_device *pdev)
> if (!rga)
> return -ENOMEM;
>
> + rga->hw = of_device_get_match_data(&pdev->dev);
> + if (!rga->hw)
> + return dev_err_probe(&pdev->dev, -ENODEV, "failed to get match data\n");
> +
> rga->dev = &pdev->dev;
> spin_lock_init(&rga->ctrl_lock);
> mutex_init(&rga->mutex);
> @@ -833,8 +704,7 @@ static int rga_probe(struct platform_device *pdev)
> if (ret < 0)
> goto rel_m2m;
>
> - rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
> - rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
> + rga->hw->get_version(rga);
>
> v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n",
> rga->version.major, rga->version.minor);
> @@ -842,7 +712,7 @@ static int rga_probe(struct platform_device *pdev)
> pm_runtime_put(rga->dev);
>
> /* Create CMD buffer */
> - rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
> + rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, rga->hw->cmdbuf_size,
> &rga->cmdbuf_phy, GFP_KERNEL,
> DMA_ATTR_WRITE_COMBINE);
> if (!rga->cmdbuf_virt) {
> @@ -850,9 +720,6 @@ static int rga_probe(struct platform_device *pdev)
> goto rel_m2m;
> }
>
> - def_frame.stride = (DEFAULT_WIDTH * def_frame.fmt->depth) >> 3;
> - def_frame.size = def_frame.stride * DEFAULT_HEIGHT;
> -
> ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
> if (ret) {
> v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
> @@ -865,7 +732,7 @@ static int rga_probe(struct platform_device *pdev)
> return 0;
>
> free_dma:
> - dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
> + dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, rga->cmdbuf_virt,
> rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
> rel_m2m:
> v4l2_m2m_release(rga->m2m_dev);
> @@ -883,7 +750,7 @@ static void rga_remove(struct platform_device *pdev)
> {
> struct rockchip_rga *rga = platform_get_drvdata(pdev);
>
> - dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
> + dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, rga->cmdbuf_virt,
> rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
>
> v4l2_info(&rga->v4l2_dev, "Removing\n");
> @@ -919,9 +786,11 @@ static const struct dev_pm_ops rga_pm = {
> static const struct of_device_id rockchip_rga_match[] = {
> {
> .compatible = "rockchip,rk3288-rga",
> + .data = &rga2_hw,
> },
> {
> .compatible = "rockchip,rk3399-rga",
> + .data = &rga2_hw,
> },
> {},
> };
> diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
> index c4a3905a48f0d..640e510285341 100644
> --- a/drivers/media/platform/rockchip/rga/rga.h
> +++ b/drivers/media/platform/rockchip/rga/rga.h
> @@ -14,6 +14,9 @@
>
> #define RGA_NAME "rockchip-rga"
>
> +#define DEFAULT_WIDTH 100
> +#define DEFAULT_HEIGHT 100
> +
> struct rga_fmt {
> u32 fourcc;
> int depth;
> @@ -68,6 +71,8 @@ static inline struct rga_ctx *file_to_rga_ctx(struct file *filp)
> return container_of(file_to_v4l2_fh(filp), struct rga_ctx, fh);
> }
>
> +struct rga_hw;
> +
> struct rockchip_rga {
> struct v4l2_device v4l2_dev;
> struct v4l2_m2m_dev *m2m_dev;
> @@ -88,6 +93,8 @@ struct rockchip_rga {
> struct rga_ctx *curr;
> dma_addr_t cmdbuf_phy;
> void *cmdbuf_virt;
> +
> + const struct rga_hw *hw;
> };
>
> struct rga_addr_offset {
> @@ -138,7 +145,19 @@ static inline void rga_mod(struct rockchip_rga *rga, u32 reg, u32 val, u32 mask)
> rga_write(rga, reg, temp);
> };
>
> -void rga_hw_start(struct rockchip_rga *rga,
> - struct rga_vb_buffer *src, struct rga_vb_buffer *dst);
> +struct rga_hw {
> + struct rga_fmt *formats;
> + u32 num_formats;
> + size_t cmdbuf_size;
> + u32 min_width, min_height;
> + u32 max_width, max_height;
> +
> + void (*start)(struct rockchip_rga *rga,
> + struct rga_vb_buffer *src, struct rga_vb_buffer *dst);
> + bool (*handle_irq)(struct rockchip_rga *rga);
> + void (*get_version)(struct rockchip_rga *rga);
> +};
> +
> +extern const struct rga_hw rga2_hw;
>
> #endif
>
> --
> 2.54.0
>
>
^ permalink raw reply
* RE: [PATCH v2 08/10] arm64: dts: renesas: r9a07g0{43,44,54}: remove TCIU8 interrupt from MTU3
From: Cosmin-Gabriel Tanislav @ 2026-05-21 13:53 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, Biju Das, Daniel Lezcano,
Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <20260410163530.383818-9-cosmin-gabriel.tanislav.xa@renesas.com>
Hi Geert, is it too late in the cycle for this to be picked up for 7.2?
> From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> Sent: Friday, April 10, 2026 7:35 PM
>
> The TCIU8 interrupt used to be documented in earlier revisions of the
> user manuals, but has since been removed. The corresponding entry is now
> marked as reserved in the interrupt mapping tables of all supported
> SoCs.
>
> * Page 486, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/G2UL
> Rev.1.40 User Manual
> * Page 363, Table 8.2 Interrupt Mapping (6/13) in the Renesas RZ/Five
> Rev.1.30 User Manual
> * Page 528, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/G2L
> and RZ/G2LC Rev.1.50 User Manual
> * Page 540, Table 8.2 Interrupt mapping (7/13) in the Renesas RZ/V2L
> Rev.1.50 User Manual
>
> Remove the TCIU8 interrupt. This does not cause any breakage as the
> driver does not make use of the interrupts.
>
> Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> ---
>
> V2:
> * reword to mention that TCIU8 used to exist
>
> arch/arm64/boot/dts/renesas/r9a07g043.dtsi | 5 ++---
> arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 5 ++---
> arch/arm64/boot/dts/renesas/r9a07g054.dtsi | 5 ++---
> 3 files changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
> index 593c66b27ad12..7bc37e1015a47 100644
> --- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
> @@ -120,8 +120,7 @@ mtu3: timer@10001200 {
> <SOC_PERIPHERAL_IRQ(209) IRQ_TYPE_EDGE_RISING>,
> <SOC_PERIPHERAL_IRQ(210) IRQ_TYPE_EDGE_RISING>,
> <SOC_PERIPHERAL_IRQ(211) IRQ_TYPE_EDGE_RISING>,
> - <SOC_PERIPHERAL_IRQ(212) IRQ_TYPE_EDGE_RISING>,
> - <SOC_PERIPHERAL_IRQ(213) IRQ_TYPE_EDGE_RISING>;
> + <SOC_PERIPHERAL_IRQ(212) IRQ_TYPE_EDGE_RISING>;
> interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0",
> "tciv0", "tgie0", "tgif0",
> "tgia1", "tgib1", "tciv1", "tciu1",
> @@ -136,7 +135,7 @@ mtu3: timer@10001200 {
> "tgia7", "tgib7", "tgic7", "tgid7",
> "tciv7",
> "tgia8", "tgib8", "tgic8", "tgid8",
> - "tciv8", "tciu8";
> + "tciv8";
> clocks = <&cpg CPG_MOD R9A07G043_MTU_X_MCK_MTU3>;
> power-domains = <&cpg>;
> resets = <&cpg R9A07G043_MTU_X_PRESET_MTU3>;
> diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> index 29273da819951..799a974c4dba1 100644
> --- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> @@ -220,8 +220,7 @@ mtu3: timer@10001200 {
> <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 211 IRQ_TYPE_EDGE_RISING>,
> - <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>,
> - <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>;
> + <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>;
> interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0",
> "tciv0", "tgie0", "tgif0",
> "tgia1", "tgib1", "tciv1", "tciu1",
> @@ -236,7 +235,7 @@ mtu3: timer@10001200 {
> "tgia7", "tgib7", "tgic7", "tgid7",
> "tciv7",
> "tgia8", "tgib8", "tgic8", "tgid8",
> - "tciv8", "tciu8";
> + "tciv8";
> clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>;
> power-domains = <&cpg>;
> resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>;
> diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
> index 0dee48c4f1e44..0dc4c3c8c06b2 100644
> --- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
> @@ -220,8 +220,7 @@ mtu3: timer@10001200 {
> <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 211 IRQ_TYPE_EDGE_RISING>,
> - <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>,
> - <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>;
> + <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>;
> interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0",
> "tciv0", "tgie0", "tgif0",
> "tgia1", "tgib1", "tciv1", "tciu1",
> @@ -236,7 +235,7 @@ mtu3: timer@10001200 {
> "tgia7", "tgib7", "tgic7", "tgid7",
> "tciv7",
> "tgia8", "tgib8", "tgic8", "tgid8",
> - "tciv8", "tciu8";
> + "tciv8";
> clocks = <&cpg CPG_MOD R9A07G054_MTU_X_MCK_MTU3>;
> power-domains = <&cpg>;
> resets = <&cpg R9A07G054_MTU_X_PRESET_MTU3>;
> --
> 2.53.0
^ permalink raw reply
* Re: [PATCH v5 03/13] iio: core: add hierarchical channel relationships
From: Rodrigo Alencar @ 2026-05-21 13:48 UTC (permalink / raw)
To: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
linux-hardening
Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
Kees Cook, Gustavo A. R. Silva
In-Reply-To: <20260517-ad9910-iio-driver-v5-3-31599c88314a@analog.com>
On 26/05/18 03:26PM, Rodrigo Alencar wrote:
> On 26/05/17 06:56PM, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > - [Medium] Exposing the hierarchical relationship via channel labels creates an ambiguous UAPI for userspace.
> > --
> >
> > commit 64c6f961f1d7645c58f732e4bd4c11200b999e93
> > Author: Rodrigo Alencar <rodrigo.alencar@analog.com>
> >
> > iio: core: add hierarchical channel relationships
> >
> > This commit introduces a parent-child relationship between IIO channels.
> > It adds a parent pointer to the iio_chan_spec struct and exposes this
> > relationship to userspace through a new "parent" sysfs attribute that
> > returns the parent channel's label.
> >
> > > diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> > > index 5c8404efd0a56..348ac7a597385 100644
> > > --- a/drivers/iio/industrialio-core.c
> > > +++ b/drivers/iio/industrialio-core.c
> >
> > [ ... ]
> >
> > > @@ -1263,6 +1271,31 @@ static int iio_device_add_channel_label(struct iio_dev *indio_dev,
> > > return 1;
> > > }
> > >
> > > +static int iio_device_add_channel_parent(struct iio_dev *indio_dev,
> > > + struct iio_chan_spec const *chan)
> > > +{
> > > + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
> > > + int ret;
> > > +
> > > + if (!chan->parent || (!indio_dev->info->read_label &&
> > > + !chan->parent->extend_name))
> > > + return 0;
> >
> > Is relying on channel labels robust enough for programmatic parent resolution?
> >
> > IIO channel labels are optional, human-readable descriptors and are not
> > guaranteed by the core to be unique. If multiple channels within a device
> > share the same label, how can userspace definitively resolve which specific
> > channel is the parent?
> >
> > Also, if a driver establishes a hierarchy where chan->parent is set, but the
> > parent channel lacks a label, this attribute is silently omitted, hiding the
> > relationship entirely.
> >
> > Would it be more reliable to expose a definitive, unique identifier (such as
> > the parent channel's sysfs prefix or index) rather than relying on an optional
> > descriptive string?
>
> A bit impressive that sashiko can comment on that architecture level.
>
> Those are all good points. I suppose I went for this because otherwise it would
> require refactoring core code to get the needed parts from __iio_device_attr_init()
> that gets you the channel name without the attribute part.
>
> Maybe we should have a function that outputs a channel name into a buffer based on
> __iio_device_attr_init() behavior, and that could be reused.
This is the function with behavior extracted from __iio_device_attr_init():
static int __iio_chan_prefix_emit(const struct iio_chan_spec *chan,
enum iio_shared_by shared_by,
char *buf, size_t len)
{
const char *dir = iio_direction[chan->output];
const char *type = iio_chan_type_name_spec[chan->type];
int n = 0;
switch (shared_by) {
case IIO_SHARED_BY_ALL:
break;
case IIO_SHARED_BY_DIR:
n = scnprintf(buf, len, "%s", dir);
break;
case IIO_SHARED_BY_TYPE:
n = scnprintf(buf, len, "%s_%s", dir, type);
if (chan->differential)
n += scnprintf(buf + n, len - n, "-%s", type);
break;
case IIO_SEPARATE:
if (chan->indexed) {
n = scnprintf(buf, len, "%s_%s%d", dir, type,
chan->channel);
if (chan->differential)
n += scnprintf(buf + n, len - n, "-%s%d", type,
chan->channel2);
} else {
if (chan->differential) {
WARN(1, "Differential channels must be indexed\n");
return -EINVAL;
}
n = scnprintf(buf, len, "%s_%s", dir, type);
}
if (chan->modified) {
if (chan->differential) {
WARN(1, "Differential channels can not have modifier\n");
return -EINVAL;
}
n += scnprintf(buf + n, len - n, "_%s",
iio_modifier_names[chan->channel2]);
}
if (chan->extend_name)
n += scnprintf(buf + n, len - n, "_%s", chan->extend_name);
break;
}
return n;
}
I think it is clear and reusable.
> > > +
> > > + ret = __iio_add_chan_devattr("parent",
> > > + chan,
> > > + &iio_read_channel_parent,
> > > + NULL,
> > > + 0,
> > > + IIO_SEPARATE,
> > > + &indio_dev->dev,
> > > + NULL,
> > > + &iio_dev_opaque->channel_attr_list);
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + return 1;
> > > +}
> >
> > --
> > Sashiko AI review · https://sashiko.dev/#/patchset/20260517-ad9910-iio-driver-v5-0-31599c88314a@analog.com?part=3
--
Kind regards,
Rodrigo Alencar
^ permalink raw reply
* Re: [PATCH v7 10/28] media: rockchip: rga: announce and sync colorimetry
From: Michael Tretter @ 2026-05-21 13:44 UTC (permalink / raw)
To: Sven Püschel
Cc: Jacob Chen, Ezequiel Garcia, Mauro Carvalho Chehab,
Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans Verkuil, linux-media, linux-rockchip, linux-arm-kernel,
linux-kernel, devicetree, kernel, nicolas, sebastian.reichel,
p.zabel, Nicolas Dufresne
In-Reply-To: <20260521-spu-rga3-v7-10-3f33e8c7145f@pengutronix.de>
"announce colorimetry" in the subject is a bit strange. Maybe rephrase
the subject to
media: rockchip: rga: announce CSC and sync colorimetry
On Thu, 21 May 2026 00:44:15 +0200, Sven Püschel wrote:
> Announce the capability to adjust the quantization and ycbcr_enc on the
> capture side and check if the SET_CSC flag is set when the colorimetry
> is changed. Furthermore copy the colorimetry from the output to the
> capture side to fix the currently failing v4l2-compliance tests, which
> expect exactly this behavior.
>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
> ---
> drivers/media/platform/rockchip/rga/rga.c | 37 +++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
> index ca8d8a53dc251..8c34f73d69764 100644
> --- a/drivers/media/platform/rockchip/rga/rga.c
> +++ b/drivers/media/platform/rockchip/rga/rga.c
> @@ -437,6 +437,15 @@ static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f
> fmt = &formats[f->index];
> f->pixelformat = fmt->fourcc;
>
> + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
> + f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
Is there a reason for not using V4L2_TYPE_IS_CAPTURE(f->type)? I'd also
invert the condition, set the flags in the branch and have a single exit
point of this function.
> + return 0;
> +
> + /* allow changing the quantization and xfer func for YUV formats */
> + if (v4l2_is_format_yuv(v4l2_format_info(f->pixelformat)))
> + f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION |
> + V4L2_FMT_FLAG_CSC_YCBCR_ENC;
> +
> return 0;
> }
>
> @@ -459,8 +468,25 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
> static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
> {
> struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
> + struct rga_ctx *ctx = file_to_rga_ctx(file);
> struct rga_fmt *fmt;
>
> + if (V4L2_TYPE_IS_CAPTURE(f->type)) {
> + const struct rga_frame *frm;
> +
> + frm = rga_get_frame(ctx, f->type);
> + if (IS_ERR(frm))
> + return PTR_ERR(frm);
> +
> + if (!(pix_fmt->flags & V4L2_PIX_FMT_FLAG_SET_CSC)) {
> + pix_fmt->quantization = frm->pix.quantization;
> + pix_fmt->ycbcr_enc = frm->pix.ycbcr_enc;
> + }
Are there any limits on the colorspace conversion that the RGA can do?
If I understand correctly, user space may set an arbitrary
v4l2_ycbcr_encoding (for example V4L2_YCBCR_ENC_BT2020) and the driver
will happily accept it.
> + /* disallow values not announced in vidioc_enum_fmt */
"disallow values" sounds strange. Maybe:
/* The RGA cannot convert colorspace and xfer_func */
> + pix_fmt->colorspace = frm->pix.colorspace;
> + pix_fmt->xfer_func = frm->pix.xfer_func;
> + }
> +
> fmt = rga_fmt_find(pix_fmt->pixelformat);
> if (!fmt)
> fmt = &formats[0];
> @@ -506,6 +532,17 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
> frm->fmt = rga_fmt_find(pix_fmt->pixelformat);
> frm->stride = pix_fmt->plane_fmt[0].bytesperline;
>
> + /*
> + * Copy colorimetry from output to capture as required by the
> + * v4l2-compliance tests
> + */
> + if (V4L2_TYPE_IS_OUTPUT(f->type)) {
> + ctx->out.pix.colorspace = pix_fmt->colorspace;
> + ctx->out.pix.ycbcr_enc = pix_fmt->ycbcr_enc;
> + ctx->out.pix.quantization = pix_fmt->quantization;
> + ctx->out.pix.xfer_func = pix_fmt->xfer_func;
I was very confused, because ctx->out is actually the format for
CAPTURE. The comment kind of helps to mark this trap. Not sure, if there
is anything that can be done about this.
Michael
> + }
> +
> /* Reset crop settings */
> frm->crop.left = 0;
> frm->crop.top = 0;
>
> --
> 2.54.0
>
>
^ permalink raw reply
* Re: [PATCH 05/18] arm64: dts: qcom: sm8150: Fix PCIe wake GPIO polarity
From: sashiko-bot @ 2026-05-21 13:42 UTC (permalink / raw)
To: Krishna Chaitanya Chundru; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260521-wake-v1-5-d822567be258@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The dt-binding examples for Qualcomm PCIe controllers are not updated to reflect the `wake-gpios` polarity change.
--
commit ceea67812f2db3dd214265d1322e7b8e9c36e293
Author: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
arm64: dts: qcom: sm8150: Fix PCIe wake GPIO polarity
The PCIe WAKE# signal is active-low as defined in the PCIe Base
Specification. Fix the wake-gpios polarity by using GPIO_ACTIVE_LOW
instead of GPIO_ACTIVE_HIGH.
> diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
> index 0e101096209ab..8da494de4308a 100644
> --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
> @@ -1905,7 +1905,7 @@ pcie0: pcie@1c00000 {
> phy-names = "pciephy";
>
> perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
> - wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
> + wake-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
[Severity: Low]
Should the dt-binding example for this controller be updated to reflect the
polarity change?
The example in Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml
still instructs developers to use GPIO_ACTIVE_HIGH for wake-gpios. Leaving
the documentation with the old polarity risks propagating the incorrect
configuration to new board designs.
>
> pinctrl-names = "default";
> pinctrl-0 = <&pcie0_default_state>;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-wake-v1-0-d822567be258@oss.qualcomm.com?part=5
^ permalink raw reply
* Re: [PATCH v22 08/13] mfd: core: Add firmware-node support to MFD cells
From: Bartosz Golaszewski @ 2026-05-21 13:36 UTC (permalink / raw)
To: Lee Jones
Cc: Shivendra Pratap, Sebastian Reichel, Mark Rutland,
Lorenzo Pieralisi, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Arnd Bergmann,
Souvik Chakravarty, Andy Yan, Matthias Brugger, John Stultz,
Moritz Fischer, Sudeep Holla, linux-pm, linux-kernel,
linux-arm-msm, linux-arm-kernel, devicetree, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, Srinivas Kandagatla,
Bartosz Golaszewski
In-Reply-To: <20260521132419.GA3591266@google.com>
On Thu, May 21, 2026 at 3:24 PM Lee Jones <lee@kernel.org> wrote:
>
> >
> > I suggested it because of its flexibility. The alternative I had in
> > mind is something like a new field in mfd_cell:
> >
> > const char *cell_node_name;
> >
> > Which - if set - would tell MFD to look up an fwnode that's a child of
> > the parent device's node by name - as it may not have a compatible.
>
> Remind me why the chlid device can't look-up its own fwnode?
>
Oh sure it can, but should it? I'm not sure it's logically sound to
have the child device reach into the parent, look up the fwnode and
then assign it to itself after it's already attached to the driver.
This should be done at the subsystem level before the device is
registered.
Bart
^ permalink raw reply
* Re: [PATCH v12 17/22] media: i2c: maxim-serdes: add MAX96724 driver
From: sashiko-bot @ 2026-05-21 13:36 UTC (permalink / raw)
To: Dumitru Ceclan via B4 Relay; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260521-gmsl2-3_serdes-v12-17-b26d92931196@analog.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Incorrect macro definition for MAX96724_BACKTOP32_BPP12(p) causes register corruption for pipes 4-7.
- [High] Disabling an unused PHY inadvertently disables half of the active PHY when using 4-lane mode.
- [Medium] The VIDEO_MAX96724 config selects VIDEO_MAXIM_SERDES without inheriting its dependency on VIDEO_DEV.
- [Medium] Missing GPIO power-off in probe error paths leaves the hardware powered on indefinitely.
- [Medium] The 64-bit link_frequency is truncated to a 32-bit unsigned int before being passed to a 64-bit division function.
- [Low] Mismatch between comment and actual bitfield operation for PHY 4-lane standby masks.
--
commit e87ac21571cc062a409316fe229ce7535941f437
Author: Cosmin Tanislav <demonsingur@gmail.com>
media: i2c: maxim-serdes: add MAX96724 driver
Add a new MAX96724 driver that also supports MAX96712, MAX96724F
and MAX96724R. Integrate it with the common deserializer framework,
while keeping compatibility with existing usecases, avoiding code
duplication, and also enabling more features across all chips.
> diff --git a/drivers/media/i2c/maxim-serdes/Kconfig b/drivers/media/i2c/maxim-serdes/Kconfig
> index ddbb5791e9349..f060307e3de38 100644
> --- a/drivers/media/i2c/maxim-serdes/Kconfig
> +++ b/drivers/media/i2c/maxim-serdes/Kconfig
> @@ -33,3 +33,15 @@ config VIDEO_MAX96717
>
> To compile this driver as a module, choose M here: the module
> will be called max96717.
> +
> +config VIDEO_MAX96724
> + tristate "Maxim MAX96724 Quad Deserializer support"
> + depends on I2C
> + select VIDEO_MAXIM_SERDES
[Severity: Medium]
Does selecting VIDEO_MAXIM_SERDES here without inheriting its dependency on
VIDEO_DEV cause Kconfig unmet direct dependency warnings? Compiling the
kernel with I2C=y and VIDEO_DEV=n might trigger warnings.
> diff --git a/drivers/media/i2c/maxim-serdes/max96724.c b/drivers/media/i2c/maxim-serdes/max96724.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/media/i2c/maxim-serdes/max96724.c
[ ... ]
> +#define MAX96724_BACKTOP31(p) (0x41e + (p) / 4 * 0x20)
> +#define MAX96724_BACKTOP31_BPP10DBL2 BIT(6)
> +#define MAX96724_BACKTOP31_BPP10DBL2_MODE BIT(7)
> +
> +#define MAX96724_BACKTOP32(p) (0x41f + (p) / 4 * 0x20)
> +#define MAX96724_BACKTOP32_BPP12(p) BIT(p)
[Severity: High]
Can this corrupt register 0x43f when configuring 12-bit double mode for
pipes 4-7? BIT(p) evaluates to BIT(4) through BIT(7) for those pipes, which
might overwrite the 10-bit mode configuration (e.g., BPP10DBL0) instead of
setting the correct BPP12 bit. Should this be BIT((p) % 4) instead?
[ ... ]
> +static int max96724_init_phy(struct max_des *des, struct max_des_phy *phy)
> +{
> + struct max96724_priv *priv = des_to_priv(des);
> + bool is_cphy = phy->bus_type == V4L2_MBUS_CSI2_CPHY;
> + unsigned int num_data_lanes = phy->mipi.num_data_lanes;
> + unsigned int dpll_freq = is_cphy ? phy->link_frequency
> + : phy->link_frequency * 2;
[Severity: Medium]
Will this truncate the 64-bit link_frequency if link_frequency * 2 exceeds
UINT_MAX (e.g., frequencies > 2.14 GHz)? Since dpll_freq is later passed to
div_u64() which expects a 64-bit dividend, should this be declared as a u64
to prevent silent overflow?
[ ... ]
> +static int max96724_set_phy_enable(struct max_des *des, struct max_des_phy *phy,
> + bool enable)
> +{
> + struct max96724_priv *priv = des_to_priv(des);
> + unsigned int index = max96724_phy_id(des, phy);
> + unsigned int num_hw_data_lanes;
> + unsigned int mask;
> +
> + num_hw_data_lanes = max_des_phy_hw_data_lanes(des, phy);
> +
> + if (num_hw_data_lanes == 4)
> + /* PHY 1 -> bits [1:0] */
> + /* PHY 2 -> bits [3:2] */
[Severity: Low]
This isn't a bug, but the comment mentions bits [1:0] and [3:2], while the
MAX96724_MIPI_PHY2_PHY_STDB_N_4 macro evaluates to GENMASK(5, 4) and
GENMASK(7, 6). Could this comment be updated for accuracy?
> + mask = MAX96724_MIPI_PHY2_PHY_STDB_N_4(index);
> + else
> + mask = MAX96724_MIPI_PHY2_PHY_STDB_N_2(index);
> +
> + return regmap_assign_bits(priv->regmap, MAX96724_MIPI_PHY2, mask, enable);
> +}
[Severity: High]
Does this inadvertently break PHY 0 when it is running in 4-lane mode?
If PHY 0 is in 4-lane mode, it combines with PHY 1, leaving
phy[1].enabled = false. The common framework calls this function for the
disabled PHY 1, which max96724_phy_id() maps to index 0.
Because num_hw_data_lanes for phy[1] is 0, the else branch sets mask to
MAX96724_MIPI_PHY2_PHY_STDB_N_2(0), which is BIT(4), and clears it. However,
PHY 0's 4-lane mode needs both BIT(4) and BIT(5) set.
Should this function return early when handling disabled PHYs during 4-lane
mode?
[ ... ]
> +static int max96724_probe(struct i2c_client *client)
> +{
[ ... ]
> + if (priv->gpiod_enable) {
> + /* PWDN must be held for 1us for reset */
> + udelay(1);
> +
> + gpiod_set_value_cansleep(priv->gpiod_enable, 1);
> +
> + /* Maximum power-up time (tLOCK) 4ms */
> + usleep_range(4000, 5000);
> + }
> +
> + priv->cc_port_cfg = MAX96724_REG3_CC_PORT_CFG_PORT0;
> +
> + ret = device_property_read_u32(dev, "maxim,control-channel-port",
> + &cc_port);
> + if (!ret) {
> + switch (cc_port) {
> + case 0:
> + priv->cc_port_cfg = MAX96724_REG3_CC_PORT_CFG_PORT0;
> + break;
> + case 1:
> + priv->cc_port_cfg = MAX96724_REG3_CC_PORT_CFG_PORT1;
> + break;
> + default:
> + dev_err(dev, "Invalid control-channel port %u\n", cc_port);
> + return -EINVAL;
> + }
> + } else if (ret != -ENODATA && ret != -ENOENT && ret != -EINVAL) {
> + return ret;
> + }
> +
> + *info = max96724_des_info;
> + info->versions = priv->info->versions;
> + info->modes = priv->info->modes;
> + info->num_pipes = priv->info->num_pipes;
> + priv->des.info = info;
> +
> + *ops = max96724_des_ops;
> + ops->set_pipe_tunnel_enable = priv->info->set_pipe_tunnel_enable;
> + ops->set_pipe_phy = priv->info->set_pipe_phy;
> + ops->set_pipe_tunnel_phy = priv->info->set_pipe_tunnel_phy;
> + priv->des.ops = ops;
> +
> + ret = max96724_reset(priv);
> + if (ret)
> + return ret;
> +
> + return max_des_probe(client, &priv->des);
> +}
[Severity: Medium]
If max96724_reset() or max_des_probe() fails and returns an error, is the
hardware left powered on indefinitely? While devres will free the GPIO
descriptor, it doesn't actively pull the pin low. Should the error paths
symmetrically deassert the GPIO to match the cleanup in max96724_remove()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-gmsl2-3_serdes-v12-0-b26d92931196@analog.com?part=17
^ permalink raw reply
* Re: [PATCH v12 18/22] media: i2c: maxim-serdes: add MAX9296A driver
From: sashiko-bot @ 2026-05-21 13:34 UTC (permalink / raw)
To: Dumitru Ceclan via B4 Relay; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260521-gmsl2-3_serdes-v12-18-b26d92931196@analog.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] max96792a_ops is missing the .set_pipe_link callback, preventing proper link routing.
- [High] max9296a_set_pipe_stream_id ignores the new stream_id argument and programs the old state.
- [High] Unvalidated data lane values of 0 can trigger an integer underflow and undefined bitwise shift behavior.
- [Medium] The device remains powered on (resource state leak) if probe fails after toggling the powerdown GPIO.
- [Low] The Kconfig symbol VIDEO_MAX9296A selects VIDEO_MAXIM_SERDES but does not inherit its dependency on VIDEO_DEV.
--
commit dd3188793bbc20f9b99b6950a6fcec1fa7e23c5d
Author: Cosmin Tanislav <demonsingur@gmail.com>
media: i2c: maxim-serdes: add MAX9296A driver
Add a new MAX9296A driver that also supports MAX96714, MAX96714F,
MAX96714R, MAX96716A and MAX96792A.
Integrate it with the common Deserializer framework.
> diff --git a/drivers/media/i2c/maxim-serdes/Kconfig b/drivers/media/i2c/maxim-serdes/Kconfig
> --- a/drivers/media/i2c/maxim-serdes/Kconfig
> +++ b/drivers/media/i2c/maxim-serdes/Kconfig
[ ... ]
> @@ -45,3 +45,16 @@ config VIDEO_MAX96724
>
> To compile this driver as a module, choose M here: the module
> will be called max96724.
> +
> +config VIDEO_MAX9296A
> + tristate "Maxim MAX9296A Dual Deserializer support"
> + depends on I2C
> + select VIDEO_MAXIM_SERDES
[Severity: Low]
Is there a missing dependency here? VIDEO_MAXIM_SERDES depends on VIDEO_DEV,
but this config only depends on I2C. Selecting a symbol without meeting its
dependencies can lead to unmet direct dependency warnings and silent build
failures.
> diff --git a/drivers/media/i2c/maxim-serdes/max9296a.c b/drivers/media/i2c/maxim-serdes/max9296a.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/media/i2c/maxim-serdes/max9296a.c
[ ... ]
> +static int max9296a_init_phy(struct max_des *des, struct max_des_phy *phy)
> +{
[ ... ]
> + for (i = 0; i < num_hw_data_lanes ; i++) {
> + unsigned int map;
> +
> + if (i < num_data_lanes)
> + map = phy->mipi.data_lanes[i] - 1;
> + else
> + map = ffz(used_data_lanes);
> +
> + val |= map << (i * 2);
> + used_data_lanes |= BIT(map);
[Severity: High]
What happens if a malformed Device Tree provides a lane value of 0?
It appears the core framework only validates if the value exceeds
num_data_lanes. If the data lane is 0, the subtraction will underflow to
UINT_MAX, which could trigger undefined behavior when shifting bits in the
BIT(map) macro.
[ ... ]
> +static int max9296a_set_pipe_stream_id(struct max_des *des, struct max_des_pipe *pipe,
> + unsigned int stream_id)
> +{
> + struct max9296a_priv *priv = des_to_priv(des);
> + unsigned int index = max9296a_pipe_id(priv, pipe);
> +
> + return regmap_update_bits(priv->regmap, MAX9296A_RX50(index), MAX9296A_RX50_STR_SEL,
> + FIELD_PREP(MAX9296A_RX50_STR_SEL, pipe->stream_id));
[Severity: High]
Should this use the passed stream_id argument instead of pipe->stream_id?
If the framework hasn't updated the pipe state yet, this might program
the hardware with the old stream ID, potentially breaking video stream
routing.
[ ... ]
> +static int max9296a_probe(struct i2c_client *client)
> +{
[ ... ]
> + if (priv->gpiod_pwdn) {
> + /* PWDN must be held for 1us for reset */
> + udelay(1);
> +
> + gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
> + /* Maximum power-up time (tLOCK) 4ms */
> + usleep_range(4000, 5000);
> + }
> +
> + priv->des.info = priv->info->info;
> + priv->des.ops = priv->info->ops;
> +
> + ret = max9296a_reset(priv);
> + if (ret)
> + return ret;
[Severity: Medium]
If max9296a_reset() or max_des_probe() fails below, does the device remain
powered on?
The powerdown GPIO is driven to 0 here to wake up the device, but it
doesn't appear to be reverted to 1 on the error paths, potentially leaving
the hardware drawing power.
> +
> + return max_des_probe(client, &priv->des);
> +}
[ ... ]
> +static const struct max_des_ops max96792a_ops = {
> + MAX9296A_COMMON_OPS,
> + .set_pipe_stream_id = max96714_set_pipe_stream_id,
> + .set_pipe_enable = max96714_set_pipe_enable,
> + .set_pipe_tunnel_phy = max96716a_set_pipe_tunnel_phy,
> + .set_pipe_tunnel_enable = max96714_set_pipe_tunnel_enable,
> +};
[Severity: High]
Should this struct include the .set_pipe_link callback?
The MAX96792A chip supports 2 pipes and 2 links, and it looks like the closely
related max96716a_ops uses max96716a_set_pipe_link for proper link routing.
Without it, could the core framework skip configuring the pipe-to-link mapping,
leaving the hardware with an incomplete configuration?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521-gmsl2-3_serdes-v12-0-b26d92931196@analog.com?part=18
^ 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