From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
To: Loic Poulain <loic.poulain@oss.qualcomm.com>,
Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Kees Cook <kees@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konradybcio@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org,
devicetree@vger.kernel.org,
Hans de Goede <johannes.goede@oss.qualcomm.com>
Subject: Re: [PATCH v4 6/7] media: qcom: camss: Add CAMSS Offline Processing Engine driver
Date: Mon, 13 Jul 2026 14:05:29 +0100 [thread overview]
Message-ID: <da70ed94-fd76-4105-8071-1ed8d8e41d84@linaro.org> (raw)
In-Reply-To: <20260710-camss-isp-ope-v4-6-51207a0319d8@oss.qualcomm.com>
On 10/07/2026 10:04, Loic Poulain wrote:
> Add an image processing driver for the Qualcomm Offline Processing Engine
> (OPE). OPE is a memory-to-memory ISP block that converts raw Bayer
> frames to YUV, performing white balance, demosaic, chroma enhancement,
> color correction and downscaling.
>
> The hardware architecture consists of Fetch Engines and Write Engines,
> connected through intermediate pipeline modules for pix processing.
>
> The driver exposes three video nodes per pipeline instance:
> - ope_input: Bayer RAW input (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
> - ope_disp_output: YUV output (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
> - ope_params: ISP parameters (V4L2_BUF_TYPE_META_OUTPUT)
>
> Hardware features:
> - Stripe-based processing (up to 336 pixels wide per stripe)
> - White balance (CLC_WB)
> - Demosaic / Bayer-to-RGB (CLC_DEMO)
> - RGB-to-YUV conversion (CLC_CHROMA_ENHAN)
> - Color correction matrix (CLC_CC)
> - MN downscaler for chroma and luma planes
>
> Default configuration values are based on public standards such as BT.601.
>
> Processing Model:
> OPE processes frames in stripes of up to 336 pixels. Therefore, frames must
> be split into stripes for processing. Each stripe is configured after the
> previous one has been acquired (double buffered registers). To minimize
> inter-stripe latency, stripe configurations are generated ahead of time.
>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> Co-developed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/Kconfig | 18 +
> drivers/media/platform/qcom/camss/Makefile | 4 +
> drivers/media/platform/qcom/camss/camss-ope.c | 3245 +++++++++++++++++++++++++
I think this should be in a sub-directory.
> 3 files changed, 3267 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/platform/qcom/camss/Kconfig
> index 4eda48cb1adf049a7fb6cb59b9da3c0870fe57f4..895fc57a679655fcb6f308be1565dc6b77bbbd67 100644
> --- a/drivers/media/platform/qcom/camss/Kconfig
> +++ b/drivers/media/platform/qcom/camss/Kconfig
> @@ -7,3 +7,21 @@ config VIDEO_QCOM_CAMSS
> select VIDEO_V4L2_SUBDEV_API
> select VIDEOBUF2_DMA_SG
> select V4L2_FWNODE
> +
> +config VIDEO_QCOM_CAMSS_OPE
> + tristate "Qualcomm Offline Processing Engine (OPE) driver"
> + depends on VIDEO_QCOM_CAMSS
> + depends on V4L_PLATFORM_DRIVERS
> + depends on VIDEO_DEV
> + depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
> + select V4L2_ISP
> + select VIDEOBUF2_DMA_CONTIG
> + select VIDEOBUF2_VMALLOC
> + help
> + Enable support for the Qualcomm Offline Processing Engine (OPE).
> + OPE is a memory-to-memory ISP block that converts raw Bayer frames
> + to YUV, performing white balance, demosaic, chroma enhancement and
> + downscaling. Found on QCM2290 and related SoCs.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called qcom-camss-ope.
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 5678621efb6780b67a043ec8a2e914cce02d9b98..422eebc0a86301de3f39c743fbc06c437b17ac9a 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -31,3 +31,7 @@ qcom-camss-objs += \
> camss-params.o \
>
> obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom-camss.o
> +
> +qcom-camss-ope-objs := camss-ope.o
> +
> +obj-$(CONFIG_VIDEO_QCOM_CAMSS_OPE) += qcom-camss-ope.o
> diff --git a/drivers/media/platform/qcom/camss/camss-ope.c b/drivers/media/platform/qcom/camss/camss-ope.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..2c0d68cf1a637c998ebe4d3afb1fa6dbdb68f029
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-ope.c
> @@ -0,0 +1,3245 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-ope.c
> + *
> + * Qualcomm MSM Camera Subsystem - Offline Processing Engine
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/*
> + * This driver provides driver implementation for the Qualcomm Offline
> + * Processing Engine (OPE). OPE is a memory-to-memory hardware block
> + * designed for image processing on a source frame. Typically, the input
> + * frame originates from the SoC CSI capture path, though not limited to.
> + *
> + * The hardware architecture consists of Fetch Engines and Write Engines,
> + * connected through intermediate pipeline modules:
> + * [FETCH ENGINES] => [Pipeline Modules] => [WRITE ENGINES]
> + *
> + * Current Configuration:
> + * Fetch Engine: One fetch engine is used for Bayer frame input.
> + * Write Engines: Two display write engines for Y and UV planes output.
> + *
> + * Only a subset of the pipeline modules are enabled:
> + * CLC_WB: White balance for channel gain configuration
> + * CLC_DEMO: Demosaic for Bayer to RGB conversion
> + * CLC_CC: Color Correct, coefficient based RGB correction
> + * CLC_CHROMA_ENHAN: for RGB to YUV conversion
> + * CLC_DOWNSCALE*: Downscaling for UV (YUV444 -> YUV422/YUV420) and YUV planes
> + *
> + * Default configuration values are based on public standards such as BT.601.
> + *
> + * Processing Model:
> + * OPE processes frames in stripes of up to 336 pixels. Therefore, frames must
> + * be split into stripes for processing. Each stripe is configured after the
> + * previous one has been acquired (double buffered registers). To minimize
> + * inter-stripe latency, the stripe configurations are generated ahead of time.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/cleanup.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/interconnect.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_clock.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_opp.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/slab.h>
> +#include <linux/units.h>
> +
> +#include <media/v4l2-device.h>
> +#include <media/media-device.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-fh.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-rect.h>
> +
> +#include "camss-pipeline.h"
> +
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/videobuf2-vmalloc.h>
> +
> +#include <uapi/linux/camss-config.h>
> +
> +#include "camss-params.h"
> +
> +#define OPE_NAME "qcom-camss-ope"
> +
> +/* Format descriptor */
> +struct ope_fmt {
> + u32 fourcc;
> + unsigned int depth;
> + unsigned int align;
> + unsigned int num_planes;
> + u32 mbus_code;
> + unsigned int c_hsub;
> + unsigned int c_vsub;
> +};
> +
> +/* Per-queue format state */
> +struct ope_fmt_state {
> + const struct ope_fmt *fmt;
> + unsigned int width;
> + unsigned int height;
> + struct v4l2_rect crop;
> + unsigned int bytesperline;
> + unsigned int sizeimage;
> + enum v4l2_colorspace colorspace;
> + enum v4l2_xfer_func xfer_func;
> + enum v4l2_ycbcr_encoding ycbcr_enc;
> + enum v4l2_quantization quantization;
> + unsigned int sequence;
> + struct v4l2_fract timeperframe;
> +};
> +
> +/* -------- Register layout -------- */
> +
> +#define OPE_TOP_HW_VERSION 0x000
> +#define OPE_TOP_HW_VERSION_STEP GENMASK(15, 0)
> +#define OPE_TOP_HW_VERSION_REV GENMASK(27, 16)
> +#define OPE_TOP_HW_VERSION_GEN GENMASK(31, 28)
> +#define OPE_TOP_RESET_CMD 0x004
> +#define OPE_TOP_RESET_CMD_HW BIT(0)
> +#define OPE_TOP_RESET_CMD_SW BIT(1)
> +#define OPE_TOP_IRQ_STATUS 0x014
> +#define OPE_TOP_IRQ_MASK 0x018
> +#define OPE_TOP_IRQ_STATUS_RST_DONE BIT(0)
> +#define OPE_TOP_IRQ_STATUS_WE BIT(1)
> +#define OPE_TOP_IRQ_STATUS_FE BIT(2)
> +#define OPE_TOP_IRQ_STATUS_VIOL BIT(3)
> +#define OPE_TOP_IRQ_STATUS_IDLE BIT(4)
> +#define OPE_TOP_IRQ_CLEAR 0x01c
> +#define OPE_TOP_IRQ_CMD 0x024
> +#define OPE_TOP_IRQ_CMD_CLEAR BIT(0)
> +#define OPE_TOP_VIOLATION_STATUS 0x028
> +
> +/* Fetch engine */
> +#define OPE_BUS_RD_INPUT_IF_IRQ_MASK 0x00c
> +#define OPE_BUS_RD_INPUT_IF_IRQ_CLEAR 0x010
> +#define OPE_BUS_RD_INPUT_IF_IRQ_CMD 0x014
> +#define OPE_BUS_RD_INPUT_IF_IRQ_CMD_CLEAR BIT(0)
> +#define OPE_BUS_RD_INPUT_IF_IRQ_STATUS 0x018
> +#define OPE_BUS_RD_INPUT_IF_CMD 0x01c
> +#define OPE_BUS_RD_INPUT_IF_CMD_GO_CMD BIT(0)
> +#define OPE_BUS_RD_CLIENT_0_CORE_CFG 0x050
> +#define OPE_BUS_RD_CLIENT_0_CORE_CFG_EN BIT(0)
> +#define OPE_BUS_RD_CLIENT_0_CCIF_META_DATA 0x054
> +#define OPE_BUS_RD_CLIENT_0_CCIF_MD_PIX_PATTERN GENMASK(7, 2)
> +#define OPE_BUS_RD_CLIENT_0_ADDR_IMAGE 0x058
> +#define OPE_BUS_RD_CLIENT_0_RD_BUFFER_SIZE 0x05c
> +#define OPE_BUS_RD_CLIENT_0_RD_STRIDE 0x060
> +#define OPE_BUS_RD_CLIENT_0_UNPACK_CFG_0 0x064
> +
> +/* Write engines */
> +#define OPE_BUS_WR_INPUT_IF_IRQ_MASK_0 0x018
> +#define OPE_BUS_WR_INPUT_IF_IRQ_MASK_1 0x01c
> +#define OPE_BUS_WR_INPUT_IF_IRQ_CLEAR_0 0x020
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0 0x028
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_RUP_DONE BIT(0)
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_BUF_DONE BIT(8)
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_CONS_VIOL BIT(28)
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_VIOL BIT(30)
> +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_IMG_SZ_VIOL BIT(31)
> +#define OPE_BUS_WR_INPUT_IF_IRQ_CMD 0x030
> +#define OPE_BUS_WR_INPUT_IF_IRQ_CMD_CLEAR BIT(0)
> +#define OPE_BUS_WR_VIOLATION_STATUS 0x064
> +#define OPE_BUS_WR_IMAGE_SIZE_VIOLATION_STATUS 0x070
> +#define OPE_BUS_WR_CLIENT_CFG(c) (0x200 + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_CFG_EN BIT(0)
> +#define OPE_BUS_WR_CLIENT_CFG_AUTORECOVER BIT(4)
> +#define OPE_BUS_WR_CLIENT_ADDR_IMAGE(c) (0x204 + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_0(c) (0x20c + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_1(c) (0x210 + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_2(c) (0x214 + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_PACKER_CFG(c) (0x218 + (c) * 0x100)
> +#define OPE_BUS_WR_CLIENT_MAX 4
> +
> +/* Pipeline modules */
> +#define OPE_PP_CLC_WB_GAIN_MODULE_CFG (0x200 + 0x60)
Can you just map the individual blocks so that we can interrogate
HW_VERSION HW_STATUS and friends ? Those regs usually come first. I can
see useful debugfs and/or dev_dbg() usages of those data.
> +#define OPE_PP_CLC_WB_GAIN_MODULE_CFG_EN BIT(0)
> +#define OPE_PP_CLC_WB_GAIN_WB_CFG(ch) (0x200 + 0x68 + 4 * (ch))
> +#define OPE_PP_CLC_WB_GAIN_WB_CFG_GAIN GENMASK(14, 0)
> +#define OPE_PP_CLC_WB_GAIN_WB_SUB_CFG(ch) (0x200 + 0x74 + 4 * (ch))
> +#define OPE_PP_CLC_WB_GAIN_WB_SUB_CFG_VAL GENMASK(31, 20)
> +#define OPE_PP_CLC_WB_GAIN_WB_ADD_CFG(ch) (0x200 + 0x80 + 4 * (ch))
> +#define OPE_PP_CLC_WB_GAIN_WB_ADD_CFG_VAL GENMASK(31, 20)
> +
> +#define OPE_PP_CLC_CC_BASE 0x400
Is this actually the correct register base for CCM ?
I think you should check again.
Same comment for each of these blocks HW_VERSION should be the first
register.
---
bod
next prev parent reply other threads:[~2026-07-13 13:05 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 9:04 [PATCH v4 0/7] media: qcom: camss: CAMSS Offline Processing Engine support Loic Poulain
2026-07-10 9:04 ` [PATCH v4 1/7] media: qcom: camss: Add camss-pipeline helper Loic Poulain
2026-07-10 9:20 ` sashiko-bot
2026-07-10 9:04 ` [PATCH v4 2/7] media: qcom: camss: Add camss-params helper Loic Poulain
2026-07-10 9:17 ` sashiko-bot
2026-07-10 9:04 ` [PATCH v4 3/7] media: qcom: camss: Add V4L2 meta format for CAMSS ISP parameters Loic Poulain
2026-07-10 9:11 ` sashiko-bot
2026-07-10 9:04 ` [PATCH v4 4/7] dt-bindings: media: qcom: Add CAMSS Offline Processing Engine (OPE) Loic Poulain
2026-07-10 10:20 ` Bryan O'Donoghue
2026-07-10 10:38 ` Loic Poulain
2026-07-10 10:44 ` Bryan O'Donoghue
2026-07-10 9:04 ` [PATCH v4 5/7] media: uapi: Add CAMSS ISP configuration definition Loic Poulain
2026-07-10 9:21 ` sashiko-bot
2026-07-10 21:41 ` Bryan O'Donoghue
2026-07-10 9:04 ` [PATCH v4 6/7] media: qcom: camss: Add CAMSS Offline Processing Engine driver Loic Poulain
2026-07-10 9:24 ` sashiko-bot
2026-07-13 13:05 ` Bryan O'Donoghue [this message]
2026-07-10 9:04 ` [PATCH v4 7/7] arm64: dts: qcom: agatti: Add OPE node Loic Poulain
2026-07-10 9:35 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=da70ed94-fd76-4105-8071-1ed8d8e41d84@linaro.org \
--to=bryan.odonoghue@linaro.org \
--cc=andersson@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gustavoars@kernel.org \
--cc=johannes.goede@oss.qualcomm.com \
--cc=kees@kernel.org \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=loic.poulain@oss.qualcomm.com \
--cc=mchehab@kernel.org \
--cc=robh@kernel.org \
--cc=vladimir.zapolskiy@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox