From nobody Fri Oct 10 14:02:03 2025 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E85752DBF72; Tue, 17 Jun 2025 10:33:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750156422; cv=none; b=eaGDfLB8WEvMz2VoW7HftE/Jmjv7v4wSgdbh4+FPXug0qXK1Rulfxolrou3PgucWoFVJ8X1X6Eac8jtEAx8DwGGVuChkqvkZJvjBPteVbWt+M7fY8AtDmf9cjXk3uDcoZGBah2yGQtvuvpLuKNNhoYEMCXyMFxlFgV1+R3rsnAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750156422; c=relaxed/simple; bh=6PTgQpvQGYltb3w6qlrFeyDxk468gerGIIS2MnwSu7Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZjJSBxYzmMinowlho/NlcDITeg56pum15jd74riRmtW7IreSWvZDGs7LrZIzBkvECrPIq7ewbvHW/hzfbWjto5LkoDNz9AE2X2ovQczM4BKMp4cg59/GU9TQajqDFcYRWMgoRtiLqcJSjWRWz0KVkGERRDoEK4DJwLZ1HfGKu8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ragnatech.se; spf=pass smtp.mailfrom=ragnatech.se; dkim=pass (2048-bit key) header.d=ragnatech.se header.i=@ragnatech.se header.b=hntf5DKS; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=l/NLNJQs; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ragnatech.se Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ragnatech.se Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ragnatech.se header.i=@ragnatech.se header.b="hntf5DKS"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="l/NLNJQs" Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id DAE8B2540199; Tue, 17 Jun 2025 06:33:39 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Tue, 17 Jun 2025 06:33:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ragnatech.se; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm3; t=1750156419; x=1750242819; bh=tK6BnQ1KfAiJNgmED7Kjn7rSqblr+Y89tUXUFfhcy44=; b= hntf5DKSl+fpF2gc/wKx6tHvg9uZucdwMjzqXont7lbMb6ZuCh4SHf52G3TFQ4xx uMzUDYBiN+fXyjQtlJrMbEYSEdmCMviCx2UZv6liVgIlQqmJQ5hG5xRYCZlNv/vU 1hVxuna3VYVNgf0U0WRyxOdkGOwieKKWEImSXEUMWRTu3xprqq6YMEbOI9myW+Am ZNRxzdcw3rUl0QuZmc6syDavWCQCQbR/9nnnrUq7yUo6qGg2CZE7t/9RwPqrYYuy Z6a/Igpv8kafkVfDKRnm3fKOT4CzW3nSKLorDyz/peMPCUMWBmWpfJEep+5xsaj5 RfDHw6sevDSPS5TmbLbFqg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1750156419; x= 1750242819; bh=tK6BnQ1KfAiJNgmED7Kjn7rSqblr+Y89tUXUFfhcy44=; b=l /NLNJQsiAMLe0qwonrwttqrqUVnKfmyUhMAS2akBm1bm3GyyT2U8QFoN0tRcLAz9 2/JqW/mn8tmWD1eJypP+F8cwrkVmW7V0oGBmDJLke81wzQe/g7S+LyqmT9ZHUOVE AeBSf7XQZjKRIWpOdiFoo/TJGD/Kt6xVvvjkjLZAvL+7oUyqMGD7FpnXHJFAhg7Q W8rVyTKFsaj4roQG9V224QE4mc1EhWooglVZlx6lv9MFNd8U2UxHYzvyYn2OPo1O PP6X8ZfKctJjrqcEY5oybJU8OJNoJWPAJrqEuTQpD0C3/CM0kOHsssogzCFyZl2y tgqBSbCqaRvG27oIIwFqg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtddugddvledtfecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredt jeenucfhrhhomheppfhikhhlrghsucfunpguvghrlhhunhguuceonhhikhhlrghsrdhsoh guvghrlhhunhguodhrvghnvghsrghssehrrghgnhgrthgvtghhrdhsvgeqnecuggftrfgr thhtvghrnhepheeigfeuveeutdefhfehgeekvedtleeuueekveefudehhffhjeffgfegff elfeegnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhep nhhikhhlrghsrdhsohguvghrlhhunhgusehrrghgnhgrthgvtghhrdhsvgdpnhgspghrtg hpthhtohepjedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepmhgthhgvhhgrsges khgvrhhnvghlrdhorhhgpdhrtghpthhtohepjhgrtghophhordhmohhnughisehiuggvrg hsohhnsghorghrugdrtghomhdprhgtphhtthhopehlrghurhgvnhhtrdhpihhntghhrghr thesihguvggrshhonhgsohgrrhgurdgtohhmpdhrtghpthhtoheplhhinhhugidqmhgvug hirgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhrvghn vghsrghsqdhsohgtsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinh hugidqkhgvrhhnvghlsehvghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtohepnhhi khhlrghsrdhsohguvghrlhhunhguodhrvghnvghsrghssehrrghgnhgrthgvtghhrdhsvg X-ME-Proxy: Feedback-ID: i80c9496c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 17 Jun 2025 06:33:39 -0400 (EDT) From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= To: Mauro Carvalho Chehab , Jacopo Mondi , Laurent Pinchart , linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Subject: [PATCH 5/7] media: rppx1: Add support for Histogram Measurement Date: Tue, 17 Jun 2025 12:31:59 +0200 Message-ID: <20250617103201.1594152-6-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250617103201.1594152-1-niklas.soderlund+renesas@ragnatech.se> References: <20250617103201.1594152-1-niklas.soderlund+renesas@ragnatech.se> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Extend the RPPX1 driver to allow setting the Histogram configuration using the RkISP1 parameter buffer format. It uses the RPPX1 framework for parameters and its writer abstraction to allow the user to control how (and when) configuration is applied to the RPPX1. As the RkISP1 parameters buffer have lower precision then the RPPX1 hardware the values needs to be scaled. The behavior matches the RkISP1 hardware. Signed-off-by: Niklas S=C3=B6derlund --- .../platform/dreamchip/rppx1/rpp_params.c | 3 + .../platform/dreamchip/rppx1/rpp_stats.c | 4 + .../platform/dreamchip/rppx1/rppx1_hist.c | 173 ++++++++++++++++++ 3 files changed, 180 insertions(+) diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_params.c b/drivers/= media/platform/dreamchip/rppx1/rpp_params.c index deb88ff8b78b..5ab2e2a6bcbd 100644 --- a/drivers/media/platform/dreamchip/rppx1/rpp_params.c +++ b/drivers/media/platform/dreamchip/rppx1/rpp_params.c @@ -29,6 +29,9 @@ int rppx1_params_rkisp1(struct rppx1 *rpp, struct rkisp1_= ext_params_cfg *cfg, case RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS: module =3D &rpp->post.wbmeas; break; + case RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS: + module =3D &rpp->post.hist; + break; case RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS: module =3D &rpp->pre1.exm; break; diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_stats.c b/drivers/m= edia/platform/dreamchip/rppx1/rpp_stats.c index d62b26e24cb0..059bd76ecf64 100644 --- a/drivers/media/platform/dreamchip/rppx1/rpp_stats.c +++ b/drivers/media/platform/dreamchip/rppx1/rpp_stats.c @@ -16,6 +16,10 @@ void rppx1_stats_fill_isr(struct rppx1 *rpp, u32 isc, vo= id *buf) if (!rpp_module_call(&rpp->post.wbmeas, stats_rkisp1, &stats->params)) stats->meas_type |=3D RKISP1_CIF_ISP_STAT_AWB; =20 + if (isc & RPPX1_IRQ_ID_POST_HIST_MEAS) + if (!rpp_module_call(&rpp->post.hist, stats_rkisp1, &stats->params)) + stats->meas_type |=3D RKISP1_CIF_ISP_STAT_HIST; + if (isc & RPPX1_IRQ_ID_PRE1_EXM) if (!rpp_module_call(&rpp->pre1.exm, stats_rkisp1, &stats->params)) stats->meas_type |=3D RKISP1_CIF_ISP_STAT_AUTOEXP; diff --git a/drivers/media/platform/dreamchip/rppx1/rppx1_hist.c b/drivers/= media/platform/dreamchip/rppx1/rppx1_hist.c index cab498ece5a8..40ae8dc72b90 100644 --- a/drivers/media/platform/dreamchip/rppx1/rppx1_hist.c +++ b/drivers/media/platform/dreamchip/rppx1/rppx1_hist.c @@ -25,6 +25,9 @@ =20 #define HIST_LAST_MEAS_LINE_REG 0x0010 #define HIST_SUBSAMPLING_REG 0x0014 +#define HIST_SUBSAMPLING_V_STEPSIZE(x) (((x) & 0x7f) << 24) +#define HIST_SUBSAMPLING_H_STEP_INC(x) (((x) & 0x1ffff)) + #define HIST_COEFF_R_REG 0x0018 #define HIST_COEFF_G_REG 0x001c #define HIST_COEFF_B_REG 0x0020 @@ -71,6 +74,176 @@ static int rppx1_hist_probe(struct rpp_module *mod) return 0; } =20 +#define RPPX1_HIST_WEIGHT(v0, v1, v2, v3) \ + (((v0) & 0x1f) | (((v1) & 0x1f) << 8) | \ + (((v2) & 0x1f) << 16) | \ + (((v3) & 0x1f) << 24)) + +static int rppx1_hist_param_rkisp1(struct rpp_module *mod, + const union rppx1_params_rkisp1_config *block, + rppx1_reg_write write, void *priv) +{ + const struct rkisp1_ext_params_hst_config *cfg =3D &block->hst; + const struct rkisp1_cif_isp_hst_config *arg =3D &cfg->config; + u32 h_offs, v_offs, h_size, v_size; + u8 mode, coeff[3]; + + /* If the modules is disabled, simply bypass it. */ + if (cfg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { + write(priv, mod->base + HIST_MODE_REG, + HIST_MODE_HIST_MODE_DISABLE); + return 0; + } + + /* Sample after demosaicing. */ + write(priv, mod->base + HIST_CHANNEL_SEL_REG, 7); + + /* + * The RkISP1 histogram_predivider setting controls the pixel spacing + * between each sample. On RPPX1 there is greater control as both line + * and pixel spacing can be controlled. The RkISP1 stepsize register is + * documented as. + * + * 0, 1, 3: not allowed + * 3: process every third input pixel + * 4: process every fourth input pixel + * 127: process every 127th pixel + * + * The output bins are 16 bit (FP16.4) so to not overflow a divider + * calculated as would be needed. + * + * count =3D mode =3D=3D RGB_COMBINED ? 3 : 1 + * factor =3D vsize * hsize * count / 65536 + * + * However the libcamera user of the RkISP documents the setting as + * applying to both h and v direction at the same time and calculates + * the divider as, + * + * count =3D mode =3D=3D RGB_COMBINED ? 3 : 1 + * factor =3D ceil(sqrt(vsize * hsize * count / 65536)) + * + * Real world usage is better then bad documentation, do the same here + * and apply the divider in both directions. + * + * The RPPX1 h-stepping is also configured differently. Internally + * there is a 16-bit counter and for each input pixel h_step_inc is + * added to it. Every time it overflows the input pixel is sampled. + * + * h_step_inc =3D 2**16 =3D> sample every pixel + * h_step_inc =3D 2**15 =3D> sample every other pixel + * + * Gives us the conversion to RkISP1 parameters of. + * + * h_step_inc =3D 65536 / divider + */ + write(priv, mod->base + HIST_SUBSAMPLING_REG, + HIST_SUBSAMPLING_V_STEPSIZE(arg->histogram_predivider) | + HIST_SUBSAMPLING_H_STEP_INC(0x10000 / arg->histogram_predivider)); + + /* + * Adjust and set measurement window to hardware limitations, + * - Offsets must be even. + * - Width and height must be divisible by 10. + */ + h_offs =3D arg->meas_window.h_offs & 0x1ffe; + v_offs =3D arg->meas_window.v_offs & 0x1ffe; + h_size =3D arg->meas_window.h_size - arg->meas_window.h_size % 10; + v_size =3D arg->meas_window.v_size - arg->meas_window.v_size % 10; + + write(priv, mod->base + HIST_H_OFFS_REG, h_offs); + write(priv, mod->base + HIST_V_OFFS_REG, v_offs); + write(priv, mod->base + HIST_H_SIZE_REG, h_size / 5); + write(priv, mod->base + HIST_V_SIZE_REG, v_size / 5); + + /* Set last measurement line for ready interrupt. */ + write(priv, mod->base + HIST_LAST_MEAS_LINE_REG, + v_offs + v_size + 1); + + /* NOTE: Keep the default full sample range. */ + + /* Set measurement window weights. */ + write(priv, mod->base + HIST_WEIGHT_00TO30_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[0], arg->hist_weight[1], + arg->hist_weight[2], arg->hist_weight[3])); + write(priv, mod->base + HIST_WEIGHT_40TO21_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[4], arg->hist_weight[5], + arg->hist_weight[6], arg->hist_weight[7])); + write(priv, mod->base + HIST_WEIGHT_31TO12_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[8], arg->hist_weight[9], + arg->hist_weight[10], arg->hist_weight[11])); + write(priv, mod->base + HIST_WEIGHT_22TO03_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[12], arg->hist_weight[13], + arg->hist_weight[14], arg->hist_weight[15])); + write(priv, mod->base + HIST_WEIGHT_13TO43_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[16], arg->hist_weight[17], + arg->hist_weight[18], arg->hist_weight[19])); + write(priv, mod->base + HIST_WEIGHT_04TO34_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[20], arg->hist_weight[21], + arg->hist_weight[22], arg->hist_weight[23])); + write(priv, mod->base + HIST_WEIGHT_44_REG, + RPPX1_HIST_WEIGHT(arg->hist_weight[24], 0, 0, 0)); + + /* Translate RkISP1 modes. */ + mode =3D HIST_MODE_HIST_MODE_YRGB; + switch (arg->mode) { + case RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED: + /* L =3D R + G + B */ + coeff[0] =3D 0x80; + coeff[1] =3D 0x80; + coeff[2] =3D 0x80; + break; + case RKISP1_CIF_ISP_HISTOGRAM_MODE_R_HISTOGRAM: + /* L =3D R */ + coeff[0] =3D 0x80; + coeff[1] =3D 0x00; + coeff[2] =3D 0x00; + break; + case RKISP1_CIF_ISP_HISTOGRAM_MODE_G_HISTOGRAM: + /* L =3D G */ + coeff[0] =3D 0x00; + coeff[1] =3D 0x80; + coeff[2] =3D 0x00; + break; + case RKISP1_CIF_ISP_HISTOGRAM_MODE_B_HISTOGRAM: + coeff[0] =3D 0x00; + coeff[1] =3D 0x00; + coeff[2] =3D 0x80; + break; + case RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM: + /* Coefficients for a BT.601 (from datasheet). */ + coeff[0] =3D 38; + coeff[1] =3D 75; + coeff[2] =3D 15; + break; + default: + mode =3D HIST_MODE_HIST_MODE_DISABLE; + coeff[0] =3D 0x00; + coeff[1] =3D 0x00; + coeff[2] =3D 0x00; + break; + } + + write(priv, mod->base + HIST_MODE_REG, mode); + write(priv, mod->base + HIST_COEFF_R_REG, coeff[0]); + write(priv, mod->base + HIST_COEFF_G_REG, coeff[1]); + write(priv, mod->base + HIST_COEFF_B_REG, coeff[2]); + + write(priv, mod->base + HIST_FORCED_UPDATE_REG, 1); + + return 0; +} + +static int rppx1_hist_stats_rkisp1(struct rpp_module *mod, + struct rkisp1_cif_isp_stat *stats) +{ + for (unsigned int i =3D 0; i < HIST_BIN_REG_NUM; i++) + stats->hist.hist_bins[i] =3D rpp_module_read(mod, HIST_BIN_REG(i)) & 0xf= ffff; + + return 0; +} + const struct rpp_module_ops rppx1_hist_ops =3D { .probe =3D rppx1_hist_probe, + .param_rkisp1 =3D rppx1_hist_param_rkisp1, + .stats_rkisp1 =3D rppx1_hist_stats_rkisp1, }; --=20 2.49.0