[v8 12/14] media: rppx1: db: Add support for debayering filters

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

Extend the RPPX1 driver to allow setting the debayering filters
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 | 2 +
.../platform/dreamchip/rppx1/rpp_params.c | 7 ++
.../media/platform/dreamchip/rppx1/rppx1_db.c | 82 +++++++++++++++++++
.../uapi/linux/media/dreamchip/rppx1-config.h | 58 ++++++++++++-
4 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_module.h b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
index 830ef0df7228..064da13082fe 100644
--- a/drivers/media/platform/dreamchip/rppx1/rpp_module.h
+++ b/drivers/media/platform/dreamchip/rppx1/rpp_module.h
@@ -88,6 +88,8 @@ union rppx1_params_block {
struct rppx1_bls_params bls;
struct rppx1_lsc_params lsc;
struct rppx1_awbg_params awbg;
+ struct rppx1_db_demosaic_params db_demosaic;
+ struct rppx1_db_filter_params db_filter;
struct rppx1_ccor_params ccor;
struct rppx1_hist_params hist;
struct rppx1_exm_params exm;
diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_params.c b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
index 317ed715f1de..3320ca3998bd 100644
--- a/drivers/media/platform/dreamchip/rppx1/rpp_params.c
+++ b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
@@ -22,6 +22,8 @@ rppx1_ext_params_blocks_info[] = {
RPPX1_PARAMS_BLOCK_INFO(LSC_PRE2, lsc),
RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE1, awbg),
RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE2, awbg),
+ RPPX1_PARAMS_BLOCK_INFO(DB_DEMOSAIC_POST, db_demosaic),
+ RPPX1_PARAMS_BLOCK_INFO(DB_FILTER_POST, db_filter),
RPPX1_PARAMS_BLOCK_INFO(CCOR_POST, ccor),
RPPX1_PARAMS_BLOCK_INFO(HIST_PRE1, hist),
RPPX1_PARAMS_BLOCK_INFO(HIST_PRE2, hist),
@@ -74,6 +76,11 @@ 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_DB_DEMOSAIC_POST:
+ case RPPX1_PARAMS_BLOCK_TYPE_DB_FILTER_POST:
+ /* Both types handled by the same block. */
+ module = &rpp->post.db;
+ break;
case RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST:
module = &rpp->post.ccor;
break;
diff --git a/drivers/media/platform/dreamchip/rppx1/rppx1_db.c b/drivers/media/platform/dreamchip/rppx1/rppx1_db.c
index 5e233896cfc8..5571b3a9562d 100644
--- a/drivers/media/platform/dreamchip/rppx1/rppx1_db.c
+++ b/drivers/media/platform/dreamchip/rppx1/rppx1_db.c
@@ -39,6 +39,88 @@ static int rppx1_db_probe(struct rpp_module *mod)
return 0;
}

+static int
+rppx1_db_fill_params_demosaic(struct rpp_module *mod,
+ const union rppx1_params_block *block,
+ rppx1_reg_write write, void *priv)
+{
+ const struct rppx1_db_demosaic_params *cfg = &block->db_demosaic;
+
+ /* If the modules is disabled, simply bypass it. */
+ if (cfg->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) {
+ write(priv, mod->base + DEMOSAIC_REG, 0x400);
+ return 0;
+ }
+
+ /* Native threshold is at RPP 16-bit precision. */
+ write(priv, mod->base + DEMOSAIC_REG, cfg->demosaic_th);
+
+ return 0;
+}
+
+static int
+rppx1_db_fill_params_filter(struct rpp_module *mod,
+ const union rppx1_params_block *block,
+ rppx1_reg_write write, void *priv)
+{
+ const struct rppx1_db_filter_params *cfg = &block->db_filter;
+
+ /* If the modules is disabled, simply bypass it. */
+ if (cfg->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) {
+ write(priv, mod->base + FILT_MODE_REG, 0);
+ return 0;
+ }
+
+ /* Native values are at RPP 18-bit precision. */
+ write(priv, mod->base + FILT_THRESH_BL0_REG, cfg->thresh_bl0);
+ write(priv, mod->base + FILT_THRESH_BL0_REG, cfg->thresh_bl1);
+ write(priv, mod->base + FILT_THRESH_SH0_REG, cfg->thresh_sh0);
+ write(priv, mod->base + FILT_THRESH_SH1_REG, cfg->thresh_sh1);
+
+ /* Native values are at RPP 8-bit precision. */
+ write(priv, mod->base + FILT_FAC_BL0_REG, cfg->fac_bl0);
+ write(priv, mod->base + FILT_FAC_BL1_REG, cfg->fac_bl1);
+ write(priv, mod->base + FILT_FAC_MID_REG, cfg->fac_mid);
+ write(priv, mod->base + FILT_FAC_SH0_REG, cfg->fac_sh0);
+ write(priv, mod->base + FILT_FAC_SH1_REG, cfg->fac_sh1);
+
+ /*
+ * The lum_weight field is provided in RPP register format:
+ *
+ * 31 unused
+ * 30:28 lum_weight_gain
+ * 27:24 unused
+ * 23:12 lum_weight_kink
+ * 11:0 lum_weight_min
+ */
+ write(priv, mod->base + FILT_LUM_WEIGHT_REG, cfg->lum_weight);
+
+ write(priv, mod->base + FILT_MODE_REG,
+ (cfg->chr_v_mode << 4) |
+ (cfg->chr_h_mode << 6) |
+ (cfg->grn_stage1 << 8) |
+ (cfg->mode ? FILT_MODE_FILT_MODE : 0) |
+ FILT_MODE_FILT_ENABLE);
+
+ return 0;
+}
+
+static int
+rppx1_db_fill_params(struct rpp_module *mod,
+ const union rppx1_params_block *block,
+ rppx1_reg_write write, void *priv)
+{
+ switch (block->header.type) {
+ case RPPX1_PARAMS_BLOCK_TYPE_DB_DEMOSAIC_POST:
+ return rppx1_db_fill_params_demosaic(mod, block, write, priv);
+ case RPPX1_PARAMS_BLOCK_TYPE_DB_FILTER_POST:
+ return rppx1_db_fill_params_filter(mod, block, write, priv);
+ }
+
+ return -EINVAL;
+}
+
const struct rpp_module_ops rppx1_db_ops = {
.probe = rppx1_db_probe,
+ .fill_params = rppx1_db_fill_params,
};
diff --git a/include/uapi/linux/media/dreamchip/rppx1-config.h b/include/uapi/linux/media/dreamchip/rppx1-config.h
index d173c0c1bfc0..378b18dbc48d 100644
--- a/include/uapi/linux/media/dreamchip/rppx1-config.h
+++ b/include/uapi/linux/media/dreamchip/rppx1-config.h
@@ -91,6 +91,8 @@ enum rppx1_meas_chan {
* @RPPX1_PARAMS_BLOCK_TYPE_LSC_PRE2: PRE2 Lens Shading Correction
* @RPPX1_PARAMS_BLOCK_TYPE_GA_HV: Human Vision Pipe Gamma Out Correction
* @RPPX1_PARAMS_BLOCK_TYPE_GA_MV: Machine Vision Gamma Out Correction
+ * @RPPX1_PARAMS_BLOCK_TYPE_DB_DEMOSAIC_POST: Debayer demosaicing
+ * @RPPX1_PARAMS_BLOCK_TYPE_DB_FILTER_POST: Debayer filtering
*/
enum rppx1_params_block_type {
RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST,
@@ -109,6 +111,8 @@ enum rppx1_params_block_type {
RPPX1_PARAMS_BLOCK_TYPE_LSC_PRE2,
RPPX1_PARAMS_BLOCK_TYPE_GA_HV,
RPPX1_PARAMS_BLOCK_TYPE_GA_MV,
+ RPPX1_PARAMS_BLOCK_TYPE_DB_DEMOSAIC_POST,
+ RPPX1_PARAMS_BLOCK_TYPE_DB_FILTER_POST,
};

/**
@@ -544,6 +548,56 @@ struct rppx1_ga_params {
__u32 gamma_y[RPPX1_GA_MAX_SAMPLES];
};

+/**
+ * struct rppx1_db_demosaic_params - Debayer demosaic configuration
+ *
+ * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_DB_DEMOSAIC_POST)
+ * @demosaic_th: threshold for texture detection, 16-bit
+ */
+struct rppx1_db_demosaic_params {
+ struct v4l2_isp_params_block_header header;
+ __u16 demosaic_th;
+};
+
+/**
+ * struct rppx1_db_filter_params - Debayer filter (denoise) configuration
+ *
+ * RPP-X1 thresholds are 18-bit and factors are 8-bit.
+ *
+ * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_DB_FILTER_POST)
+ * @mode: filter mode
+ * @grn_stage1: green filter stage 1 select (range 0x0...0x8)
+ * @chr_h_mode: chroma filter horizontal mode
+ * @chr_v_mode: chroma filter vertical mode
+ * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
+ * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
+ * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
+ * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
+ * @lum_weight: luminance weight, min (bits 0:11), kink (bits 12:23), gain (bits 28:30)
+ * @fac_sh1: filter factor for sharp1 level
+ * @fac_sh0: filter factor for sharp0 level
+ * @fac_mid: filter factor for mid level and for static filter mode
+ * @fac_bl0: filter factor for blur0 level
+ * @fac_bl1: filter factor for blur1 level (max blur)
+ */
+struct rppx1_db_filter_params {
+ struct v4l2_isp_params_block_header header;
+ __u32 mode;
+ __u8 grn_stage1;
+ __u8 chr_h_mode;
+ __u8 chr_v_mode;
+ __u32 thresh_bl0;
+ __u32 thresh_bl1;
+ __u32 thresh_sh0;
+ __u32 thresh_sh1;
+ __u32 lum_weight;
+ __u32 fac_sh1;
+ __u32 fac_sh0;
+ __u32 fac_mid;
+ __u32 fac_bl0;
+ __u32 fac_bl1;
+};
+
/**
* RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks
*
@@ -566,7 +620,9 @@ struct rppx1_ga_params {
sizeof(struct rppx1_lsc_params) + \
sizeof(struct rppx1_lsc_params) + \
sizeof(struct rppx1_ga_params) + \
- sizeof(struct rppx1_ga_params))
+ sizeof(struct rppx1_ga_params) + \
+ sizeof(struct rppx1_db_demosaic_params) + \
+ sizeof(struct rppx1_db_filter_params))

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