[v8 09/14] media: rppx1: ccor: Add support for color correction matrix

Niklas Söderlund
2026-05-04T01:09:15Z

Extend the RPPX1 driver to allow setting the color correction matrix
configuration parameters. 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>
---
.../platform/dreamchip/rppx1/rpp_module.h | 1 +
.../platform/dreamchip/rppx1/rpp_params.c | 4 ++
.../platform/dreamchip/rppx1/rppx1_ccor.c | 61 +++++++++++++++++++
.../uapi/linux/media/dreamchip/rppx1-config.h | 28 ++++++++-
4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_module.h b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
index 9c761448717b..121fea99b237 100644
--- a/drivers/media/platform/dreamchip/rppx1/rpp_module.h
+++ b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
@@ -87,6 +87,7 @@ union rppx1_params_block {
struct v4l2_isp_params_block_header header;
struct rppx1_bls_params bls;
struct rppx1_awbg_params awbg;
+ struct rppx1_ccor_params ccor;
struct rppx1_hist_params hist;
struct rppx1_exm_params exm;
struct rppx1_wbmeas_params wbmeas;
diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_params.c b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
index 7b006c68381b..57829e3b533d 100644
--- a/drivers/media/platform/dreamchip/rppx1/rpp_params.c
+++ b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
@@ -20,6 +20,7 @@ rppx1_ext_params_blocks_info[] = {
RPPX1_PARAMS_BLOCK_INFO(BLS_PRE2, bls),
RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE1, awbg),
RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE2, awbg),
+ RPPX1_PARAMS_BLOCK_INFO(CCOR_POST, ccor),
RPPX1_PARAMS_BLOCK_INFO(HIST_PRE1, hist),
RPPX1_PARAMS_BLOCK_INFO(HIST_PRE2, hist),
RPPX1_PARAMS_BLOCK_INFO(HIST_POST, hist),
@@ -66,6 +67,9 @@ int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb, size_t max_size,
case RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1:
module = &rpp->pre1.awbg;
break;
+ case RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST:
+ module = &rpp->post.ccor;
+ break;
case RPPX1_PARAMS_BLOCK_TYPE_HIST_POST:
module = &rpp->post.hist;
break;
diff --git a/drivers/media/platform/dreamchip/rppx1/rppx1_ccor.c b/drivers/media/platform/dreamchip/rppx1/rppx1_ccor.c
index 4754b0bbce0a..1655c58c8d59 100644
--- a/drivers/media/platform/dreamchip/rppx1/rppx1_ccor.c
+++ b/drivers/media/platform/dreamchip/rppx1/rppx1_ccor.c
@@ -68,9 +68,70 @@ static int rppx1_ccor_start(struct rpp_module *mod,
return 0;
}

+static int
+rppx1_ccor_fill_params(struct rpp_module *mod,
+ const union rppx1_params_block *block,
+ rppx1_reg_write write, void *priv)
+{
+ const struct rppx1_ccor_params *cfg = &block->ccor;
+
+ /* If the modules is disabled, configure in bypass mode. */
+ if (cfg->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) {
+ write(priv, mod->base + CCOR_COEFF_REG(0), 0x1000);
+ write(priv, mod->base + CCOR_COEFF_REG(1), 0x0000);
+ write(priv, mod->base + CCOR_COEFF_REG(2), 0x0000);
+
+ write(priv, mod->base + CCOR_COEFF_REG(3), 0x0000);
+ write(priv, mod->base + CCOR_COEFF_REG(4), 0x1000);
+ write(priv, mod->base + CCOR_COEFF_REG(5), 0x0000);
+
+ write(priv, mod->base + CCOR_COEFF_REG(6), 0x0000);
+ write(priv, mod->base + CCOR_COEFF_REG(7), 0x0000);
+ write(priv, mod->base + CCOR_COEFF_REG(8), 0x1000);
+
+ write(priv, mod->base + CCOR_OFFSET_R_REG, 0x00000000);
+ write(priv, mod->base + CCOR_OFFSET_G_REG, 0x00000000);
+ write(priv, mod->base + CCOR_OFFSET_B_REG, 0x00000000);
+
+ return 0;
+ }
+
+ /*
+ * Coefficient n for color correction matrix.
+ *
+ * RPP coefficients are 16-bit signed fixed-point numbers with 4 bit
+ * integer and 12 bit fractional part ranging from -8 (0x8000) to
+ * +7.9996 (0x7FFF). 0 is represented by 0x0000 and a coefficient
+ * value of 1 as 0x1000.
+ */
+ write(priv, mod->base + CCOR_COEFF_REG(0), cfg->coeff[0][0]);
+ write(priv, mod->base + CCOR_COEFF_REG(1), cfg->coeff[0][1]);
+ write(priv, mod->base + CCOR_COEFF_REG(2), cfg->coeff[0][2]);
+
+ write(priv, mod->base + CCOR_COEFF_REG(3), cfg->coeff[1][0]);
+ write(priv, mod->base + CCOR_COEFF_REG(4), cfg->coeff[1][1]);
+ write(priv, mod->base + CCOR_COEFF_REG(5), cfg->coeff[1][2]);
+
+ write(priv, mod->base + CCOR_COEFF_REG(6), cfg->coeff[2][0]);
+ write(priv, mod->base + CCOR_COEFF_REG(7), cfg->coeff[2][1]);
+ write(priv, mod->base + CCOR_COEFF_REG(8), cfg->coeff[2][2]);
+
+ /*
+ * Offset for color components correction matrix.
+ *
+ * Values are a two's complement integer with one sign bit.
+ */
+ write(priv, mod->base + CCOR_OFFSET_R_REG, cfg->offset[0]);
+ write(priv, mod->base + CCOR_OFFSET_G_REG, cfg->offset[1]);
+ write(priv, mod->base + CCOR_OFFSET_B_REG, cfg->offset[2]);
+
+ return 0;
+}
+
const struct rpp_module_ops rppx1_ccor_ops = {
.probe = rppx1_ccor_probe,
.start = rppx1_ccor_start,
+ .fill_params = rppx1_ccor_fill_params,
};

static int rppx1_ccor_csm_start(struct rpp_module *mod,
diff --git a/include/uapi/linux/media/dreamchip/rppx1-config.h b/include/uapi/linux/media/dreamchip/rppx1-config.h
index b181ef08d093..3030369a2fbc 100644
--- a/include/uapi/linux/media/dreamchip/rppx1-config.h
+++ b/include/uapi/linux/media/dreamchip/rppx1-config.h
@@ -86,6 +86,7 @@ enum rppx1_meas_chan {
* @RPPX1_PARAMS_BLOCK_TYPE_HIST_POST: POST pipe Histogram Measurement
* @RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE1: PRE1 pipe Black Level Subtraction
* @RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE2: PRE2 pipe Black Level Subtraction
+ * @RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST: POST pipe Color Correction
*/
enum rppx1_params_block_type {
RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST,
@@ -99,6 +100,7 @@ enum rppx1_params_block_type {
RPPX1_PARAMS_BLOCK_TYPE_HIST_POST,
RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE1,
RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE2,
+ RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST,
};

/**
@@ -420,6 +422,29 @@ struct rppx1_bls_params {
struct rppx1_bls_fixed fixed;
};

+/**
+ * struct rppx1_ccor_params - Color CORrection configuration
+ *
+ * The CCOR (Color Correction) module is available on the MAIN_POST pipe. It
+ * performs color space correction on a pixel-per-pixel basis using a 3x3 matrix
+ * of coefficients and per-color channel offsets.
+ *
+ * The matrix coefficients are represented as 16 bits signed fixed point values
+ * in Q4.12 format ranging from -8 to +7.999.
+ *
+ * The per-channel color offsets are represented as 2's complement values
+ * stored in 25 bits ranging from -16777216 to 16777215.
+ *
+ * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST)
+ * @coeff: color correction matrix coefficients, 16 bits signed Q4.12
+ * @offset: R, G, B offsets, 2's complement 25 bits
+ */
+struct rppx1_ccor_params {
+ struct v4l2_isp_params_block_header header;
+ __u16 coeff[3][3];
+ __u32 offset[3];
+};
+
/**
* RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks
*
@@ -437,7 +462,8 @@ struct rppx1_bls_params {
sizeof(struct rppx1_hist_params) + \
sizeof(struct rppx1_hist_params) + \
sizeof(struct rppx1_bls_params) + \
- sizeof(struct rppx1_bls_params))
+ sizeof(struct rppx1_bls_params) + \
+ sizeof(struct rppx1_ccor_params))

/* ---------------------------------------------------------------------------
* Statistics Structures
--
2.54.0