public inbox for linux-rockchip@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] media: rockchip: rkisp1: Add support for WDR and AWB64
@ 2025-02-25 12:53 Jai Luthra
  2025-02-25 12:53 ` [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range Jai Luthra
  2025-02-25 12:53 ` [PATCH v3 2/2] media: rockchip: rkisp1: Add support for AWB64 Jai Luthra
  0 siblings, 2 replies; 5+ messages in thread
From: Jai Luthra @ 2025-02-25 12:53 UTC (permalink / raw)
  To: Dafna Hirschfeld, Laurent Pinchart, Mauro Carvalho Chehab,
	Heiko Stuebner
  Cc: linux-media, linux-rockchip, linux-arm-kernel, linux-kernel,
	Stefan Klug, Jai Luthra

Add support for Wide Dynamic Range and Auto White Balance 64 modules of
the ISP.

This series is in continuation of the v2 posted earlier that enabled
only AWB64. We add a new patch enabling WDR, and rebase the AWB64
patch on top of it, as WDR is a simpler module which is present across
different variants of the ISP.

Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
---
Changes in v3:
- Add a new patch that enables support for WDR module, and rebase AWB64
  support on top of it
- Document the fractional bits used for AWB64 configuration parameters
- Link to v2: https://lore.kernel.org/r/20250110-awb64-v2-1-01b7fb471465@ideasonboard.com

Changes in v2:
- Fix register offsets
- Drop the _v10 suffix from awb64 functions
- Combine the min and max for R, G, B components into a single value in
  the struct
- Move all the configuration except IRQ and module enable in the
  meas_config() routine, making sure the bool bits are cleared if
  userspace updates the struct
- Fix documentation and indent at various places
- Create a single function for getting both AWB and AWB64 stats for
  IMX8MP
- Rename accumulator fields to only specify RGB and not YUV, as AWB64
  block does not operate on YUV colorspace
- Link to v1: https://lore.kernel.org/r/20241230-awb64-v1-1-27b0ee65f551@ideasonboard.com

---
Jai Luthra (2):
      media: rockchip: rkisp1: Add support for Wide Dynamic Range
      media: rockchip: rkisp1: Add support for AWB64

 .../media/platform/rockchip/rkisp1/rkisp1-common.h |   2 +
 .../media/platform/rockchip/rkisp1/rkisp1-dev.c    |   3 +-
 .../media/platform/rockchip/rkisp1/rkisp1-params.c | 215 +++++++++++++++++++++
 .../media/platform/rockchip/rkisp1/rkisp1-regs.h   | 140 +++++++-------
 .../media/platform/rockchip/rkisp1/rkisp1-stats.c  |  40 ++++
 include/uapi/linux/rkisp1-config.h                 | 208 ++++++++++++++++++++
 6 files changed, 533 insertions(+), 75 deletions(-)
---
base-commit: d082ecbc71e9e0bf49883ee4afd435a77a5101b6
change-id: 20241230-awb64-79270098e15e

Best regards,
-- 
Jai Luthra <jai.luthra@ideasonboard.com>


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range
  2025-02-25 12:53 [PATCH v3 0/2] media: rockchip: rkisp1: Add support for WDR and AWB64 Jai Luthra
@ 2025-02-25 12:53 ` Jai Luthra
  2025-04-10 15:51   ` Laurent Pinchart
  2025-02-25 12:53 ` [PATCH v3 2/2] media: rockchip: rkisp1: Add support for AWB64 Jai Luthra
  1 sibling, 1 reply; 5+ messages in thread
From: Jai Luthra @ 2025-02-25 12:53 UTC (permalink / raw)
  To: Dafna Hirschfeld, Laurent Pinchart, Mauro Carvalho Chehab,
	Heiko Stuebner
  Cc: linux-media, linux-rockchip, linux-arm-kernel, linux-kernel,
	Stefan Klug, Jai Luthra

RKISP supports a basic Wide Dynamic Range (WDR) module since the first
iteration (v1.0) of the ISP. Add support for enabling and configuring it
using extensible parameters.

Also, to ease programming, switch to using macro variables for defining
the tonemapping curve register addresses.

Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
---
New patch in v3
---
 .../media/platform/rockchip/rkisp1/rkisp1-params.c |  92 +++++++++++++++++++
 .../media/platform/rockchip/rkisp1/rkisp1-regs.h   |  99 +++++---------------
 include/uapi/linux/rkisp1-config.h                 | 101 +++++++++++++++++++++
 3 files changed, 218 insertions(+), 74 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
index b28f4140c8a309a3231d44d825c6461e3ecb2a44..92a9aad79f6dca3c76d7692421827234e7f06390 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
@@ -60,6 +60,7 @@ union rkisp1_ext_params_config {
 	struct rkisp1_ext_params_afc_config afc;
 	struct rkisp1_ext_params_compand_bls_config compand_bls;
 	struct rkisp1_ext_params_compand_curve_config compand_curve;
+	struct rkisp1_ext_params_wdr_config wdr;
 };
 
 enum rkisp1_params_formats {
@@ -1348,6 +1349,73 @@ rkisp1_compand_compress_config(struct rkisp1_params *params,
 				       arg->x);
 }
 
+static void rkisp1_wdr_config(struct rkisp1_params *params,
+			      const struct rkisp1_cif_isp_wdr_config *arg)
+{
+	unsigned int i;
+	u32 value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL);
+
+	/* Colorspace and chrominance mapping */
+	if (arg->use_rgb_colorspace)
+		value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
+	else
+		value &= ~RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
+
+	if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
+		value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
+	else
+		value &= ~RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
+
+	/* Illumination reference */
+	if (arg->use_iref) {
+		value = RKISP1_CIF_ISP_WDR_USE_IREF;
+
+		if (arg->iref_config.use_y9_8)
+			value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;
+		else
+			value &= ~RKISP1_CIF_ISP_WDR_USE_Y9_8;
+
+		if (arg->iref_config.use_rgb7_8)
+			value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;
+		else
+			value &= ~RKISP1_CIF_ISP_WDR_USE_RGB7_8;
+
+		if (arg->iref_config.disable_transient)
+			value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
+		else
+			value &= ~RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
+
+		value |= min_t(u8, arg->iref_config.rgb_factor,
+			       RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX)
+			 << RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT;
+	} else {
+		value &= ~RKISP1_CIF_ISP_WDR_USE_IREF;
+	}
+
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);
+
+	/* RGB and Luminance offsets */
+	value = arg->rgb_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK;
+	value |= (arg->luma_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK)
+		 << RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT;
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);
+
+	/* DeltaMin */
+	value = arg->dmin_thresh & RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK;
+	value |= min_t(u8, arg->dmin_strength,
+		       RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX)
+		 << RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT;
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_DELTAMIN, value);
+
+	/* Tone curve */
+	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS; i++)
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE(i),
+			     arg->tone_curve.dY[i]);
+	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF; i++)
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
+			     arg->tone_curve.ym[i]);
+}
+
 static void
 rkisp1_isp_isr_other_config(struct rkisp1_params *params,
 			    const struct rkisp1_params_cfg *new_params)
@@ -2005,6 +2073,25 @@ static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params,
 				      RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);
 }
 
+static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
+				  const union rkisp1_ext_params_config *block)
+{
+	const struct rkisp1_ext_params_wdr_config *wdr = &block->wdr;
+
+	if (wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
+		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
+					RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
+		return;
+	}
+
+	rkisp1_wdr_config(params, &wdr->config);
+
+	if ((wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
+	    !(params->enabled_blocks & BIT(wdr->header.type)))
+		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
+				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
+}
+
 typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
 			     const union rkisp1_ext_params_config *config);
 
@@ -2118,6 +2205,11 @@ static const struct rkisp1_ext_params_handler {
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 		.features	= RKISP1_FEATURE_COMPAND,
 	},
+	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
+		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
+		.handler	= rkisp1_ext_params_wdr,
+		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
+	},
 };
 
 static void rkisp1_ext_params_config(struct rkisp1_params *params,
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
index bf0260600a1923eebde6b5fe233daf7d427362dd..31783617f39753a9b847b6612c9adf09c2ea8c99 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
@@ -710,6 +710,27 @@
 #define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG	BIT(2)
 #define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE		BIT(3)
 
+/* WDR */
+/* ISP_WDR_CTRL */
+#define RKISP1_CIF_ISP_WDR_CTRL_ENABLE			BIT(0)
+#define RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT		BIT(1)
+#define RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE		BIT(2)
+#define RKISP1_CIF_ISP_WDR_USE_IREF			BIT(3)
+#define RKISP1_CIF_ISP_WDR_USE_Y9_8			BIT(4)
+#define RKISP1_CIF_ISP_WDR_USE_RGB7_8			BIT(5)
+#define RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT		BIT(6)
+#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT		8
+#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX		8
+/* ISP_WDR_TONE_CURVE_YM */
+#define RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK		GENMASK(12, 0)
+/* ISP_WDR_OFFSET */
+#define RKISP1_CIF_ISP_WDR_OFFSET_MASK			GENMASK(11, 0)
+#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT		16
+/* ISP_WDR_DELTAMIN */
+#define RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK		GENMASK(11, 0)
+#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX		0x10
+#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT		16
+
 /* =================================================================== */
 /*                            CIF Registers                            */
 /* =================================================================== */
@@ -1302,82 +1323,12 @@
 
 #define RKISP1_CIF_ISP_WDR_BASE			0x00002a00
 #define RKISP1_CIF_ISP_WDR_CTRL			(RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2		(RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3		(RKISP1_CIF_ISP_WDR_BASE + 0x0000000c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4		(RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1	(RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2	(RKISP1_CIF_ISP_WDR_BASE + 0x0000001c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3	(RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4	(RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5	(RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6	(RKISP1_CIF_ISP_WDR_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7	(RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8	(RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9	(RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10	(RKISP1_CIF_ISP_WDR_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11	(RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12	(RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13	(RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14	(RKISP1_CIF_ISP_WDR_BASE + 0x0000004c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15	(RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16	(RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17	(RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18	(RKISP1_CIF_ISP_WDR_BASE + 0x0000005c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19	(RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20	(RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21	(RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22	(RKISP1_CIF_ISP_WDR_BASE + 0x0000006c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23	(RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24	(RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25	(RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26	(RKISP1_CIF_ISP_WDR_BASE + 0x0000007c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27	(RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28	(RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29	(RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30	(RKISP1_CIF_ISP_WDR_BASE + 0x0000008c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31	(RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32	(RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
+#define RKISP1_CIF_ISP_WDR_TONECURVE(n)		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004 + (n) * 4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014 + (n) * 4)
 #define RKISP1_CIF_ISP_WDR_OFFSET		(RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
 #define RKISP1_CIF_ISP_WDR_DELTAMIN		(RKISP1_CIF_ISP_WDR_BASE + 0x0000009c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ac)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000bc)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000cc)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000dc)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ec)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000fc)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000010c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000011c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000012c)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
 
 #define RKISP1_CIF_ISP_HIST_BASE_V12		0x00002c00
 #define RKISP1_CIF_ISP_HIST_CTRL_V12		(RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)
diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
index 430daceafac7056951be968f3b4d9cd50eb04e71..78f4f350119bd29b2ac50cba2dd7cf3b0e4a8416 100644
--- a/include/uapi/linux/rkisp1-config.h
+++ b/include/uapi/linux/rkisp1-config.h
@@ -169,6 +169,13 @@
  */
 #define RKISP1_CIF_ISP_COMPAND_NUM_POINTS	64
 
+/*
+ * Wide Dynamic Range
+ */
+#define RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV	32
+#define RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF	(RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV + 1)
+#define RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS	4
+
 /*
  * Measurement types
  */
@@ -889,6 +896,81 @@ struct rkisp1_cif_isp_compand_curve_config {
 	__u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
 };
 
+/**
+ * struct rkisp1_cif_isp_wdr_tone_curve - Tone mapping curve definition for WDR.
+ *
+ * @dY: the dYn increments for horizontal (input) axis of the tone curve.
+ *      each 3-bit dY value represents an increment of 2**(value+3).
+ *      dY[0] bits 0:2 is increment dY1, bit 3 unused
+ *      dY[0] bits 4:6 is increment dY2, bit 7 unused
+ *      ...
+ *      dY[0] bits 28:30 is increment dY8, bit 31 unused
+ *      ... and so on till dY[3] bits 28:30 is increment dY32, bit 31 unused.
+ * @ym: the Ym values for the vertical (output) axis of the tone curve.
+ *      each value is 13 bit.
+ *
+ * The reset values define a linear curve which has the same effect as bypass:
+ *
+ * dY[0..3] = 0x44444444, This means that input sample range of 0-4096 is
+ * divided in 32 equal increments of 2**(4+3) = 128 units
+ *
+ * ym[0] = 0x0000, ym[1] = 0x0080, ... ym[31] = 0x0f80, ym[32] = 0x1000
+ * which increases by 0x80 = 128 units
+ *
+ */
+struct rkisp1_cif_isp_wdr_tone_curve {
+	__u32 dY[RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS];
+	__u16 ym[RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF];
+};
+
+/**
+ * struct rkisp1_cif_isp_wdr_iref_config - Illumination reference config for WDR.
+ *
+ * Use illumination reference value as described below, instead of only the
+ * luminance (Y) value for tone mapping and gain calculations:
+ * IRef = (rgb_factor * RGBMax_tr + (8 - rgb_factor) * Y)/8
+ *
+ * @rgb_factor: defines how much influence the RGBmax approach has in
+ *              comparison to Y (valid values are 0..8).
+ * @use_y9_8: use Y*9/8 for maximum value calculation along with the
+ *            default of R, G, B for noise reduction.
+ * @use_rgb7_8: decrease RGBMax by 7/8 for noise reduction.
+ * @disable_transient: disable transient calculation between Y and RGBY_max.
+ */
+struct rkisp1_cif_isp_wdr_iref_config {
+	__u8 rgb_factor;
+	__u8 use_y9_8;
+	__u8 use_rgb7_8;
+	__u8 disable_transient;
+};
+
+/**
+ * struct rkisp1_cif_isp_wdr_config - Configuration for wide dynamic range.
+ *
+ * @tone_curve: tone mapping curve.
+ * @iref_config: illumination reference configuration. (when use_iref is true)
+ * @rgb_offset: RGB offset value for RGB operation mode. (12 bits)
+ * @luma_offset: luminance offset value for RGB operation mode. (12 bits)
+ * @dmin_thresh: lower threshold for deltaMin value. (12 bits)
+ * @dmin_strength: strength factor for deltaMin. (valid range is 0x00..0x10)
+ * @use_rgb_colorspace: use RGB instead of luminance/chrominance colorspace.
+ * @bypass_chroma_mapping: disable chrominance mapping (only valid if
+ *                         use_rgb_colorspace = 0)
+ * @use_iref: use illumination reference instead of Y for tone mapping
+ *            and gain calculations.
+ */
+struct rkisp1_cif_isp_wdr_config {
+	struct rkisp1_cif_isp_wdr_tone_curve tone_curve;
+	struct rkisp1_cif_isp_wdr_iref_config iref_config;
+	__u16 rgb_offset;
+	__u16 luma_offset;
+	__u16 dmin_thresh;
+	__u8 dmin_strength;
+	__u8 use_rgb_colorspace;
+	__u8 bypass_chroma_mapping;
+	__u8 use_iref;
+};
+
 /*---------- PART2: Measurement Statistics ------------*/
 
 /**
@@ -1059,6 +1141,7 @@ struct rkisp1_stat_buffer {
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS: BLS in the compand block
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve
+ * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range
  */
 enum rkisp1_ext_params_block_type {
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
@@ -1081,6 +1164,7 @@ enum rkisp1_ext_params_block_type {
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS,
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
+	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
 };
 
 #define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
@@ -1460,6 +1544,23 @@ struct rkisp1_ext_params_compand_curve_config {
 	struct rkisp1_cif_isp_compand_curve_config config;
 } __attribute__((aligned(8)));
 
+/**
+ * struct rkisp1_ext_params_wdr_config - RkISP1 extensible params
+ *                                       Wide dynamic range config
+ *
+ * RkISP1 extensible parameters WDR block.
+ * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR`
+ *
+ * @header: The RkISP1 extensible parameters header, see
+ *	    :c:type:`rkisp1_ext_params_block_header`
+ * @config: WDR configuration, see
+ *	    :c:type:`rkisp1_cif_isp_wdr_config`
+ */
+struct rkisp1_ext_params_wdr_config {
+	struct rkisp1_ext_params_block_header header;
+	struct rkisp1_cif_isp_wdr_config config;
+} __attribute__((aligned(8)));
+
 /*
  * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
  * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.

-- 
2.48.1


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/2] media: rockchip: rkisp1: Add support for AWB64
  2025-02-25 12:53 [PATCH v3 0/2] media: rockchip: rkisp1: Add support for WDR and AWB64 Jai Luthra
  2025-02-25 12:53 ` [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range Jai Luthra
@ 2025-02-25 12:53 ` Jai Luthra
  1 sibling, 0 replies; 5+ messages in thread
From: Jai Luthra @ 2025-02-25 12:53 UTC (permalink / raw)
  To: Dafna Hirschfeld, Laurent Pinchart, Mauro Carvalho Chehab,
	Heiko Stuebner
  Cc: linux-media, linux-rockchip, linux-arm-kernel, linux-kernel,
	Stefan Klug, Jai Luthra

AWB64 is an advanced auto white-balance statistics block, present on the
ISP in iMX8MP. This block can calculate color statistics for a maximum
of 8 different (elliptical) regions, which can help the AWB algorithm in
calculating gains for complex lighting scenarios.

Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
---
Changes in v3:
- Rebase on top of WDR support
- Improve doxygen comments to better describe the fixed-point values
  used by AWB64 for ellipse configuration and minimum divider threshold
---
 .../media/platform/rockchip/rkisp1/rkisp1-common.h |   2 +
 .../media/platform/rockchip/rkisp1/rkisp1-dev.c    |   3 +-
 .../media/platform/rockchip/rkisp1/rkisp1-params.c | 123 +++++++++++++++++++++
 .../media/platform/rockchip/rkisp1/rkisp1-regs.h   |  41 +++++++
 .../media/platform/rockchip/rkisp1/rkisp1-stats.c  |  40 +++++++
 include/uapi/linux/rkisp1-config.h                 | 107 ++++++++++++++++++
 6 files changed, 315 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index ca952fd0829ba7d923ad42fec92840ccd422b6e5..60fbf5a886c498957ba04ddd47a21b744d4ff8b1 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -118,6 +118,7 @@ enum rkisp1_isp_pad {
  * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
  * @RKISP1_FEATURE_BLS: The ISP has a dedicated BLS block
  * @RKISP1_FEATURE_COMPAND: The ISP has a companding block
+ * @RKISP1_FEATURE_AWB64: The ISP has an AWB64 block
  *
  * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
  * the driver to implement support for features present in some ISP versions
@@ -131,6 +132,7 @@ enum rkisp1_feature {
 	RKISP1_FEATURE_DMA_34BIT = BIT(4),
 	RKISP1_FEATURE_BLS = BIT(5),
 	RKISP1_FEATURE_COMPAND = BIT(6),
+	RKISP1_FEATURE_AWB64 = BIT(7),
 };
 
 #define rkisp1_has_feature(rkisp1, feature) \
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index dc65a7924f8ae6f95e7c93c4339619cd90881a62..576ed26e013add281b6d1ad401ba91c5c4128e76 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -560,7 +560,8 @@ static const struct rkisp1_info imx8mp_isp_info = {
 	.isp_ver = RKISP1_V_IMX8MP,
 	.features = RKISP1_FEATURE_MAIN_STRIDE
 		  | RKISP1_FEATURE_DMA_34BIT
-		  | RKISP1_FEATURE_COMPAND,
+		  | RKISP1_FEATURE_COMPAND
+		  | RKISP1_FEATURE_AWB64,
 	.max_width = 4096,
 	.max_height = 3072,
 };
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
index 92a9aad79f6dca3c76d7692421827234e7f06390..7671dfc8249b4f631ab8bc1e0a7bf6debc0ddc1a 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
@@ -61,6 +61,7 @@ union rkisp1_ext_params_config {
 	struct rkisp1_ext_params_compand_bls_config compand_bls;
 	struct rkisp1_ext_params_compand_curve_config compand_curve;
 	struct rkisp1_ext_params_wdr_config wdr;
+	struct rkisp1_ext_params_awb64_meas_config awb64;
 };
 
 enum rkisp1_params_formats {
@@ -675,6 +676,105 @@ rkisp1_awb_meas_enable_v12(struct rkisp1_params *params,
 	}
 }
 
+/* ISP White Balance Mode */
+static void
+rkisp1_awb64_meas_config(struct rkisp1_params *params,
+			 const struct rkisp1_cif_isp_awb64_meas_config *arg)
+{
+	u32 reg_val =
+		rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB64_MEAS_MODE);
+
+	/* Measurement mode */
+	if (arg->enable_median_filter)
+		reg_val |= RKISP1_CIF_ISP_AWB64_PRE_FILTER_EN;
+	else
+		reg_val &= ~RKISP1_CIF_ISP_AWB64_PRE_FILTER_EN;
+
+	if (arg->chrom_switch)
+		reg_val |= RKISP1_CIF_ISP_AWB64_CHROM_SWITCH;
+	else
+		reg_val &= ~RKISP1_CIF_ISP_AWB64_CHROM_SWITCH;
+
+	reg_val |= (arg->ellip_unite & RKISP1_CIF_ISP_AWB64_UNITE_MASK)
+		   << RKISP1_CIF_ISP_AWB64_UNITE_SHIFT;
+
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_MEAS_MODE,
+		     reg_val);
+
+	/* Measurement window */
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_V_OFFS,
+		     arg->awb_wnd.v_offs);
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_H_OFFS,
+		     arg->awb_wnd.h_offs);
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_V_SIZE,
+		     arg->awb_wnd.v_size);
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_H_SIZE,
+		     arg->awb_wnd.h_size);
+
+	/* RGB thresholds for measurement */
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_R_MIN_MAX,
+		     arg->min_max_r);
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_G_MIN_MAX,
+		     arg->min_max_g);
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_B_MIN_MAX,
+		     arg->min_max_b);
+
+	/* Minimum input divider threshold */
+	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_MIN_DIVIDER,
+		     arg->min_div & RKISP1_CIF_ISP_AWB64_MIN_DIV_MASK);
+
+	/* Colorspace matrix coefficients */
+	for (int i = 0; i < 3; i++) {
+		for (int j = 0; j < 3; j++)
+			rkisp1_write(params->rkisp1,
+				     RKISP1_CIF_ISP_AWB64_CC_COEFF(i * 3 + j),
+				     arg->cc_coeff[i][j]);
+	}
+
+	/* Ellipse configuration */
+	for (int i = 0; i < RKISP1_CIF_ISP_AWB64_MAX_ELLIPSE; i++) {
+		const struct rkisp1_cif_isp_awb64_ellip *ellip = &arg->ellip[i];
+
+		/* Center */
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_CEN_X(i),
+			     ellip->cen_x & RKISP1_CIF_ISP_AWB64_ELLIP_CEN_MASK);
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_CEN_Y(i),
+			     ellip->cen_y & RKISP1_CIF_ISP_AWB64_ELLIP_CEN_MASK);
+		/* Radius */
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_RMAX(i),
+			     ellip->rmax & RKISP1_CIF_ISP_AWB64_ELLIP_RMAX_MASK);
+		/* CTM */
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_A1(i),
+			     ellip->ctm[0] &
+				     RKISP1_CIF_ISP_AWB64_ELLIP_A1_A3_MASK);
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_A2(i),
+			     ellip->ctm[1] &
+				     RKISP1_CIF_ISP_AWB64_ELLIP_A2_A4_MASK);
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_A3(i),
+			     ellip->ctm[2] &
+				     RKISP1_CIF_ISP_AWB64_ELLIP_A1_A3_MASK);
+		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_AWB64_ELLIP_A4(i),
+			     ellip->ctm[3] &
+				     RKISP1_CIF_ISP_AWB64_ELLIP_A2_A4_MASK);
+	}
+}
+
+static void
+rkisp1_awb64_meas_enable(struct rkisp1_params *params,
+			 const struct rkisp1_cif_isp_awb64_meas_config *arg,
+			 bool en)
+{
+	if (en) {
+		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AWB64_MEAS_MODE,
+				      RKISP1_CIF_ISP_AWB64_MEAS_EN |
+					      RKISP1_CIF_ISP_AWB64_IRQ_EN);
+	} else {
+		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AWB64_MEAS_MODE,
+					RKISP1_CIF_ISP_AWB64_MEAS_EN |
+						RKISP1_CIF_ISP_AWB64_IRQ_EN);
+	}
+}
+
 static void
 rkisp1_awb_gain_config_v10(struct rkisp1_params *params,
 			   const struct rkisp1_cif_isp_awb_gain_config *arg)
@@ -2092,6 +2192,23 @@ static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
 				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
 }
 
+static void rkisp1_ext_params_awb64(struct rkisp1_params *params,
+				    const union rkisp1_ext_params_config *block)
+{
+	const struct rkisp1_ext_params_awb64_meas_config *awb64 = &block->awb64;
+
+	if (awb64->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
+		rkisp1_awb64_meas_enable(params, &awb64->config, false);
+		return;
+	}
+
+	rkisp1_awb64_meas_config(params, &awb64->config);
+
+	if ((awb64->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
+	    !(params->enabled_blocks & BIT(awb64->header.type)))
+		rkisp1_awb64_meas_enable(params, &awb64->config, true);
+}
+
 typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
 			     const union rkisp1_ext_params_config *config);
 
@@ -2210,6 +2327,12 @@ static const struct rkisp1_ext_params_handler {
 		.handler	= rkisp1_ext_params_wdr,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
+	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB64_MEAS] = {
+		.size		= sizeof(struct rkisp1_ext_params_awb64_meas_config),
+		.handler	= rkisp1_ext_params_awb64,
+		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
+		.features	= RKISP1_FEATURE_AWB64,
+	},
 };
 
 static void rkisp1_ext_params_config(struct rkisp1_params *params,
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
index 31783617f39753a9b847b6612c9adf09c2ea8c99..14299ecc3a067d6711b86965e9acca31d29f9555 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
@@ -516,6 +516,24 @@
 #define RKISP1_CIF_ISP_AWB_CBCR_MAX_REF			0x000000ff
 #define RKISP1_CIF_ISP_AWB_THRES_MAX_YC			0x000000ff
 
+/* AWB64 */
+/* ISP_AWB64_WHITE_CNT */
+#define RKISP1_CIF_ISP_AWB64_GET_PIXEL_CNT(x)		((x) & 0xffffff)
+/* ISP_AWB64_MEAS_MODE */
+#define RKISP1_CIF_ISP_AWB64_MEAS_EN			BIT(0)
+#define RKISP1_CIF_ISP_AWB64_PRE_FILTER_EN		BIT(1)
+#define RKISP1_CIF_ISP_AWB64_IRQ_EN			BIT(2)
+#define RKISP1_CIF_ISP_AWB64_CHROM_SWITCH		BIT(3)
+#define RKISP1_CIF_ISP_AWB64_UNITE_MASK			GENMASK(5, 0)
+#define RKISP1_CIF_ISP_AWB64_UNITE_SHIFT		4
+/* ISP_AWB64_DIVIDER_MIN */
+#define RKISP1_CIF_ISP_AWB64_MIN_DIV_MASK		GENMASK(9, 0)
+/* ISP_AWB64_ELLIP */
+#define RKISP1_CIF_ISP_AWB64_ELLIP_CEN_MASK		GENMASK(9, 0)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A1_A3_MASK		GENMASK(11, 0)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A2_A4_MASK		GENMASK(8, 0)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_RMAX_MASK		GENMASK(23, 0)
+
 /* AE */
 /* ISP_EXP_CTRL */
 #define RKISP1_CIF_ISP_EXP_ENA				BIT(0)
@@ -1330,6 +1348,29 @@
 #define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
 #define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
 
+#define RKISP1_CIF_ISP_AWB64_BASE		0x00002c00
+#define RKISP1_CIF_ISP_AWB64_MEAS_MODE		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_AWB64_H_OFFS		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_AWB64_V_OFFS		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_AWB64_H_SIZE		(RKISP1_CIF_ISP_AWB64_BASE + 0x0000000c)
+#define RKISP1_CIF_ISP_AWB64_V_SIZE		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_AWB64_R_MIN_MAX		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_AWB64_G_MIN_MAX		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_AWB64_B_MIN_MAX		(RKISP1_CIF_ISP_AWB64_BASE + 0x0000001c)
+#define RKISP1_CIF_ISP_AWB64_MIN_DIVIDER	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_AWB64_CC_COEFF(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000024 + (n) * 4)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_CEN_X(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000048 + (n) * 8)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_CEN_Y(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x0000004c + (n) * 8)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A1(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000088 + (n) * 16)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A2(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x0000008c + (n) * 16)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A3(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000090 + (n) * 16)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_A4(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000094 + (n) * 16)
+#define RKISP1_CIF_ISP_AWB64_ELLIP_RMAX(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000108 + (n) * 4)
+#define RKISP1_CIF_ISP_AWB64_WHITE_CNT(n)	(RKISP1_CIF_ISP_AWB64_BASE + 0x00000128 + (n) * 4)
+#define RKISP1_CIF_ISP_AWB64_R_ACCU(n)		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000148 + (n) * 12)
+#define RKISP1_CIF_ISP_AWB64_G_ACCU(n)		(RKISP1_CIF_ISP_AWB64_BASE + 0x0000014c + (n) * 12)
+#define RKISP1_CIF_ISP_AWB64_B_ACCU(n)		(RKISP1_CIF_ISP_AWB64_BASE + 0x00000150 + (n) * 12)
+
 #define RKISP1_CIF_ISP_HIST_BASE_V12		0x00002c00
 #define RKISP1_CIF_ISP_HIST_CTRL_V12		(RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)
 #define RKISP1_CIF_ISP_HIST_SIZE_V12		(RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000004)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
index d5fdb8f82dc78b0143f71d76f36817db389921b7..de2571ac4c162a770b987e4ada469d2e8953ff7c 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
@@ -214,6 +214,38 @@ static void rkisp1_stats_get_awb_meas_v12(struct rkisp1_stats *stats,
 				RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
 }
 
+static void rkisp1_stats_get_awb64_meas_imx8mp(struct rkisp1_stats *stats,
+					       struct rkisp1_stat_buffer *pbuf)
+{
+	struct rkisp1_device *rkisp1 = stats->rkisp1;
+	u32 white_cnt;
+
+	pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB64;
+
+	for (unsigned int i = 0; i < RKISP1_CIF_ISP_AWB64_MAX_ELLIPSE; i++) {
+		struct rkisp1_cif_isp_awb64_meas *count =
+			&pbuf->params.awb64.count[i];
+
+		white_cnt = rkisp1_read(rkisp1,
+					RKISP1_CIF_ISP_AWB64_WHITE_CNT(i));
+		count->cnt = RKISP1_CIF_ISP_AWB64_GET_PIXEL_CNT(white_cnt);
+
+		count->accu_r =
+			rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB64_R_ACCU(i));
+		count->accu_g =
+			rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB64_G_ACCU(i));
+		count->accu_b =
+			rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB64_B_ACCU(i));
+	}
+}
+
+static void rkisp1_stats_get_awb_meas_imx8mp(struct rkisp1_stats *stats,
+					     struct rkisp1_stat_buffer *pbuf)
+{
+	rkisp1_stats_get_awb_meas_v10(stats, pbuf);
+	rkisp1_stats_get_awb64_meas_imx8mp(stats, pbuf);
+}
+
 static void rkisp1_stats_get_aec_meas_v10(struct rkisp1_stats *stats,
 					  struct rkisp1_stat_buffer *pbuf)
 {
@@ -335,6 +367,12 @@ static struct rkisp1_stats_ops rkisp1_v12_stats_ops = {
 	.get_hst_meas = rkisp1_stats_get_hst_meas_v12,
 };
 
+static const struct rkisp1_stats_ops rkisp1_imx8mp_stats_ops = {
+	.get_awb_meas = rkisp1_stats_get_awb_meas_imx8mp,
+	.get_aec_meas = rkisp1_stats_get_aec_meas_v10,
+	.get_hst_meas = rkisp1_stats_get_hst_meas_v10,
+};
+
 static void
 rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
 {
@@ -404,6 +442,8 @@ static void rkisp1_init_stats(struct rkisp1_stats *stats)
 
 	if (stats->rkisp1->info->isp_ver == RKISP1_V12)
 		stats->ops = &rkisp1_v12_stats_ops;
+	else if (stats->rkisp1->info->isp_ver == RKISP1_V_IMX8MP)
+		stats->ops = &rkisp1_imx8mp_stats_ops;
 	else
 		stats->ops = &rkisp1_v10_stats_ops;
 }
diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
index 78f4f350119bd29b2ac50cba2dd7cf3b0e4a8416..0e91a36b62387ad33a67b86ed2300c59720a80cc 100644
--- a/include/uapi/linux/rkisp1-config.h
+++ b/include/uapi/linux/rkisp1-config.h
@@ -88,6 +88,11 @@
 #define RKISP1_CIF_ISP_AWB_MAX_GRID                1
 #define RKISP1_CIF_ISP_AWB_MAX_FRAMES              7
 
+/*
+ * Automatic white balance extended block (AWB64)
+ */
+#define RKISP1_CIF_ISP_AWB64_MAX_ELLIPSE           8
+
 /*
  * Gamma out
  */
@@ -183,6 +188,7 @@
 #define RKISP1_CIF_ISP_STAT_AUTOEXP       (1U << 1)
 #define RKISP1_CIF_ISP_STAT_AFM           (1U << 2)
 #define RKISP1_CIF_ISP_STAT_HIST          (1U << 3)
+#define RKISP1_CIF_ISP_STAT_AWB64         (1U << 4)
 
 /**
  * enum rkisp1_cif_isp_version - ISP variants
@@ -526,6 +532,61 @@ struct rkisp1_cif_isp_awb_gain_config {
 	__u16 gain_green_b;
 };
 
+/**
+ * struct rkisp1_cif_isp_awb64_ellip - Ellipse configuration for AWB64 measurement
+ *
+ * @rmax: Points within rmax (24-bit) squared distance from center are
+ *        considered for white point calculations
+ * @cen_x: X coordinate of the center of ellipse, 10-bit signed fixed-point
+ *         number with 9 bits fractional part
+ * @cen_y: Y coordinate of the center of ellipse, 10-bit signed fixed-point
+ *         number with 9 bits fractional part
+ * @ctm: Coordinate transformation matrix,
+ *       ctm[0] and ctm[2] are 12-bit signed fixed-point with 8-bit fractional
+ *       part ranging from -8 (0x800) to 7.996 (0x7ff),
+ *       ctm[1] and ctm[3] are 9-bit signed fixed-point with 8-bit fractional
+ *       part ranging from -1 (0x100) to 0.996 (0x0ff)
+ */
+struct rkisp1_cif_isp_awb64_ellip {
+	__u32 rmax;
+	__u16 cen_x;
+	__u16 cen_y;
+	__u16 ctm[4];
+};
+
+/**
+ * struct rkisp1_cif_isp_awb64_meas_config - Configuration for the AWB64 stats
+ *
+ * @awb_wnd: White balance measurement window (in pixels)
+ * @ellip: Ellipse regions used for measurement
+ * @cc_coeff: Colorspace matrix (all coefficient values are 11-bit)
+ * @min_div: Minimum divider, if input is less than this don't do division
+ *           (unsigned 10-bit fixed-point value with 10 fractional bits)
+ * @min_max_r: Only pixels with min_r < R < max_r contribute to measurement,
+ *             bits 0:7 are min_r and bits 8:15 are max_r
+ * @min_max_g: Only pixels with min_g < G < max_g contribute to measurement,
+ *             bits 0:7 are min_g and bits 8:15 are max_g
+ * @min_max_b: Only pixels with min_b < B < max_b contribute to measurement,
+ *             bits 0:7 are min_b and bits 8:15 are max_b
+ * @enable_median_filter: Enable median filter before AWB measurement
+ * @ellip_unite: Bitmask to select which regions should be combined for measurement,
+ *               bits 0:2 to combine ellipse 0 with ellipse 1,2,3 and
+ *               bits 3:5 to combine ellipse 4 with ellipse 5,6,7
+ * @chrom_switch: Accumulate Q1, Q2 chromaticities instead of R, G, B
+ */
+struct rkisp1_cif_isp_awb64_meas_config {
+	struct rkisp1_cif_isp_window awb_wnd;
+	struct rkisp1_cif_isp_awb64_ellip ellip[RKISP1_CIF_ISP_AWB64_MAX_ELLIPSE];
+	__u16 cc_coeff[3][3];
+	__u16 min_div;
+	__u16 min_max_r;
+	__u16 min_max_g;
+	__u16 min_max_b;
+	__u8 enable_median_filter;
+	__u8 ellip_unite;
+	__u8 chrom_switch;
+};
+
 /**
  * struct rkisp1_cif_isp_flt_config - Configuration used by ISP filtering
  *
@@ -1088,6 +1149,31 @@ struct rkisp1_cif_isp_hist_stat {
 	__u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
 };
 
+/**
+ * struct rkisp1_cif_isp_awb64_meas - AWB64 measured values
+ *
+ * @cnt: White pixel count, number of "white pixels" found during last
+ *	 measurement
+ * @accu_r: Total value of Red within elliptical region
+ * @accu_g: Total value of Green within elliptical region
+ * @accu_b: Total value of Blue within elliptical region
+ */
+struct rkisp1_cif_isp_awb64_meas {
+	__u32 cnt;
+	__u32 accu_r;
+	__u32 accu_g;
+	__u32 accu_b;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb64_stat - statistics AWB64 data
+ *
+ * @count: Measured pixel accumulator data for elliptical regions
+ */
+struct rkisp1_cif_isp_awb64_stat {
+	struct rkisp1_cif_isp_awb64_meas count[RKISP1_CIF_ISP_AWB64_MAX_ELLIPSE];
+};
+
 /**
  * struct rkisp1_cif_isp_stat - Rockchip ISP1 Statistics Data
  *
@@ -1095,12 +1181,14 @@ struct rkisp1_cif_isp_hist_stat {
  * @ae: statistics data for auto exposure
  * @af: statistics data for auto focus
  * @hist: statistics histogram data
+ * @awb64: statistics data for automatic white balance 64
  */
 struct rkisp1_cif_isp_stat {
 	struct rkisp1_cif_isp_awb_stat awb;
 	struct rkisp1_cif_isp_ae_stat ae;
 	struct rkisp1_cif_isp_af_stat af;
 	struct rkisp1_cif_isp_hist_stat hist;
+	struct rkisp1_cif_isp_awb64_stat awb64;
 };
 
 /**
@@ -1142,6 +1230,7 @@ struct rkisp1_stat_buffer {
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve
  * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range
+ * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB64_MEAS: Auto white balance 64 statistics
  */
 enum rkisp1_ext_params_block_type {
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
@@ -1165,6 +1254,7 @@ enum rkisp1_ext_params_block_type {
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
+	RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB64_MEAS,
 };
 
 #define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
@@ -1460,6 +1550,23 @@ struct rkisp1_ext_params_awb_meas_config {
 	struct rkisp1_cif_isp_awb_meas_config config;
 } __attribute__((aligned(8)));
 
+/**
+ * struct rkisp1_ext_params_awb64_meas_config - RkISP1 extensible params AWB64
+ *						Meas config
+ *
+ * RkISP1 extensible parameters Auto-White Balance 64 Measurement configuration
+ * block. Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB64_MEAS`.
+ *
+ * @header: The RkISP1 extensible parameters header, see
+ *	    :c:type:`rkisp1_ext_params_block_header`
+ * @config: Auto-White Balance 64 measure configuration, see
+ *	    :c:type:`rkisp1_cif_isp_awb64_meas_config`
+ */
+struct rkisp1_ext_params_awb64_meas_config {
+	struct rkisp1_ext_params_block_header header;
+	struct rkisp1_cif_isp_awb64_meas_config config;
+} __attribute__((aligned(8)));
+
 /**
  * struct rkisp1_ext_params_hst_config - RkISP1 extensible params Histogram config
  *

-- 
2.48.1


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range
  2025-02-25 12:53 ` [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range Jai Luthra
@ 2025-04-10 15:51   ` Laurent Pinchart
  2025-04-11 13:20     ` Jai Luthra
  0 siblings, 1 reply; 5+ messages in thread
From: Laurent Pinchart @ 2025-04-10 15:51 UTC (permalink / raw)
  To: Jai Luthra
  Cc: Dafna Hirschfeld, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, linux-kernel,
	Stefan Klug

Hi Jai,

Thank you for the patch.

On Tue, Feb 25, 2025 at 06:23:04PM +0530, Jai Luthra wrote:
> RKISP supports a basic Wide Dynamic Range (WDR) module since the first
> iteration (v1.0) of the ISP. Add support for enabling and configuring it
> using extensible parameters.
> 
> Also, to ease programming, switch to using macro variables for defining
> the tonemapping curve register addresses.
> 
> Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
> ---
> New patch in v3
> ---
>  .../media/platform/rockchip/rkisp1/rkisp1-params.c |  92 +++++++++++++++++++
>  .../media/platform/rockchip/rkisp1/rkisp1-regs.h   |  99 +++++---------------
>  include/uapi/linux/rkisp1-config.h                 | 101 +++++++++++++++++++++
>  3 files changed, 218 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> index b28f4140c8a309a3231d44d825c6461e3ecb2a44..92a9aad79f6dca3c76d7692421827234e7f06390 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> @@ -60,6 +60,7 @@ union rkisp1_ext_params_config {
>  	struct rkisp1_ext_params_afc_config afc;
>  	struct rkisp1_ext_params_compand_bls_config compand_bls;
>  	struct rkisp1_ext_params_compand_curve_config compand_curve;
> +	struct rkisp1_ext_params_wdr_config wdr;
>  };
>  
>  enum rkisp1_params_formats {
> @@ -1348,6 +1349,73 @@ rkisp1_compand_compress_config(struct rkisp1_params *params,
>  				       arg->x);
>  }
>  
> +static void rkisp1_wdr_config(struct rkisp1_params *params,
> +			      const struct rkisp1_cif_isp_wdr_config *arg)
> +{
> +	unsigned int i;
> +	u32 value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL);
> +
> +	/* Colorspace and chrominance mapping */
> +	if (arg->use_rgb_colorspace)
> +		value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
> +	else
> +		value &= ~RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
> +
> +	if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
> +		value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
> +	else
> +		value &= ~RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
> +
> +	/* Illumination reference */
> +	if (arg->use_iref) {
> +		value = RKISP1_CIF_ISP_WDR_USE_IREF;

You likely meant |= here.

> +
> +		if (arg->iref_config.use_y9_8)
> +			value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;
> +		else
> +			value &= ~RKISP1_CIF_ISP_WDR_USE_Y9_8;
> +
> +		if (arg->iref_config.use_rgb7_8)
> +			value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;
> +		else
> +			value &= ~RKISP1_CIF_ISP_WDR_USE_RGB7_8;
> +
> +		if (arg->iref_config.disable_transient)
> +			value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
> +		else
> +			value &= ~RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
> +
> +		value |= min_t(u8, arg->iref_config.rgb_factor,
> +			       RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX)
> +			 << RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT;
> +	} else {
> +		value &= ~RKISP1_CIF_ISP_WDR_USE_IREF;
> +	}
> +
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);

I think you can simplify this a bit.

	value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL)
	      & ~(RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT |
	          RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE |
		  RKISP1_CIF_ISP_WDR_USE_IREF |
		  RKISP1_CIF_ISP_WDR_USE_Y9_8 |
		  RKISP1_CIF_ISP_WDR_USE_RGB7_8 |
		  RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT |
		  RKISP1_CIF_ISP_WDR_RGB_FACTOR_MASK

	/* Colorspace and chrominance mapping */
	if (arg->use_rgb_colorspace)
		value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;

	if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
		value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;

	/* Illumination reference */
	if (arg->use_iref) {
		value |= RKISP1_CIF_ISP_WDR_USE_IREF;

		if (arg->iref_config.use_y9_8)
			value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;

		if (arg->iref_config.use_rgb7_8)
			value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;

		if (arg->iref_config.disable_transient)
			value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;

		value |= min_t(u8, arg->iref_config.rgb_factor,
			       RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX)
			 << RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT;
	}

	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);

> +
> +	/* RGB and Luminance offsets */
> +	value = arg->rgb_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK;
> +	value |= (arg->luma_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK)
> +		 << RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT;
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);

To simplify the code here, I would define the following macros

#define RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK		GENMASK(11, 0)
#define RKISP1_CIF_ISP_WDR_RGB_OFFSET_SHIFT		0
#define RKISP1_CIF_ISP_WDR_RGB_OFFSET(n)		(((n) << RKISP1_CIF_ISP_WDR_RGB_OFFSET_SHIFT) & \
							 RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK)
#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK		GENMASK(27, 16)
#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT		16
#define RKISP1_CIF_ISP_WDR_LUM_OFFSET(n)		(((n) << RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT) & \
							 RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK)

and then write

	value = RKISP1_CIF_ISP_WDR_RGB_OFFSET(arg->rgb_offset)
	      | RKISP1_CIF_ISP_WDR_LUM_OFFSET(arg->luma_offset);
	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);

The macros could also be simplified to

#define RKISP1_CIF_ISP_WDR_RGB_OFFSET(n)		(((n) << 0) & GENMASK(11, 0))
#define RKISP1_CIF_ISP_WDR_LUM_OFFSET(n)		(((n) << 16) & GENMASK(27, 16))

or you could also use

#define RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK		GENMASK(11, 0)
#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK		GENMASK(27, 16)

	value = FIELD_PREP(RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK, arg->rgb_offset)
	      | FIELD_PREP(RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK, arg->luma_offset);

> +
> +	/* DeltaMin */
> +	value = arg->dmin_thresh & RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK;
> +	value |= min_t(u8, arg->dmin_strength,
> +		       RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX)
> +		 << RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT;
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_DELTAMIN, value);

Similar comment here, and actually also for
RKISP1_CIF_ISP_WDR_RGB_FACTOR above.

> +
> +	/* Tone curve */
> +	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS; i++)
> +		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE(i),
> +			     arg->tone_curve.dY[i]);
> +	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF; i++)
> +		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
> +			     arg->tone_curve.ym[i]);

		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
			     arg->tone_curve.ym[i] &
			     RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);

> +}
> +
>  static void
>  rkisp1_isp_isr_other_config(struct rkisp1_params *params,
>  			    const struct rkisp1_params_cfg *new_params)
> @@ -2005,6 +2073,25 @@ static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params,
>  				      RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);
>  }
>  
> +static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
> +				  const union rkisp1_ext_params_config *block)
> +{
> +	const struct rkisp1_ext_params_wdr_config *wdr = &block->wdr;
> +
> +	if (wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
> +		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
> +					RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
> +		return;
> +	}
> +
> +	rkisp1_wdr_config(params, &wdr->config);
> +
> +	if ((wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
> +	    !(params->enabled_blocks & BIT(wdr->header.type)))
> +		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
> +				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
> +}
> +
>  typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
>  			     const union rkisp1_ext_params_config *config);
>  
> @@ -2118,6 +2205,11 @@ static const struct rkisp1_ext_params_handler {
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  		.features	= RKISP1_FEATURE_COMPAND,
>  	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> +		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
> +		.handler	= rkisp1_ext_params_wdr,
> +		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> +	},
>  };
>  
>  static void rkisp1_ext_params_config(struct rkisp1_params *params,
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> index bf0260600a1923eebde6b5fe233daf7d427362dd..31783617f39753a9b847b6612c9adf09c2ea8c99 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> @@ -710,6 +710,27 @@
>  #define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG	BIT(2)
>  #define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE		BIT(3)
>  
> +/* WDR */
> +/* ISP_WDR_CTRL */
> +#define RKISP1_CIF_ISP_WDR_CTRL_ENABLE			BIT(0)
> +#define RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT		BIT(1)
> +#define RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE		BIT(2)
> +#define RKISP1_CIF_ISP_WDR_USE_IREF			BIT(3)
> +#define RKISP1_CIF_ISP_WDR_USE_Y9_8			BIT(4)
> +#define RKISP1_CIF_ISP_WDR_USE_RGB7_8			BIT(5)
> +#define RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT		BIT(6)
> +#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT		8
> +#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX		8

If you define this as

#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX		8U

you could replace min_t() with min() above. Same for
RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX.

> +/* ISP_WDR_TONE_CURVE_YM */
> +#define RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK		GENMASK(12, 0)
> +/* ISP_WDR_OFFSET */
> +#define RKISP1_CIF_ISP_WDR_OFFSET_MASK			GENMASK(11, 0)

This is confusing. You're using this for both the RGB and LUM offsets,
while here it looks like it maps to register bits, after shifting.

> +#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT		16
> +/* ISP_WDR_DELTAMIN */
> +#define RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK		GENMASK(11, 0)
> +#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX		0x10
> +#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT		16
> +
>  /* =================================================================== */
>  /*                            CIF Registers                            */
>  /* =================================================================== */
> @@ -1302,82 +1323,12 @@
>  
>  #define RKISP1_CIF_ISP_WDR_BASE			0x00002a00
>  #define RKISP1_CIF_ISP_WDR_CTRL			(RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_1		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_2		(RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_3		(RKISP1_CIF_ISP_WDR_BASE + 0x0000000c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_4		(RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1	(RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2	(RKISP1_CIF_ISP_WDR_BASE + 0x0000001c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3	(RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4	(RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5	(RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6	(RKISP1_CIF_ISP_WDR_BASE + 0x0000002c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7	(RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8	(RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9	(RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10	(RKISP1_CIF_ISP_WDR_BASE + 0x0000003c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11	(RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12	(RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13	(RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14	(RKISP1_CIF_ISP_WDR_BASE + 0x0000004c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15	(RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16	(RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17	(RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18	(RKISP1_CIF_ISP_WDR_BASE + 0x0000005c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19	(RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20	(RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21	(RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22	(RKISP1_CIF_ISP_WDR_BASE + 0x0000006c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23	(RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24	(RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25	(RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26	(RKISP1_CIF_ISP_WDR_BASE + 0x0000007c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27	(RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28	(RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29	(RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30	(RKISP1_CIF_ISP_WDR_BASE + 0x0000008c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31	(RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32	(RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
> +#define RKISP1_CIF_ISP_WDR_TONECURVE(n)		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004 + (n) * 4)
> +#define RKISP1_CIF_ISP_WDR_TONECURVE_YM(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014 + (n) * 4)
>  #define RKISP1_CIF_ISP_WDR_OFFSET		(RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
>  #define RKISP1_CIF_ISP_WDR_DELTAMIN		(RKISP1_CIF_ISP_WDR_BASE + 0x0000009c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ac)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000bc)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000cc)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000dc)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ec)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f0)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f4)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f8)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000fc)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000010c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000011c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000012c)
> -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
> +#define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
> +#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
>  
>  #define RKISP1_CIF_ISP_HIST_BASE_V12		0x00002c00
>  #define RKISP1_CIF_ISP_HIST_CTRL_V12		(RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)
> diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
> index 430daceafac7056951be968f3b4d9cd50eb04e71..78f4f350119bd29b2ac50cba2dd7cf3b0e4a8416 100644
> --- a/include/uapi/linux/rkisp1-config.h
> +++ b/include/uapi/linux/rkisp1-config.h
> @@ -169,6 +169,13 @@
>   */
>  #define RKISP1_CIF_ISP_COMPAND_NUM_POINTS	64
>  
> +/*
> + * Wide Dynamic Range
> + */
> +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV	32
> +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF	(RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV + 1)
> +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS	4
> +
>  /*
>   * Measurement types
>   */
> @@ -889,6 +896,81 @@ struct rkisp1_cif_isp_compand_curve_config {
>  	__u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
>  };
>  
> +/**
> + * struct rkisp1_cif_isp_wdr_tone_curve - Tone mapping curve definition for WDR.
> + *
> + * @dY: the dYn increments for horizontal (input) axis of the tone curve.
> + *      each 3-bit dY value represents an increment of 2**(value+3).
> + *      dY[0] bits 0:2 is increment dY1, bit 3 unused
> + *      dY[0] bits 4:6 is increment dY2, bit 7 unused
> + *      ...
> + *      dY[0] bits 28:30 is increment dY8, bit 31 unused
> + *      ... and so on till dY[3] bits 28:30 is increment dY32, bit 31 unused.
> + * @ym: the Ym values for the vertical (output) axis of the tone curve.
> + *      each value is 13 bit.
> + *
> + * The reset values define a linear curve which has the same effect as bypass:
> + *
> + * dY[0..3] = 0x44444444, This means that input sample range of 0-4096 is
> + * divided in 32 equal increments of 2**(4+3) = 128 units
> + *
> + * ym[0] = 0x0000, ym[1] = 0x0080, ... ym[31] = 0x0f80, ym[32] = 0x1000
> + * which increases by 0x80 = 128 units
> + *
> + */
> +struct rkisp1_cif_isp_wdr_tone_curve {
> +	__u32 dY[RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS];
> +	__u16 ym[RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF];
> +};
> +
> +/**
> + * struct rkisp1_cif_isp_wdr_iref_config - Illumination reference config for WDR.
> + *
> + * Use illumination reference value as described below, instead of only the
> + * luminance (Y) value for tone mapping and gain calculations:
> + * IRef = (rgb_factor * RGBMax_tr + (8 - rgb_factor) * Y)/8
> + *
> + * @rgb_factor: defines how much influence the RGBmax approach has in
> + *              comparison to Y (valid values are 0..8).
> + * @use_y9_8: use Y*9/8 for maximum value calculation along with the
> + *            default of R, G, B for noise reduction.
> + * @use_rgb7_8: decrease RGBMax by 7/8 for noise reduction.
> + * @disable_transient: disable transient calculation between Y and RGBY_max.
> + */
> +struct rkisp1_cif_isp_wdr_iref_config {
> +	__u8 rgb_factor;
> +	__u8 use_y9_8;
> +	__u8 use_rgb7_8;
> +	__u8 disable_transient;
> +};
> +
> +/**
> + * struct rkisp1_cif_isp_wdr_config - Configuration for wide dynamic range.
> + *
> + * @tone_curve: tone mapping curve.
> + * @iref_config: illumination reference configuration. (when use_iref is true)
> + * @rgb_offset: RGB offset value for RGB operation mode. (12 bits)
> + * @luma_offset: luminance offset value for RGB operation mode. (12 bits)
> + * @dmin_thresh: lower threshold for deltaMin value. (12 bits)
> + * @dmin_strength: strength factor for deltaMin. (valid range is 0x00..0x10)
> + * @use_rgb_colorspace: use RGB instead of luminance/chrominance colorspace.
> + * @bypass_chroma_mapping: disable chrominance mapping (only valid if
> + *                         use_rgb_colorspace = 0)
> + * @use_iref: use illumination reference instead of Y for tone mapping
> + *            and gain calculations.
> + */
> +struct rkisp1_cif_isp_wdr_config {
> +	struct rkisp1_cif_isp_wdr_tone_curve tone_curve;
> +	struct rkisp1_cif_isp_wdr_iref_config iref_config;
> +	__u16 rgb_offset;
> +	__u16 luma_offset;
> +	__u16 dmin_thresh;
> +	__u8 dmin_strength;
> +	__u8 use_rgb_colorspace;
> +	__u8 bypass_chroma_mapping;
> +	__u8 use_iref;
> +};
> +
>  /*---------- PART2: Measurement Statistics ------------*/
>  
>  /**
> @@ -1059,6 +1141,7 @@ struct rkisp1_stat_buffer {
>   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS: BLS in the compand block
>   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve
>   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve
> + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range
>   */
>  enum rkisp1_ext_params_block_type {
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
> @@ -1081,6 +1164,7 @@ enum rkisp1_ext_params_block_type {
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS,
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
> +	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
>  };
>  
>  #define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
> @@ -1460,6 +1544,23 @@ struct rkisp1_ext_params_compand_curve_config {
>  	struct rkisp1_cif_isp_compand_curve_config config;
>  } __attribute__((aligned(8)));
>  
> +/**
> + * struct rkisp1_ext_params_wdr_config - RkISP1 extensible params
> + *                                       Wide dynamic range config
> + *
> + * RkISP1 extensible parameters WDR block.
> + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR`
> + *
> + * @header: The RkISP1 extensible parameters header, see
> + *	    :c:type:`rkisp1_ext_params_block_header`
> + * @config: WDR configuration, see
> + *	    :c:type:`rkisp1_cif_isp_wdr_config`
> + */
> +struct rkisp1_ext_params_wdr_config {
> +	struct rkisp1_ext_params_block_header header;
> +	struct rkisp1_cif_isp_wdr_config config;
> +} __attribute__((aligned(8)));
> +
>  /*
>   * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
>   * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.

-- 
Regards,

Laurent Pinchart

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range
  2025-04-10 15:51   ` Laurent Pinchart
@ 2025-04-11 13:20     ` Jai Luthra
  0 siblings, 0 replies; 5+ messages in thread
From: Jai Luthra @ 2025-04-11 13:20 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Dafna Hirschfeld, Mauro Carvalho Chehab, Heiko Stuebner,
	linux-media, linux-rockchip, linux-arm-kernel, linux-kernel,
	Stefan Klug


[-- Attachment #1.1: Type: text/plain, Size: 24836 bytes --]

Hi Laurent,

On Apr 10, 2025 at 18:51:26 +0300, Laurent Pinchart wrote:
> Hi Jai,
> 
> Thank you for the patch.
> 
> On Tue, Feb 25, 2025 at 06:23:04PM +0530, Jai Luthra wrote:
> > RKISP supports a basic Wide Dynamic Range (WDR) module since the first
> > iteration (v1.0) of the ISP. Add support for enabling and configuring it
> > using extensible parameters.
> > 
> > Also, to ease programming, switch to using macro variables for defining
> > the tonemapping curve register addresses.
> > 
> > Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
> > ---
> > New patch in v3
> > ---
> >  .../media/platform/rockchip/rkisp1/rkisp1-params.c |  92 +++++++++++++++++++
> >  .../media/platform/rockchip/rkisp1/rkisp1-regs.h   |  99 +++++---------------
> >  include/uapi/linux/rkisp1-config.h                 | 101 +++++++++++++++++++++
> >  3 files changed, 218 insertions(+), 74 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > index b28f4140c8a309a3231d44d825c6461e3ecb2a44..92a9aad79f6dca3c76d7692421827234e7f06390 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > @@ -60,6 +60,7 @@ union rkisp1_ext_params_config {
> >  	struct rkisp1_ext_params_afc_config afc;
> >  	struct rkisp1_ext_params_compand_bls_config compand_bls;
> >  	struct rkisp1_ext_params_compand_curve_config compand_curve;
> > +	struct rkisp1_ext_params_wdr_config wdr;
> >  };
> >  
> >  enum rkisp1_params_formats {
> > @@ -1348,6 +1349,73 @@ rkisp1_compand_compress_config(struct rkisp1_params *params,
> >  				       arg->x);
> >  }
> >  
> > +static void rkisp1_wdr_config(struct rkisp1_params *params,
> > +			      const struct rkisp1_cif_isp_wdr_config *arg)
> > +{
> > +	unsigned int i;
> > +	u32 value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL);
> > +
> > +	/* Colorspace and chrominance mapping */
> > +	if (arg->use_rgb_colorspace)
> > +		value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
> > +	else
> > +		value &= ~RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
> > +
> > +	if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
> > +		value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
> > +	else
> > +		value &= ~RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
> > +
> > +	/* Illumination reference */
> > +	if (arg->use_iref) {
> > +		value = RKISP1_CIF_ISP_WDR_USE_IREF;
> 
> You likely meant |= here.
> 

Oops, will fix.

> > +
> > +		if (arg->iref_config.use_y9_8)
> > +			value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;
> > +		else
> > +			value &= ~RKISP1_CIF_ISP_WDR_USE_Y9_8;
> > +
> > +		if (arg->iref_config.use_rgb7_8)
> > +			value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;
> > +		else
> > +			value &= ~RKISP1_CIF_ISP_WDR_USE_RGB7_8;
> > +
> > +		if (arg->iref_config.disable_transient)
> > +			value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
> > +		else
> > +			value &= ~RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
> > +
> > +		value |= min_t(u8, arg->iref_config.rgb_factor,
> > +			       RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX)
> > +			 << RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT;
> > +	} else {
> > +		value &= ~RKISP1_CIF_ISP_WDR_USE_IREF;
> > +	}
> > +
> > +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);
> 
> I think you can simplify this a bit.
> 
> 	value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL)
> 	      & ~(RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT |
> 	          RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE |
> 		  RKISP1_CIF_ISP_WDR_USE_IREF |
> 		  RKISP1_CIF_ISP_WDR_USE_Y9_8 |
> 		  RKISP1_CIF_ISP_WDR_USE_RGB7_8 |
> 		  RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT |
> 		  RKISP1_CIF_ISP_WDR_RGB_FACTOR_MASK
> 
> 	/* Colorspace and chrominance mapping */
> 	if (arg->use_rgb_colorspace)
> 		value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
> 
> 	if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
> 		value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
> 
> 	/* Illumination reference */
> 	if (arg->use_iref) {
> 		value |= RKISP1_CIF_ISP_WDR_USE_IREF;
> 
> 		if (arg->iref_config.use_y9_8)
> 			value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;
> 
> 		if (arg->iref_config.use_rgb7_8)
> 			value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;
> 
> 		if (arg->iref_config.disable_transient)
> 			value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
> 
> 		value |= min_t(u8, arg->iref_config.rgb_factor,
> 			       RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX)
> 			 << RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT;
> 	}
> 
> 	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);
> 
> > +
> > +	/* RGB and Luminance offsets */
> > +	value = arg->rgb_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK;
> > +	value |= (arg->luma_offset & RKISP1_CIF_ISP_WDR_OFFSET_MASK)
> > +		 << RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT;
> > +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);
> 
> To simplify the code here, I would define the following macros
> 
> #define RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK		GENMASK(11, 0)
> #define RKISP1_CIF_ISP_WDR_RGB_OFFSET_SHIFT		0
> #define RKISP1_CIF_ISP_WDR_RGB_OFFSET(n)		(((n) << RKISP1_CIF_ISP_WDR_RGB_OFFSET_SHIFT) & \
> 							 RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK)
> #define RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK		GENMASK(27, 16)
> #define RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT		16
> #define RKISP1_CIF_ISP_WDR_LUM_OFFSET(n)		(((n) << RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT) & \
> 							 RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK)
> 
> and then write
> 
> 	value = RKISP1_CIF_ISP_WDR_RGB_OFFSET(arg->rgb_offset)
> 	      | RKISP1_CIF_ISP_WDR_LUM_OFFSET(arg->luma_offset);
> 	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);
> 
> The macros could also be simplified to
> 
> #define RKISP1_CIF_ISP_WDR_RGB_OFFSET(n)		(((n) << 0) & GENMASK(11, 0))
> #define RKISP1_CIF_ISP_WDR_LUM_OFFSET(n)		(((n) << 16) & GENMASK(27, 16))
> 
> or you could also use
> 
> #define RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK		GENMASK(11, 0)
> #define RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK		GENMASK(27, 16)
> 
> 	value = FIELD_PREP(RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK, arg->rgb_offset)
> 	      | FIELD_PREP(RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK, arg->luma_offset);
> 

I find the FIELD_PREP approach the best one, will fix in next revision 
along with other suggestions.

> > +
> > +	/* DeltaMin */
> > +	value = arg->dmin_thresh & RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK;
> > +	value |= min_t(u8, arg->dmin_strength,
> > +		       RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX)
> > +		 << RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT;
> > +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_DELTAMIN, value);
> 
> Similar comment here, and actually also for
> RKISP1_CIF_ISP_WDR_RGB_FACTOR above.
> 
> > +
> > +	/* Tone curve */
> > +	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS; i++)
> > +		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE(i),
> > +			     arg->tone_curve.dY[i]);
> > +	for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF; i++)
> > +		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
> > +			     arg->tone_curve.ym[i]);
> 
> 		rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
> 			     arg->tone_curve.ym[i] &
> 			     RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);
> 
> > +}
> > +
> >  static void
> >  rkisp1_isp_isr_other_config(struct rkisp1_params *params,
> >  			    const struct rkisp1_params_cfg *new_params)
> > @@ -2005,6 +2073,25 @@ static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params,
> >  				      RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);
> >  }
> >  
> > +static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
> > +				  const union rkisp1_ext_params_config *block)
> > +{
> > +	const struct rkisp1_ext_params_wdr_config *wdr = &block->wdr;
> > +
> > +	if (wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
> > +		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
> > +					RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
> > +		return;
> > +	}
> > +
> > +	rkisp1_wdr_config(params, &wdr->config);
> > +
> > +	if ((wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
> > +	    !(params->enabled_blocks & BIT(wdr->header.type)))
> > +		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
> > +				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
> > +}
> > +
> >  typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
> >  			     const union rkisp1_ext_params_config *config);
> >  
> > @@ -2118,6 +2205,11 @@ static const struct rkisp1_ext_params_handler {
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  		.features	= RKISP1_FEATURE_COMPAND,
> >  	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
> > +		.handler	= rkisp1_ext_params_wdr,
> > +		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> > +	},
> >  };
> >  
> >  static void rkisp1_ext_params_config(struct rkisp1_params *params,
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > index bf0260600a1923eebde6b5fe233daf7d427362dd..31783617f39753a9b847b6612c9adf09c2ea8c99 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > @@ -710,6 +710,27 @@
> >  #define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG	BIT(2)
> >  #define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE		BIT(3)
> >  
> > +/* WDR */
> > +/* ISP_WDR_CTRL */
> > +#define RKISP1_CIF_ISP_WDR_CTRL_ENABLE			BIT(0)
> > +#define RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT		BIT(1)
> > +#define RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE		BIT(2)
> > +#define RKISP1_CIF_ISP_WDR_USE_IREF			BIT(3)
> > +#define RKISP1_CIF_ISP_WDR_USE_Y9_8			BIT(4)
> > +#define RKISP1_CIF_ISP_WDR_USE_RGB7_8			BIT(5)
> > +#define RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT		BIT(6)
> > +#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_SHIFT		8
> > +#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX		8
> 
> If you define this as
> 
> #define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX		8U
> 
> you could replace min_t() with min() above. Same for
> RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX.
> 

Will do.

> > +/* ISP_WDR_TONE_CURVE_YM */
> > +#define RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK		GENMASK(12, 0)
> > +/* ISP_WDR_OFFSET */
> > +#define RKISP1_CIF_ISP_WDR_OFFSET_MASK			GENMASK(11, 0)
> 
> This is confusing. You're using this for both the RGB and LUM offsets,
> while here it looks like it maps to register bits, after shifting.
> 
> > +#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_SHIFT		16
> > +/* ISP_WDR_DELTAMIN */
> > +#define RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK		GENMASK(11, 0)
> > +#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX		0x10
> > +#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_SHIFT		16
> > +
> >  /* =================================================================== */
> >  /*                            CIF Registers                            */
> >  /* =================================================================== */
> > @@ -1302,82 +1323,12 @@
> >  
> >  #define RKISP1_CIF_ISP_WDR_BASE			0x00002a00
> >  #define RKISP1_CIF_ISP_WDR_CTRL			(RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_1		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_2		(RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_3		(RKISP1_CIF_ISP_WDR_BASE + 0x0000000c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_4		(RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1	(RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2	(RKISP1_CIF_ISP_WDR_BASE + 0x0000001c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3	(RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4	(RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5	(RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6	(RKISP1_CIF_ISP_WDR_BASE + 0x0000002c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7	(RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8	(RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9	(RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10	(RKISP1_CIF_ISP_WDR_BASE + 0x0000003c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11	(RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12	(RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13	(RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14	(RKISP1_CIF_ISP_WDR_BASE + 0x0000004c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15	(RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16	(RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17	(RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18	(RKISP1_CIF_ISP_WDR_BASE + 0x0000005c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19	(RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20	(RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21	(RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22	(RKISP1_CIF_ISP_WDR_BASE + 0x0000006c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23	(RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24	(RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25	(RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26	(RKISP1_CIF_ISP_WDR_BASE + 0x0000007c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27	(RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28	(RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29	(RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30	(RKISP1_CIF_ISP_WDR_BASE + 0x0000008c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31	(RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32	(RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
> > +#define RKISP1_CIF_ISP_WDR_TONECURVE(n)		(RKISP1_CIF_ISP_WDR_BASE + 0x00000004 + (n) * 4)
> > +#define RKISP1_CIF_ISP_WDR_TONECURVE_YM(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x00000014 + (n) * 4)
> >  #define RKISP1_CIF_ISP_WDR_OFFSET		(RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
> >  #define RKISP1_CIF_ISP_WDR_DELTAMIN		(RKISP1_CIF_ISP_WDR_BASE + 0x0000009c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ac)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000bc)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000c8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000cc)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000d8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000dc)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000e8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000ec)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f0)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f4)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000f8)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x000000fc)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000010c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000011c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x0000012c)
> > -#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD	(RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
> > +#define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
> > +#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n)	(RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
> >  
> >  #define RKISP1_CIF_ISP_HIST_BASE_V12		0x00002c00
> >  #define RKISP1_CIF_ISP_HIST_CTRL_V12		(RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)
> > diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
> > index 430daceafac7056951be968f3b4d9cd50eb04e71..78f4f350119bd29b2ac50cba2dd7cf3b0e4a8416 100644
> > --- a/include/uapi/linux/rkisp1-config.h
> > +++ b/include/uapi/linux/rkisp1-config.h
> > @@ -169,6 +169,13 @@
> >   */
> >  #define RKISP1_CIF_ISP_COMPAND_NUM_POINTS	64
> >  
> > +/*
> > + * Wide Dynamic Range
> > + */
> > +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV	32
> > +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF	(RKISP1_CIF_ISP_WDR_CURVE_NUM_INTERV + 1)
> > +#define RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS	4
> > +
> >  /*
> >   * Measurement types
> >   */
> > @@ -889,6 +896,81 @@ struct rkisp1_cif_isp_compand_curve_config {
> >  	__u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
> >  };
> >  
> > +/**
> > + * struct rkisp1_cif_isp_wdr_tone_curve - Tone mapping curve definition for WDR.
> > + *
> > + * @dY: the dYn increments for horizontal (input) axis of the tone curve.
> > + *      each 3-bit dY value represents an increment of 2**(value+3).
> > + *      dY[0] bits 0:2 is increment dY1, bit 3 unused
> > + *      dY[0] bits 4:6 is increment dY2, bit 7 unused
> > + *      ...
> > + *      dY[0] bits 28:30 is increment dY8, bit 31 unused
> > + *      ... and so on till dY[3] bits 28:30 is increment dY32, bit 31 unused.
> > + * @ym: the Ym values for the vertical (output) axis of the tone curve.
> > + *      each value is 13 bit.
> > + *
> > + * The reset values define a linear curve which has the same effect as bypass:
> > + *
> > + * dY[0..3] = 0x44444444, This means that input sample range of 0-4096 is
> > + * divided in 32 equal increments of 2**(4+3) = 128 units
> > + *
> > + * ym[0] = 0x0000, ym[1] = 0x0080, ... ym[31] = 0x0f80, ym[32] = 0x1000
> > + * which increases by 0x80 = 128 units
> > + *
> > + */
> > +struct rkisp1_cif_isp_wdr_tone_curve {
> > +	__u32 dY[RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS];
> > +	__u16 ym[RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF];
> > +};
> > +
> > +/**
> > + * struct rkisp1_cif_isp_wdr_iref_config - Illumination reference config for WDR.
> > + *
> > + * Use illumination reference value as described below, instead of only the
> > + * luminance (Y) value for tone mapping and gain calculations:
> > + * IRef = (rgb_factor * RGBMax_tr + (8 - rgb_factor) * Y)/8
> > + *
> > + * @rgb_factor: defines how much influence the RGBmax approach has in
> > + *              comparison to Y (valid values are 0..8).
> > + * @use_y9_8: use Y*9/8 for maximum value calculation along with the
> > + *            default of R, G, B for noise reduction.
> > + * @use_rgb7_8: decrease RGBMax by 7/8 for noise reduction.
> > + * @disable_transient: disable transient calculation between Y and RGBY_max.
> > + */
> > +struct rkisp1_cif_isp_wdr_iref_config {
> > +	__u8 rgb_factor;
> > +	__u8 use_y9_8;
> > +	__u8 use_rgb7_8;
> > +	__u8 disable_transient;
> > +};
> > +
> > +/**
> > + * struct rkisp1_cif_isp_wdr_config - Configuration for wide dynamic range.
> > + *
> > + * @tone_curve: tone mapping curve.
> > + * @iref_config: illumination reference configuration. (when use_iref is true)
> > + * @rgb_offset: RGB offset value for RGB operation mode. (12 bits)
> > + * @luma_offset: luminance offset value for RGB operation mode. (12 bits)
> > + * @dmin_thresh: lower threshold for deltaMin value. (12 bits)
> > + * @dmin_strength: strength factor for deltaMin. (valid range is 0x00..0x10)
> > + * @use_rgb_colorspace: use RGB instead of luminance/chrominance colorspace.
> > + * @bypass_chroma_mapping: disable chrominance mapping (only valid if
> > + *                         use_rgb_colorspace = 0)
> > + * @use_iref: use illumination reference instead of Y for tone mapping
> > + *            and gain calculations.
> > + */
> > +struct rkisp1_cif_isp_wdr_config {
> > +	struct rkisp1_cif_isp_wdr_tone_curve tone_curve;
> > +	struct rkisp1_cif_isp_wdr_iref_config iref_config;
> > +	__u16 rgb_offset;
> > +	__u16 luma_offset;
> > +	__u16 dmin_thresh;
> > +	__u8 dmin_strength;
> > +	__u8 use_rgb_colorspace;
> > +	__u8 bypass_chroma_mapping;
> > +	__u8 use_iref;
> > +};
> > +
> >  /*---------- PART2: Measurement Statistics ------------*/
> >  
> >  /**
> > @@ -1059,6 +1141,7 @@ struct rkisp1_stat_buffer {
> >   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS: BLS in the compand block
> >   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve
> >   * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve
> > + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range
> >   */
> >  enum rkisp1_ext_params_block_type {
> >  	RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
> > @@ -1081,6 +1164,7 @@ enum rkisp1_ext_params_block_type {
> >  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS,
> >  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
> >  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
> > +	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
> >  };
> >  
> >  #define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
> > @@ -1460,6 +1544,23 @@ struct rkisp1_ext_params_compand_curve_config {
> >  	struct rkisp1_cif_isp_compand_curve_config config;
> >  } __attribute__((aligned(8)));
> >  
> > +/**
> > + * struct rkisp1_ext_params_wdr_config - RkISP1 extensible params
> > + *                                       Wide dynamic range config
> > + *
> > + * RkISP1 extensible parameters WDR block.
> > + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR`
> > + *
> > + * @header: The RkISP1 extensible parameters header, see
> > + *	    :c:type:`rkisp1_ext_params_block_header`
> > + * @config: WDR configuration, see
> > + *	    :c:type:`rkisp1_cif_isp_wdr_config`
> > + */
> > +struct rkisp1_ext_params_wdr_config {
> > +	struct rkisp1_ext_params_block_header header;
> > +	struct rkisp1_cif_isp_wdr_config config;
> > +} __attribute__((aligned(8)));
> > +
> >  /*
> >   * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
> >   * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Thanks,
Jai

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-04-11 13:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-25 12:53 [PATCH v3 0/2] media: rockchip: rkisp1: Add support for WDR and AWB64 Jai Luthra
2025-02-25 12:53 ` [PATCH v3 1/2] media: rockchip: rkisp1: Add support for Wide Dynamic Range Jai Luthra
2025-04-10 15:51   ` Laurent Pinchart
2025-04-11 13:20     ` Jai Luthra
2025-02-25 12:53 ` [PATCH v3 2/2] media: rockchip: rkisp1: Add support for AWB64 Jai Luthra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox