From patchwork Thu Dec 26 07:49:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 853775 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (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 2A3B01CF7A1; Thu, 26 Dec 2024 07:50:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199441; cv=none; b=uKVExTV2InOxwepOM5FU3V7DHrujJVJ7uHBm+V70gNHdiRVnkcMLk25Zw16Uym3CGvv4poBigfMl3IFf8luJG/1eriB825PCozMsis8UVT3PQPrXm3soR2g8GD02LlmzoDJOqSiNVYSi+lEK0oBdF/SgzK1VEEH56nNaZGZoj8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199441; c=relaxed/simple; bh=gw6U2JG+YSx5CmmarPuDTvS/aLofbuq/YU0A8rIgCgU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RjtJcrkaaUZoAiQAiWhsTu0+0vvEMinB6BA3r3rMbd9UBEoLv9zpDrjh1beyc4oaKDFdkqVKDQc91AjcxaXAGA+pu6uAkyzSOl0uJYRQv4qofG/uVToSY4PzsfU3P68K/LcgJs+B/ACOG6g+Sx/10qb22PDGdZxOJywr8nEJ8BE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=JfjjWSTT; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JfjjWSTT" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:416f:6c:4037:639a:e90f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E232063F; Thu, 26 Dec 2024 08:49:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1735199395; bh=gw6U2JG+YSx5CmmarPuDTvS/aLofbuq/YU0A8rIgCgU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JfjjWSTTuNM+Jx4pVVRDS8/y5KHtSyQ4cMjsTzEBIaZIomKWrb3qzgM18RbSqC9+K J2FFvd/xXB3frNpDUxHG9ohjWM+hkDsu4ICV2oPAqnPkjcm0N4sz89ylh/7XiQ7CZu UQDyBI5hnS4Xw9YUNPw6gg1jUaZgZScS8moqr9oo= From: Jai Luthra Date: Thu, 26 Dec 2024 13:19:33 +0530 Subject: [PATCH v4 1/5] media: i2c: imx219: Correct the minimum vblanking value Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241226-imx219_fixes-v4-1-dd28383f06f7@ideasonboard.com> References: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> In-Reply-To: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jacopo Mondi , Laurent Pinchart , Jai Luthra , David Plowman X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1008; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=iw258IJ7itA4hKvQDhU7RsL6SbTVrRcFIMh4c4XZiEs=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnbQrCFrvodANxB+vbAZzh8V5rjtNa1tidBIJ47 /bXxAPMiZiJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ20KwgAKCRBD3pH5JJpx RderD/9H4+MkJrgYg+xmk8RjSxLSn43m0TKrfapi2fNNE31UzrEkX0QtB0Yjop0uBjl6WQmkt9w Y52BO/7xoUIYvwp+KaPj5NSyZI/s/bWZaCrxT3vT586hS2WRbLPRSgsX9Fmazl0CB1M0b+9syV6 1aqAXXJtEMbA3tGNxg/z/d3csn4qx266ArOO9R5QX9Sc8bU1UEOS2pLTwGtISctIg1/0wBOS5JS 4eMIWHrZq5OvcPw9PF3pUcvmkQeya+Auo08bP7UE5oWXP+8hWevOxsKRFAwJpW8OM37qfFYqB3d W+A0m9Mv3dvbwFECQlLcRS9sXPl7TtrzqvuEonCbo/cFSIHwffZ9TTM2haDGdl+EAl/mth+vRe/ PTwNbypjDawhEQjRfiO8X4ZDmbofP6zXRVHHWzoHJb4Yi7f5tCdV8RMeHB79HtqxT837NRUtZDG MTlgcPr2sJj2ykIDtEKfFV0O5TOUp2pv440jJVCYHjPBhTWx92T+dDQX/2X0DKaTZbcdN6B3kUy 8i20v4LR7yaxkdKWlC1tEQc8Gqf05/GfDRvIS/xTVQEZKepeoDS2Dg8YvySs5tP7ty3+lh8j9bR VSSDtD3PGpMYZXQVoZtIW0v0kwGmRxlOAx5kLmnAjkxnpQP6YuemOmIEi8VgcTpJfPRCcjujW31 43twZ2pmycyBSCw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: David Plowman The datasheet for this sensor documents the minimum vblanking as being 32 lines. It does fix some problems with occasional black lines at the bottom of images (tested on Raspberry Pi). Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi Reviewed-by: Dave Stevenson Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 2d54cea113e19f68e1553ffb2e4c78491dc80acf..0486bbc046cb9c36afd911eb799c1b010a01d496 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -73,7 +73,7 @@ #define IMX219_REG_VTS CCI_REG16(0x0160) #define IMX219_VTS_MAX 0xffff -#define IMX219_VBLANK_MIN 4 +#define IMX219_VBLANK_MIN 32 /* HBLANK control - read only */ #define IMX219_PPL_DEFAULT 3448 From patchwork Thu Dec 26 07:49:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 853774 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (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 7A627170A1A; Thu, 26 Dec 2024 07:50:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199453; cv=none; b=NTnji9qoMhNpc/8nEmNnmyZLceKvfjHSHJVX18/GUvp4NaImfn28/sdiw0xAUYhQv041mqU1wzwB02EyQZmEAfxX57dU3L9PaHy6YbUj+Q6px/KSQY/Jb5xdFjE5WHLhB17DVO8H425hMydJJHvr9JKY5HjOzzjNTsP7wVQDnOo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199453; c=relaxed/simple; bh=l8pRiF06P9+gNCp/60PThg5USXY2PQRXtqUeRkCzLVo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k5eBG+HXS/DzaIOl4oR6jS7VLUoHcp4xawKoeSe3wUx09ijFdcDV18feUJHkMmYvXLju6ZLEqP4jZUpKsrU0qKv53QGuS6l+EKWiR5YJir/W8gW0RXUG3T4sHlZb9UysRkWDpAIIBeQyv9O50bAjFF4PkpGpXBlDgqRc6gJ6hHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=etTOvFku; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="etTOvFku" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:416f:6c:4037:639a:e90f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BEF49FF; Thu, 26 Dec 2024 08:50:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1735199406; bh=l8pRiF06P9+gNCp/60PThg5USXY2PQRXtqUeRkCzLVo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=etTOvFkuz0dKB9KsU14nYmetMflol7N+LyEArq7uGct4PG6bKU289zaPdE64i3y2g EVLOJwdGDOLAloEhSioNXzYt4CZqsyYEW31t1/BX//+i2t9aqVNuGYYr4DgE+qUfGX apHcGjK0DT0tGvSv4kypKYvvquL/kD9DwO1mTWJI= From: Jai Luthra Date: Thu, 26 Dec 2024 13:19:35 +0530 Subject: [PATCH v4 3/5] media: i2c: imx219: make HBLANK r/w to allow longer exposures Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241226-imx219_fixes-v4-3-dd28383f06f7@ideasonboard.com> References: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> In-Reply-To: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jacopo Mondi , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5371; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=N/aj8QO3pgzkAlcQ85YfmhL0md4CJuiv8c96ULXE/+M=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnbQrCGTbYLw7l6a0fQP38j9ZicZf40Wfqsi/pA 0BL+ObzOoiJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ20KwgAKCRBD3pH5JJpx RWEKD/9vHWCVAUVIK6e+QYCb9O2VF2STxjW8xTceMFBrBcWG91n6bWXnmWWdM9TZ88snxgAW4Qh i8IYsWH1IiZa1wOjUEjriDfQi+NnSYaKcWxmsY6HRZiF0iG+tLZHMzwe6SW0YUZ+FrOiva/fm/V Ybbn9BvYysqvsEdsTvLkxRJ3GJ0mvvhihaVAylT5u2qVFRm0vlHkzu9IokXAt8DI6L1JiDk4E6H KJKUX0EZokRuSe5/j0wnst2QYWMu5wrj5zVfer5NDVOsUW2vDQd5faY2qPx2/DaONI38+2kwYgd wA1LKwrR0eUBJnkj+R/nUVJNByPKtw3+NcNZ+5EFOzez2nQLkT7c8PUFI0U+8MII4TggxJ4WMN4 QH8xLBuS8mneBJq5yUA/5hLiq7KiGo2R5kOXgIbPYOyhnx6OID317A82Sgx6BIjYNO76ShCcSVV J0SokngetzwXGvpFrRsjtWZ7FmpXsJSnyDNnSfzOWYmWDEdMIwt+cCoayaV7zV6qnuaTJ5GyElG XOeoG+e0jGkgTHxMikjN/IRQSIPzfN6tyZLi00TEijJMspqVaNjnykIHKbkyK54jj1bRTPOijL3 QT827qvt0i6aLw37aZnoZ57t7CvDGKIXOBpIgiI6IuQ/mP+JzdOTpX4UaRYyY4bodlIqrHVO7N+ vpRr7m+0xTwohoA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Dave Stevenson The HBLANK control was read-only, and always configured such that the sensor line length register was 3448. This limited the maximum exposure time that could be achieved to around 1.26 secs. Make HBLANK read/write so that the line time can be extended, and thereby allow longer exposures (and slower frame rates). Retain the overall line length setting when changing modes rather than resetting it to a default. Signed-off-by: Dave Stevenson Reviewed-by: Jacopo Mondi Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 49 +++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 6c4a72d88cdd2bdd05f2273786110c9f2818e44f..84681e5da3e238905139fe174e9ee3cfe5fa0246 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -73,11 +73,10 @@ #define IMX219_REG_FRM_LENGTH CCI_REG16(0x0160) #define IMX219_FLL_MAX 0xffff #define IMX219_VBLANK_MIN 32 +#define IMX219_REG_LINE_LENGTH CCI_REG16(0x0162) +#define IMX219_LLP_MIN 0x0d78 +#define IMX219_LLP_MAX 0x7ff0 -/* HBLANK control - read only */ -#define IMX219_PPL_DEFAULT 3448 - -#define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) #define IMX219_REG_X_ADD_END_A CCI_REG16(0x0166) #define IMX219_REG_Y_ADD_STA_A CCI_REG16(0x0168) @@ -191,7 +190,7 @@ static const struct cci_reg_sequence imx219_common_regs[] = { { CCI_REG8(0x479b), 0x0e }, /* Frame Bank Register Group "A" */ - { IMX219_REG_LINE_LENGTH_A, 3448 }, + { IMX219_REG_LINE_LENGTH, IMX219_LLP_MIN }, { IMX219_REG_X_ODD_INC_A, 1 }, { IMX219_REG_Y_ODD_INC_A, 1 }, @@ -420,6 +419,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) cci_write(imx219->regmap, IMX219_REG_FRM_LENGTH, format->height + ctrl->val, &ret); break; + case V4L2_CID_HBLANK: + cci_write(imx219->regmap, IMX219_REG_LINE_LENGTH, + format->width + ctrl->val, &ret); + break; case V4L2_CID_TEST_PATTERN_RED: cci_write(imx219->regmap, IMX219_REG_TESTP_RED, ctrl->val, &ret); @@ -465,7 +468,7 @@ static int imx219_init_controls(struct imx219 *imx219) const struct imx219_mode *mode = &supported_modes[0]; struct v4l2_ctrl_handler *ctrl_hdlr; struct v4l2_fwnode_device_properties props; - int exposure_max, exposure_def, hblank; + int exposure_max, exposure_def; int i, ret; ctrl_hdlr = &imx219->ctrl_handler; @@ -489,17 +492,16 @@ static int imx219_init_controls(struct imx219 *imx219) if (imx219->link_freq) imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; - /* Initial vblank/hblank/exposure parameters based on current mode */ + /* Initial blanking and exposure. Limits are updated during set_fmt */ imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_VBLANK, IMX219_VBLANK_MIN, IMX219_FLL_MAX - mode->height, 1, mode->vts_def - mode->height); - hblank = IMX219_PPL_DEFAULT - mode->width; imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HBLANK, hblank, hblank, - 1, hblank); - if (imx219->hblank) - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + V4L2_CID_HBLANK, + IMX219_LLP_MIN - mode->width, + IMX219_LLP_MAX - mode->width, 1, + IMX219_LLP_MIN - mode->width); exposure_max = mode->vts_def - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; @@ -815,6 +817,10 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; unsigned int bin_h, bin_v; + u32 prev_line_len; + + format = v4l2_subdev_state_get_format(state, 0); + prev_line_len = format->width + imx219->hblank->val; mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes), @@ -822,8 +828,6 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); - - format = v4l2_subdev_state_get_format(state, 0); *format = fmt->format; /* @@ -859,13 +863,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, exposure_max, imx219->exposure->step, exposure_def); /* - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank - * depends on mode->width only, and is not changeble in any - * way other than changing the mode. + * Retain PPL setting from previous mode so that the + * line time does not change on a mode change. + * Limits have to be recomputed as the controls define + * the blanking only, so PPL values need to have the + * mode width subtracted. */ - hblank = IMX219_PPL_DEFAULT - mode->width; - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, - hblank); + hblank = prev_line_len - mode->width; + __v4l2_ctrl_modify_range(imx219->hblank, + IMX219_LLP_MIN - mode->width, + IMX219_LLP_MAX - mode->width, 1, + IMX219_LLP_MIN - mode->width); + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); } return 0; From patchwork Thu Dec 26 07:49:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 853773 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (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 2E1611D151F; Thu, 26 Dec 2024 07:51:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199464; cv=none; b=SxonIs30G5RadYSmo2nAf8n956WLSugM+c859NW7a1W51w7ZMcCbaB1UkmKqN1IFFM6BD4QfEYWzC3n0aNe56jaH9xhOoyZ/sjwWBS6LMU8e5h+lfiopvU6lc+9xpWEw6x6ES0zS/Jsk88wT6bucJgYUdYsTnc9ZL5DpSma00yI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735199464; c=relaxed/simple; bh=rbDpw7jHnSgIIVqO7dHJG7GD0KrH66CyYFl2OAvPPpU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bp3g0+CfOAVzph5qzcVLE0orUPCT9asTdGBvdL9Qsqp0NzglguPaYaCRqIo6Qf5syOyu0lGC9M3IFhOU20SJHlZEYlRwP/gZEyn++DTQaKy4pq9GTMnW1yP7MwxinAqs7lunvyMzGivIXxozTmYOTIM5ecioQxVrxbVKYnpNQMs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=DP+cW6n+; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DP+cW6n+" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c68:416f:6c:4037:639a:e90f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7E9F89FF; Thu, 26 Dec 2024 08:50:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1735199417; bh=rbDpw7jHnSgIIVqO7dHJG7GD0KrH66CyYFl2OAvPPpU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=DP+cW6n+4QKb6i7c8hiou0nY0EWMUfmGmIdIfPbz644Qv6a2Lq7Axb8rqlOZDrbA6 kwjb1WdJtSOUDz/KgK3W1+TUTaIIqmrVEq+1eMVf/XA1aLExMgOolJUTIq2JqlRbVi 8MPP+azgnz8couRtRZ+z6UbmBOw+2NsIfTh3LWSU= From: Jai Luthra Date: Thu, 26 Dec 2024 13:19:37 +0530 Subject: [PATCH v4 5/5] media: i2c: imx219: Scale the pixel rate for analog binning Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241226-imx219_fixes-v4-5-dd28383f06f7@ideasonboard.com> References: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> In-Reply-To: <20241226-imx219_fixes-v4-0-dd28383f06f7@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jacopo Mondi , Laurent Pinchart , Jai Luthra , Naushir Patuck , Vinay Varma X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7108; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=rbDpw7jHnSgIIVqO7dHJG7GD0KrH66CyYFl2OAvPPpU=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnbQrD6hm/+J9hwmVx34cYRIxcjizuPR5xBL6RM lC2qbG6YeWJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ20KwwAKCRBD3pH5JJpx RcvGD/4uORxU0gzWQIEozJWm9Y9iiej13ziNhJ5JPzKtd0Vls+FBr0ilDFajV4t8pNVUTaovUoF 0n1gMNOk5kiCJvTCAJUnflWTT1jDJ33jTgf6z/2LC/8nXzvrJN4hx06NDq7Pdq88Wc4pJtWlDXd 09G7DmZ2wVvFIIei53xnYL0zOYrSPPvfvZbye7hccNMEzWfEiBdEaLNydBfrzaXPGUjkvRcjE6E R1+txZ422aLbu7K/7MfO9NLieFVYqpfk/nAkJMQvw2qfiZmnL1spONAmpfZ4SL10WBi18IJXcCo FnlHYcBaZDiT4tDPTa9Wdaf9ReqTJgTSdSIMgy6psA+cflZqyBQnki+C6XZ0yaGqdbwmRB5iG3Q r5njYnQI2Pk6maVdB+azBpUAhpi4J7PTL+Uxyy1nnuB6mff/C/eUUzx4a9jhQy4g80JPwwZ4uRQ NK5cgS6a4jnjIWzAcctH204QaRDu/Dsoh3hdtpu5ARBqWvxGj0CgAKty6AOfwYxNcUwaaIcwtnn khAYbFCy3yHlJW8Hb13LAvcYOk0U62pxSZJ54KtXGPS1HrbcLn1SPx/Ny+LOF4iZ25X/840patK jHzYmt6aKNwlvq82dVRQBbZO5kIXfKUIDS3uEV1q+m3iA8SnYaSRIZcB1HfGH13JdlL76sl0tjX PwqG96zOhWqmA5w== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 When the analog binning mode is used for high framerate operation, the pixel rate is effectively doubled. Account for this when setting up the pixel clock rate, and applying the vblank and exposure controls. The previous logic only used analog binning for RAW8, but normal binning limits the framerate on RAW10 480p [1]. So with this patch we switch to using special binning (with 2x pixel rate) wherever possible. [1]: https://github.com/raspberrypi/linux/issues/5493 Co-developed-by: Naushir Patuck Signed-off-by: Naushir Patuck Co-developed-by: Vinay Varma Signed-off-by: Vinay Varma Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 122 +++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 43 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index a8fcb7234c78b888cd7424629ced02cdc55a98fd..087ace42e5b6f27a2f7ff4980ed22f16aeafaede 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -144,6 +144,12 @@ #define IMX219_PIXEL_ARRAY_WIDTH 3280U #define IMX219_PIXEL_ARRAY_HEIGHT 2464U +enum binning_mode { + BINNING_NONE = IMX219_BINNING_NONE, + BINNING_X2 = IMX219_BINNING_X2, + BINNING_ANALOG_X2 = IMX219_BINNING_X2_ANALOG, +}; + /* Mode : resolution and related config&values */ struct imx219_mode { /* Frame width */ @@ -357,6 +363,59 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) return imx219_mbus_formats[i]; } +static u32 imx219_get_format_bpp(const struct v4l2_mbus_framefmt *format) +{ + switch (format->code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + return 8; + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + default: + return 10; + } +} + +static enum binning_mode imx219_get_binning(struct imx219 *imx219, u8 *bin_h, + u8 *bin_v) +{ + struct v4l2_subdev_state *state = + v4l2_subdev_get_locked_active_state(&imx219->sd); + const struct v4l2_mbus_framefmt *format = + v4l2_subdev_state_get_format(state, 0); + const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0); + + *bin_h = crop->width / format->width; + *bin_v = crop->height / format->height; + + if (*bin_h == 2 && *bin_v == 2) + return BINNING_ANALOG_X2; + else if (*bin_h == 2 || *bin_v == 2) + /* + * Don't use analog binning if only one dimension + * is binned, as it crops the other dimension + */ + return BINNING_X2; + else + return BINNING_NONE; +} + +static inline u32 imx219_get_rate_factor(struct imx219 *imx219) +{ + u8 bin_h, bin_v; + enum binning_mode binning = imx219_get_binning(imx219, &bin_h, &bin_v); + + if (binning == BINNING_ANALOG_X2) + return 2; + + return 1; +} + /* ----------------------------------------------------------------------------- * Controls */ @@ -368,10 +427,12 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); const struct v4l2_mbus_framefmt *format; struct v4l2_subdev_state *state; + u32 rate_factor; int ret = 0; state = v4l2_subdev_get_locked_active_state(&imx219->sd); format = v4l2_subdev_state_get_format(state, 0); + rate_factor = imx219_get_rate_factor(imx219); if (ctrl->id == V4L2_CID_VBLANK) { int exposure_max, exposure_def; @@ -400,7 +461,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_EXPOSURE: cci_write(imx219->regmap, IMX219_REG_EXPOSURE, - ctrl->val, &ret); + ctrl->val / rate_factor, &ret); break; case V4L2_CID_DIGITAL_GAIN: cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, @@ -417,7 +478,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: cci_write(imx219->regmap, IMX219_REG_FRM_LENGTH, - format->height + ctrl->val, &ret); + (format->height + ctrl->val) / rate_factor, &ret); break; case V4L2_CID_HBLANK: cci_write(imx219->regmap, IMX219_REG_LINE_LENGTH, @@ -588,29 +649,14 @@ static int imx219_set_framefmt(struct imx219 *imx219, { const struct v4l2_mbus_framefmt *format; const struct v4l2_rect *crop; - unsigned int bpp; - u64 bin_h, bin_v; + enum binning_mode binning; + u8 bin_h, bin_v; + u32 bpp; int ret = 0; format = v4l2_subdev_state_get_format(state, 0); crop = v4l2_subdev_state_get_crop(state, 0); - - switch (format->code) { - case MEDIA_BUS_FMT_SRGGB8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SGBRG8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - bpp = 8; - break; - - case MEDIA_BUS_FMT_SRGGB10_1X10: - case MEDIA_BUS_FMT_SGRBG10_1X10: - case MEDIA_BUS_FMT_SGBRG10_1X10: - case MEDIA_BUS_FMT_SBGGR10_1X10: - default: - bpp = 10; - break; - } + bpp = imx219_get_format_bpp(format); cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); @@ -621,28 +667,11 @@ static int imx219_set_framefmt(struct imx219 *imx219, cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); - switch (crop->width / format->width) { - case 1: - default: - bin_h = IMX219_BINNING_NONE; - break; - case 2: - bin_h = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; - break; - } - - switch (crop->height / format->height) { - case 1: - default: - bin_v = IMX219_BINNING_NONE; - break; - case 2: - bin_v = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; - break; - } - - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, bin_h, &ret); - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, bin_v, &ret); + binning = imx219_get_binning(imx219, &bin_h, &bin_v); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, + (bin_h == 2) ? binning : BINNING_NONE, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, + (bin_v == 2) ? binning : BINNING_NONE, &ret); cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, format->width, &ret); @@ -847,6 +876,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, int exposure_max; int exposure_def; int hblank; + int pixel_rate; /* Update limits and set FPS to default */ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, @@ -875,6 +905,12 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, IMX219_LLP_MAX - mode->width, 1, IMX219_LLP_MIN - mode->width); __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); + + /* Scale the pixel rate based on the mode specific factor */ + pixel_rate = imx219_get_pixel_rate(imx219) * + imx219_get_rate_factor(imx219); + __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate, + pixel_rate, 1, pixel_rate); } return 0;