From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
To: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
Cc: Jacopo Mondi <jacopo.mondi@ideasonboard.com>,
Jai Luthra <jai.luthra+renesas@ideasonboard.com>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
linux-kernel@vger.kernel.org,
Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
Subject: Re: [PATCH v9 05/13] media: rppx1: wbmeas: Add support for white balance measurement
Date: Wed, 3 Jun 2026 15:35:50 +0200 [thread overview]
Message-ID: <aiAtgAi-QXUIm8m1@zed> (raw)
In-Reply-To: <20260516211320.3041412-6-niklas.soderlund+renesas@ragnatech.se>
Hi Niklas,
On Sat, May 16, 2026 at 11:13:12PM +0200, Niklas Söderlund wrote:
> Extend the RPPX1 driver to allow setting the white balance measurement
> configuration and consuming the resulting statistics. It uses the RPPX1
> framework for parameters and its writer abstraction to allow the user to
> control how, and when, configuration is applied to the RPPX1.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> Co-developed-by: Jai Luthra <jai.luthra+renesas@ideasonboard.com>
> Signed-off-by: Jai Luthra <jai.luthra+renesas@ideasonboard.com>
> Co-developed-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> * Changes since v8
> - Use IS_ERR to check rppx1_init_stats_block() return code.
> ---
> .../platform/dreamchip/rppx1/rpp_module.h | 2 +
> .../platform/dreamchip/rppx1/rpp_params.c | 4 +
> .../platform/dreamchip/rppx1/rpp_stats.c | 18 +++
> .../platform/dreamchip/rppx1/rppx1_wbmeas.c | 103 ++++++++++++++++++
> .../uapi/linux/media/dreamchip/rppx1-config.h | 101 ++++++++++++++++-
> 5 files changed, 226 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_module.h b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
> index e92e77542980..64a1b848f1ea 100644
> --- a/drivers/media/platform/dreamchip/rppx1/rpp_module.h
> +++ b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
> @@ -47,10 +47,12 @@ void rpp_module_clrset(struct rpp_module *mod, u32 offset, u32 mask, u32 value);
>
> union rppx1_params_block {
> struct v4l2_isp_block_header header;
> + struct rppx1_wbmeas_params wbmeas;
> };
>
> union rppx1_stats_block {
> struct v4l2_isp_block_header header;
> + struct rppx1_wbmeas_stats wbmeas;
> };
>
> struct rpp_module_ops {
> diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_params.c b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
> index af45ad5750b3..7325abeba92a 100644
> --- a/drivers/media/platform/dreamchip/rppx1/rpp_params.c
> +++ b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
> @@ -17,6 +17,7 @@
>
> static const struct v4l2_isp_params_block_type_info
> rppx1_ext_params_blocks_info[] = {
> + RPPX1_PARAMS_BLOCK_INFO(WBMEAS_POST, wbmeas),
> };
>
> int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb, size_t max_size,
> @@ -50,6 +51,9 @@ int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb, size_t max_size,
> block_offset += block->header.size;
>
> switch (block->header.type) {
> + case RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST:
> + module = &rpp->post.wbmeas;
> + break;
> default:
> dev_warn(rpp->dev,
> "Not handled RPPX1 block type: 0x%04x\n",
> diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_stats.c b/drivers/media/platform/dreamchip/rppx1/rpp_stats.c
> index f7eb60deae10..c99ea158abcf 100644
> --- a/drivers/media/platform/dreamchip/rppx1/rpp_stats.c
> +++ b/drivers/media/platform/dreamchip/rppx1/rpp_stats.c
> @@ -15,6 +15,11 @@
> .size = sizeof(struct rppx1_ ## block ## _stats), \
> }
>
> +static const struct v4l2_isp_stats_block_type_info
> +rppx1_stats_blocks_info[] = {
> + RPPX1_STATS_BLOCK_INFO(WBMEAS_POST, wbmeas),
> +};
> +
This is handled a bit differently than params, where the
rppx1_ext_params_blocks_info[] array was already defined but empty.
A nit though
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Thanks
j
> #define rppx1_init_stats_block(rpp, buf, type) \
> ((union rppx1_stats_block *) \
> v4l2_isp_stats_init_block((rpp)->dev, (buf), \
> @@ -24,5 +29,18 @@
>
> void rppx1_stats_fill_isr(struct rppx1 *rpp, u32 isc, void *buf)
> {
> + struct v4l2_isp_buffer *stats = buf;
> + union rppx1_stats_block *block;
> +
> + v4l2_isp_stats_init_buffer(stats, V4L2_ISP_VERSION_V1);
> +
> + if (isc & RPPX1_IRQ_ID_POST_AWB_MEAS) {
> + block = rppx1_init_stats_block(rpp, stats,
> + RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST);
> + if (IS_ERR(block))
> + return;
> +
> + rpp_module_call(&rpp->post.wbmeas, fill_stats, block);
> + }
> }
> EXPORT_SYMBOL_GPL(rppx1_stats_fill_isr);
> diff --git a/drivers/media/platform/dreamchip/rppx1/rppx1_wbmeas.c b/drivers/media/platform/dreamchip/rppx1/rppx1_wbmeas.c
> index 60b9c076ec42..f0a943556238 100644
> --- a/drivers/media/platform/dreamchip/rppx1/rppx1_wbmeas.c
> +++ b/drivers/media/platform/dreamchip/rppx1/rppx1_wbmeas.c
> @@ -57,6 +57,109 @@ static int rppx1_wbmeas_probe(struct rpp_module *mod)
> return 0;
> }
>
> +static int
> +rppx1_wbmeas_fill_params(struct rpp_module *mod,
> + const union rppx1_params_block *block,
> + rppx1_reg_write write, void *priv)
> +{
> + const struct rppx1_wbmeas_params *cfg = &block->wbmeas;
> + u32 awb_meas_props;
> +
> + /* If the modules is disabled, simply bypass it. */
> + if (cfg->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) {
> + write(priv, mod->base + AWB_MEAS_PROP_REG, 0);
> + return 0;
> + }
> +
> + /* Program measurement window. */
> + write(priv, mod->base + AWB_MEAS_H_OFFS_REG, cfg->wnd.h_offs);
> + write(priv, mod->base + AWB_MEAS_V_OFFS_REG, cfg->wnd.v_offs);
> + write(priv, mod->base + AWB_MEAS_H_SIZE_REG, cfg->wnd.h_size);
> + write(priv, mod->base + AWB_MEAS_V_SIZE_REG, cfg->wnd.v_size);
> +
> + /* Set number of frames to sample. */
> + write(priv, mod->base + AWB_MEAS_FRAMES_REG, cfg->frames);
> +
> + if (cfg->mode == RPPX1_WBMEAS_MODE_YCBCR) {
> + write(priv, mod->base + AWB_MEAS_REF_CB_MAX_B_REG,
> + cfg->ref_cb_max_b);
> + write(priv, mod->base + AWB_MEAS_REF_CR_MAX_R_REG,
> + cfg->ref_cr_max_r);
> + write(priv, mod->base + AWB_MEAS_MAX_Y_REG, cfg->max_y);
> + write(priv, mod->base + AWB_MEAS_MIN_Y_MAX_G_REG,
> + cfg->min_y_max_g);
> + write(priv, mod->base + AWB_MEAS_MAX_CSUM_REG, cfg->max_csum);
> + write(priv, mod->base + AWB_MEAS_MIN_C_REG, cfg->min_c);
> +
> + /*
> + * Program the color conversion matrix coefficients and the
> + * per-color channel offsets.
> + */
> + for (unsigned int i = 0; i < 3; i++) {
> + for (unsigned int j = 0; j < 3; j++) {
> + unsigned int index = i * 3 + j;
> +
> + write(priv,
> + mod->base + AWB_MEAS_CCOR_COEFF_REG(index),
> + cfg->ccor_coeff[i][j]);
> + }
> + }
> +
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_R_REG,
> + cfg->ccor_offs[0]);
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_G_REG,
> + cfg->ccor_offs[1]);
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_B_REG,
> + cfg->ccor_offs[2]);
> +
> + awb_meas_props = cfg->ymax_cmp ? AWB_MEAS_PROP_YMAX : 0;
> + } else {
> + write(priv, mod->base + AWB_MEAS_REF_CB_MAX_B_REG,
> + cfg->ref_cb_max_b);
> + write(priv, mod->base + AWB_MEAS_REF_CR_MAX_R_REG,
> + cfg->ref_cr_max_r);
> + write(priv, mod->base + AWB_MEAS_MIN_Y_MAX_G_REG,
> + cfg->min_y_max_g);
> +
> + /* Bypass color conversion matrix and color offsets. */
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(0), 0x1000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(1), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(2), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(3), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(4), 0x1000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(5), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(6), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(7), 0x0000);
> + write(priv, mod->base + AWB_MEAS_CCOR_COEFF_REG(8), 0x1000);
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_R_REG, 0x00000000);
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_G_REG, 0x00000000);
> + write(priv, mod->base + AWB_MEAS_CCOR_OFFSET_B_REG, 0x00000000);
> +
> + awb_meas_props = AWB_MEAS_PROP_MEAS_MODE_RGB;
> + }
> +
> + write(priv, mod->base + AWB_MEAS_PROP_REG,
> + awb_meas_props | AWB_MEAS_PROP_AWB_MODE_ON);
> +
> + return 0;
> +}
> +
> +static int rppx1_wbmeas_fill_stats(struct rpp_module *mod,
> + union rppx1_stats_block *block)
> +{
> + struct rppx1_wbmeas_stats *stats = &block->wbmeas;
> +
> + /* Return measurements at native hardware precision. */
> + stats->cnt = rpp_module_read(mod, AWB_MEAS_WHITE_CNT_REG);
> + stats->mean_y_or_g = rpp_module_read(mod, AWB_MEAS_MEAN_Y_G_REG);
> + stats->mean_cb_or_b = rpp_module_read(mod, AWB_MEAS_MEAN_CB_B_REG);
> + stats->mean_cr_or_r = rpp_module_read(mod, AWB_MEAS_MEAN_CR_R_REG);
> +
> + return 0;
> +}
> +
> const struct rpp_module_ops rppx1_wbmeas_ops = {
> .probe = rppx1_wbmeas_probe,
> + .fill_params = rppx1_wbmeas_fill_params,
> + .fill_stats = rppx1_wbmeas_fill_stats
> };
> diff --git a/include/uapi/linux/media/dreamchip/rppx1-config.h b/include/uapi/linux/media/dreamchip/rppx1-config.h
> index b4d736d27ebb..938f8f258f9e 100644
> --- a/include/uapi/linux/media/dreamchip/rppx1-config.h
> +++ b/include/uapi/linux/media/dreamchip/rppx1-config.h
> @@ -42,13 +42,81 @@ struct rppx1_window {
> * the larger bitdepth/precision.
> */
>
> +/**
> + * enum rppx1_params_block_type - RPP-X1 extensible params block types
> + *
> + * NOTE: Only append to the enumeration as the numbers are uAPI.
> + *
> + * @RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST: AWB Measurement Configuration
> + */
> +enum rppx1_params_block_type {
> + RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST,
> +};
> +
> +/**
> + * enum rppx1_wbmeas_mode - AWB measurement mode
> + *
> + * @RPPX1_WBMEAS_MODE_YCBCR: YCbCr measurement mode
> + * @RPPX1_WBMEAS_MODE_RGB: RGB measurement mode
> + */
> +enum rppx1_wbmeas_mode {
> + RPPX1_WBMEAS_MODE_YCBCR,
> + RPPX1_WBMEAS_MODE_RGB,
> +};
> +
> +/**
> + * struct rppx1_wbmeas_params - AWB measurement configuration
> + *
> + * The Auto-White Balance measurement module is available on the MAIN_POST pipe.
> + * It supports two measurement modes, selected by the @mode field. The
> + * measurement window is programmed through the @wnd field.
> + *
> + * To support measurement in YCbCr mode a color conversion matrix with
> + * programmable offset is available in the @ccor_coeff and @ccor_offs fields.
> + * The color conversion matrix coefficients are represented as 16 bits signed
> + * Q4.12 numbers ranging from -8 to +7.99. The per-color channel offsets are
> + * represented as 25 bits 2's complement integer numbers ranging from -16777216
> + * to +16777215.
> + *
> + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST)
> + * @mode: measurement mode (from enum rppx1_wbmeas_mode)
> + * @ymax_cmp: enable Y_MAX compare using @max_y
> + * @wnd: measurement window
> + * @frames: number of frames for mean value calculation (0 = 1 frame)
> + * @ref_cr_max_r: reference Cr or max red value in RGB mode, 24 bits
> + * @ref_cb_max_b: reference Cb or max blue value in RGB mode, 24 bits
> + * @min_y_max_g: luminance minimum value or max green value in RGB mode, 24 bits
> + * @max_y: luminance maximum value, only valid if @mode is set to YCbCr and
> + * @ymax_cmp is set to enabled, 24 bits
> + * @max_csum: chrominance sum maximum value, 24 bits
> + * @min_c: chrominance minimum value, 24 bits
> + * @ccor_coeff: coefficients for color conversion matrix, signed 16 bits Q4.6
> + * @ccor_offs: R-G-B color conversion coefficients, signed 25 bits 2's complement
> + */
> +struct rppx1_wbmeas_params {
> + struct v4l2_isp_params_block_header header;
> + __u8 mode;
> + __u8 ymax_cmp;
> + struct rppx1_window wnd;
> + __u8 frames;
> + __u32 ref_cr_max_r;
> + __u32 ref_cb_max_b;
> + __u32 min_y_max_g;
> + __u32 max_y;
> + __u32 max_csum;
> + __u32 min_c;
> + __u16 ccor_coeff[3][3];
> + __u32 ccor_offs[3];
> +};
> +
> /**
> * RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks
> *
> * Some types are reported twice as the same block might be instantiated in
> * multiple pipes.
> */
> -#define RPPX1_PARAMS_MAX_SIZE 0
> +#define RPPX1_PARAMS_MAX_SIZE \
> + (sizeof(struct rppx1_wbmeas_params))
>
> /* ---------------------------------------------------------------------------
> * Statistics Structures
> @@ -59,12 +127,41 @@ struct rppx1_window {
> * the larger bitdepth/precision.
> */
>
> +/**
> + * enum rppx1_stats_block_type - RPP-X1 extensible stats block types
> + *
> + * NOTE: Only append to the enumeration as the numbers are uAPI.
> + *
> + * @RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST: post-fusion white-balance measurement
> + */
> +enum rppx1_stats_block_type {
> + RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST,
> +};
> +
> +/**
> + * struct rppx1_wbmeas_stats - AWB statistics
> + *
> + * @header: block header (type = RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST)
> + * @cnt: Number of pixels matched
> + * @mean_y_or_g: mean Y (or G in RGB mode) value, 24-bit
> + * @mean_cb_or_b: mean Cb (or B in RGB mode) value, 24-bit
> + * @mean_cr_or_r: mean Cr (or R in RGB mode) value, 24-bit
> + */
> +struct rppx1_wbmeas_stats {
> + struct v4l2_isp_block_header header;
> + __u32 cnt;
> + __u32 mean_y_or_g;
> + __u32 mean_cb_or_b;
> + __u32 mean_cr_or_r;
> +};
> +
> /**
> * RPPX1_STATS_MAX_SIZE - Maximum size of all RPP-X1 statistics
> *
> * Some types are reported twice as the same block might be instantiated in
> * multiple pipes.
> */
> -#define RPPX1_STATS_MAX_SIZE 0
> +#define RPPX1_STATS_MAX_SIZE \
> + (sizeof(struct rppx1_wbmeas_stats))
>
> #endif /* __UAPI_RPP_X1_CONFIG_H */
> --
> 2.54.0
>
next prev parent reply other threads:[~2026-06-03 13:35 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-16 21:13 [PATCH v9 00/13] media: Add support for R-Car ISP using Dreamchip RPPX1 ISP Niklas Söderlund
2026-05-16 21:13 ` [PATCH v9 01/13] media: Add RPP_X1_PARAMS and RPP_X1_STATS meta formats Niklas Söderlund
2026-06-03 10:49 ` Jacopo Mondi
2026-06-03 12:48 ` Niklas Söderlund
2026-05-16 21:13 ` [PATCH v9 02/13] media: uapi: Add extensible param and stats blocks for RPPX1 Niklas Söderlund
2026-06-03 10:50 ` Jacopo Mondi
2026-06-03 12:55 ` Niklas Söderlund
2026-05-16 21:13 ` [PATCH v9 03/13] media: rppx1: Add framework to support Dreamchip RPPX1 ISP Niklas Söderlund
2026-06-03 10:56 ` Jacopo Mondi
2026-06-03 12:24 ` Jacopo Mondi
2026-06-03 13:47 ` Niklas Söderlund
2026-06-03 14:26 ` Jacopo Mondi
2026-06-03 15:17 ` Niklas Söderlund
2026-06-03 15:33 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 04/13] media: rcar-isp: Add support for ISPCORE Niklas Söderlund
2026-06-03 13:15 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 05/13] media: rppx1: wbmeas: Add support for white balance measurement Niklas Söderlund
2026-06-03 13:35 ` Jacopo Mondi [this message]
2026-05-16 21:13 ` [PATCH v9 06/13] media: rppx1: awbg: Add support for white balance gain settings Niklas Söderlund
2026-06-03 13:38 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 07/13] media: rppx1: exm: Add support for exposure measurement Niklas Söderlund
2026-06-03 13:57 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 08/13] media: rppx1: hist: Add support histogram measurement Niklas Söderlund
2026-06-03 14:11 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 09/13] media: rppx1: bls: Add support for black level compensation Niklas Söderlund
2026-05-16 21:13 ` [PATCH v9 10/13] media: rppx1: ccor: Add support for color correction matrix Niklas Söderlund
2026-05-16 21:13 ` [PATCH v9 11/13] media: rppx1: lsc: Add support for lens shade correction Niklas Söderlund
2026-06-03 14:32 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 12/13] media: rppx1: ga: Add support for gamma out correction Niklas Söderlund
2026-06-03 14:33 ` Jacopo Mondi
2026-05-16 21:13 ` [PATCH v9 13/13] media: rppx1: lin: Add support for gamma sensor linearization Niklas Söderlund
2026-06-03 14:36 ` Jacopo Mondi
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=aiAtgAi-QXUIm8m1@zed \
--to=jacopo.mondi@ideasonboard.com \
--cc=jacopo.mondi+renesas@ideasonboard.com \
--cc=jai.luthra+renesas@ideasonboard.com \
--cc=kuninori.morimoto.gx@renesas.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=niklas.soderlund+renesas@ragnatech.se \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.