Patch Detail
Show a patch.
GET /api/1.1/patches/26281/?format=api
{ "id": 26281, "url": "https://patchwork.libcamera.org/api/1.1/patches/26281/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26281/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260312231616.3590215-3-faizel.kb@gmail.com>", "date": "2026-03-12T23:16:15", "name": "[RESEND,v3,2/3] media: vimc: sensor: Add pixel_rate, vblank and hblank configuration", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f25383595aba87f6a9cd56b9c79bd6ffd179b774", "submitter": { "id": 258, "url": "https://patchwork.libcamera.org/api/1.1/people/258/?format=api", "name": "Faizel K B", "email": "faizel.kb@gmail.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/26281/mbox/", "series": [ { "id": 5828, "url": "https://patchwork.libcamera.org/api/1.1/series/5828/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5828", "date": "2026-03-12T23:16:13", "name": "media: vimc: Add timing controls for fps config", "version": 3, "mbox": "https://patchwork.libcamera.org/series/5828/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26281/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26281/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id EB0FFBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 12 Mar 2026 23:17:40 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8E1D262675;\n\tFri, 13 Mar 2026 00:17:40 +0100 (CET)", "from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com\n\t[IPv6:2607:f8b0:4864:20::1032])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A62F76261B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Mar 2026 00:17:39 +0100 (CET)", "by mail-pj1-x1032.google.com with SMTP id\n\t98e67ed59e1d1-3538952a464so139353a91.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 12 Mar 2026 16:17:39 -0700 (PDT)", "from FAIZEL-KB.. ([2001:569:5b64:e100:3685:315:53bf:61fc])\n\tby smtp.googlemail.com with ESMTPSA id\n\td9443c01a7336-2aece81cde8sm619395ad.70.2026.03.12.16.17.32\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 12 Mar 2026 16:17:37 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"buzgabCd\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1773357458; x=1773962258;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=dIaf3x8xjAlsrE68JYAsh8jSNNqCyGPC00OSVKpEMxc=;\n\tb=buzgabCd/ZDflvw7k/NSPm10S/SIs+T9+kNrSqNjIXGKyqYTRplOnGlR8mRKQOuZqR\n\t1XSxAouGZt3vSqJNnu6B2KrEpLAX37cVXY5SuXVygITxTpXqqw+iGeFijPIS4buRV2yL\n\tekeN9wV7izBc8SJhp5ANJhS4fn2CqYrhJ1dhNkyIlHOC4CyG0OpAEFwFOOZ5eFmRi/rP\n\tSe+Wut/7DUR2BclqH6RJXVl++sclLRjoUA6E1z+Dfi3RHqj6tbjuEs2scIQFpvRikHEP\n\tHq8njNC6Q1ojapufA61i7bHnUlFxVU1BVJ3D7kaUGQNqPDq39Aj24uUMqMcyEFNRorlj\n\tLFww==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1773357458; x=1773962258;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=dIaf3x8xjAlsrE68JYAsh8jSNNqCyGPC00OSVKpEMxc=;\n\tb=bTEDb/39FhJsE+Uojq+zfkpNn1itHZZxtJnuePhZLSnAp6KFbUfp4aHBi3yJy8HHW6\n\tfJmZAM8IZa4LrkKDfJL+Id+Bl7HB/SbMmhPO7ENVMGAvvGrauW6SUJNyzW3za4Op9cpT\n\t5lau6AcIKOt/g5rJkiPqJ9rO/yRroWkAmFHqh0lbVFNc1ax3zIcOiJ5TYRCZ/pHSeM6I\n\t2eFS3iMn/rxFnwQ6Fda8Ix0eME88qwrAuC1iYaV2xB+nfBUHuBaSXip557jO0PB/u38Z\n\teKlOA+dvv6giiakrI2lQuwxglCOzIAqz5ucV7dz8ewGscJhgfnd86lYimqJ4zvWkT5Er\n\tlnBQ==", "X-Forwarded-Encrypted": "i=1;\n\tAJvYcCVn/8s5Yv/64ts80r6HkQjyCf/lb0jq5oyyk6gazBrGim3UIe0WitqRx1gT/cVBtNJ+CvfVsX7TkWlyNIWHrDI=@lists.libcamera.org", "X-Gm-Message-State": "AOJu0YxToHhnuSp1ttqVgMoJLfboit5mAArBiIBkZ81fbjmnY7NgBIoz\n\twSH+0Wy6MxhWDhnyJvsBryEpXUM01ivjCEyXdNJLWjDifxdE2Q97Oiby", "X-Gm-Gg": "ATEYQzyLJuR5ZgThViJ5UTnPjW4YUOEtdeatLi+ZkQlMr8B28qDsYwm2XagNo1JwB+2\n\t4322f2W2hRcm1vXl+bAgP4DQ/rTvYkPsLe4jn9S5zncATwvXCugTDAiuvNvRBY3LrLX8wHSK16j\n\tfDf6ySTRXHhmjdUMtg63BTIfEQcPOZp2xkxoinCWo49yFRj+De6iUMm0W/kCpsjWGDzfFwEIpZr\n\t5JkxUCS/ECILKePExJWq3VD/K/vNL0glgg8ftpccGqqVwH8eyvjLj8rn2633jLke4ZKZ3B2Yc8d\n\t/YLlw7GFhH/t6sRPvDmi9Bz3xXw1A3wKHfBRxQizkydkm2qoQQ+gwIw3ePXRuLu/+NvJ/fKHiE/\n\tnLgo1mNOy8qm/pThCSp1zlSVlJ8x7OG9xYKdiQ6S6gxCu7SpdfkANpockU95vRLOmbPG/leUGft\n\trMyf0Iab/jv1P2cEEg+nFMMQhTUIaZNjDPELDEqzYubZMkySCV2gPfYQk=", "X-Received": "by 2002:a17:902:e810:b0:2ae:44dd:3377 with SMTP id\n\td9443c01a7336-2aeca90943bmr7406165ad.1.1773357458023; \n\tThu, 12 Mar 2026 16:17:38 -0700 (PDT)", "From": "Faizel K B <faizel.kb@gmail.com>", "To": "Shuah Khan <skhan@linuxfoundation.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlinux-media@vger.kernel.org", "Cc": "Mauro Carvalho Chehab <mchehab@kernel.org>,\n\tlibcamera-devel@lists.libcamera.org, Faizel K B <faizel.kb@gmail.com>", "Subject": "[PATCH RESEND v3 2/3] media: vimc: sensor: Add pixel_rate,\n\tvblank and hblank configuration", "Date": "Thu, 12 Mar 2026 16:16:15 -0700", "Message-ID": "<20260312231616.3590215-3-faizel.kb@gmail.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260312231616.3590215-1-faizel.kb@gmail.com>", "References": "<20260312231616.3590215-1-faizel.kb@gmail.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "pixel_rate and hblank as read only parameter. vblank can be configured\nto match the desired frame rate.\n\nDefault values are, pixel_rate - 160 MHz, hblank - 800.\nvblank defaults to an equivalent value of 30 fps for resolutions less than\nor equal to 1920x1080 and 10 fps for higher resolutions. For higher\nresolutions, modify pixel_rate in the driver code.\nfps = pixel_rate / ((width + hblank) * (height + vblank))\nminimum vblank - 4, maximum vblank - 65535\n\nThe configured fps delay is pre-calculated into jiffies and\nstored in the sensor's hw structure for efficient access by the\nstreamer thread.\n\nSigned-off-by: Faizel K B <faizel.kb@gmail.com>\n---\n drivers/media/test-drivers/vimc/vimc-common.h | 13 +++\n drivers/media/test-drivers/vimc/vimc-sensor.c | 88 +++++++++++++++++++\n 2 files changed, 101 insertions(+)", "diff": "diff --git a/drivers/media/test-drivers/vimc/vimc-common.h b/drivers/media/test-drivers/vimc/vimc-common.h\nindex 35789add6b4a..861b334ffc65 100644\n--- a/drivers/media/test-drivers/vimc/vimc-common.h\n+++ b/drivers/media/test-drivers/vimc/vimc-common.h\n@@ -29,6 +29,15 @@\n #define VIMC_FRAME_MIN_WIDTH 16\n #define VIMC_FRAME_MIN_HEIGHT 16\n \n+#define VIMC_PIXEL_RATE_FIXED\t\t160000000\t/* 160 MHz */\n+#define VIMC_HBLANK_FIXED\t\t800\n+/* VBLANK - vertical blanking (primary FPS control) */\n+#define VIMC_VBLANK_MIN\t\t\t4\n+#define VIMC_VBLANK_MAX\t\t\t65535\n+#define VIMC_VBLANK_STEP\t\t1\n+#define VIMC_VBLANK_DEFAULT\t 3223 /* 30fps vga */\n+#define VIMC_PIXELS_THRESHOLD_30FPS\t(1920 * 1080) /* 2073600 pixels */\n+\n #define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)\n \n /* Source and sink pad checks */\n@@ -173,6 +182,9 @@ struct vimc_sensor_device {\n \tstruct tpg_data tpg;\n \tstruct v4l2_ctrl_handler hdl;\n \tstruct media_pad pad;\n+\tstruct v4l2_ctrl *pixel_rate;\n+\tstruct v4l2_ctrl *hblank;\n+\tstruct v4l2_ctrl *vblank;\n \n \tu8 *frame;\n \n@@ -184,6 +196,7 @@ struct vimc_sensor_device {\n \t\tstruct v4l2_area size;\n \t\tenum vimc_sensor_osd_mode osd_value;\n \t\tu64 start_stream_ts;\n+\t\tunsigned long fps_jiffies;\n \t} hw;\n };\n \ndiff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c\nindex 4c64cdab8cda..5deebcc78a33 100644\n--- a/drivers/media/test-drivers/vimc/vimc-sensor.c\n+++ b/drivers/media/test-drivers/vimc/vimc-sensor.c\n@@ -25,10 +25,15 @@ static const struct v4l2_mbus_framefmt fmt_default = {\n static int vimc_sensor_init_state(struct v4l2_subdev *sd,\n \t\t\t\t struct v4l2_subdev_state *sd_state)\n {\n+\tstruct vimc_sensor_device *vsensor =\n+\t\tcontainer_of(sd, struct vimc_sensor_device, sd);\n+\n \tstruct v4l2_mbus_framefmt *mf;\n \n \tmf = v4l2_subdev_state_get_format(sd_state, 0);\n \t*mf = fmt_default;\n+\tvsensor->hw.size.width = fmt_default.width;\n+\tvsensor->hw.size.height = fmt_default.height;\n \n \treturn 0;\n }\n@@ -87,6 +92,26 @@ static void vimc_sensor_tpg_s_format(struct vimc_sensor_device *vsensor,\n \ttpg_s_xfer_func(&vsensor->tpg, format->xfer_func);\n }\n \n+static int vimc_sensor_update_frame_timing(struct v4l2_subdev *sd,\n+\t\t\t\t\t u32 width, u32 height)\n+{\n+\tstruct vimc_sensor_device *vsensor =\n+\t\tcontainer_of(sd, struct vimc_sensor_device, sd);\n+\tu64 pixel_rate = vsensor->pixel_rate->val;\n+\tu32 hts = width + vsensor->hblank->val;\n+\tu32 vts = height + vsensor->vblank->val;\n+\tu64 total_pixels = (u64)hts * vts;\n+\tu64 frame_interval_ns;\n+\n+\tframe_interval_ns = total_pixels * NSEC_PER_SEC;\n+\tdo_div(frame_interval_ns, pixel_rate);\n+\tvsensor->hw.fps_jiffies = nsecs_to_jiffies(frame_interval_ns);\n+\tif (vsensor->hw.fps_jiffies == 0)\n+\t\tvsensor->hw.fps_jiffies = 1;\n+\n+\treturn 0;\n+}\n+\n static void vimc_sensor_adjust_fmt(struct v4l2_mbus_framefmt *fmt)\n {\n \tconst struct vimc_pix_map *vpix;\n@@ -108,6 +133,24 @@ static void vimc_sensor_adjust_fmt(struct v4l2_mbus_framefmt *fmt)\n \tvimc_colorimetry_clamp(fmt);\n }\n \n+static u32 vimc_calc_vblank(u32 width, u32 height,\n+\t\t\t s64 pixel_rate, s32 hblank)\n+{\n+\tu32 hts = width + hblank;\n+\tu32 target_fps;\n+\tu64 vts;\n+\n+\ttarget_fps = (width * height <= VIMC_PIXELS_THRESHOLD_30FPS) ? 30 : 10;\n+\n+\tvts = (u64)pixel_rate;\n+\tdo_div(vts, target_fps * hts);\n+\n+\tif (vts > height)\n+\t\treturn clamp((u32)(vts - height), VIMC_VBLANK_MIN, VIMC_VBLANK_MAX);\n+\n+\treturn VIMC_VBLANK_MIN;\n+}\n+\n static int vimc_sensor_set_fmt(struct v4l2_subdev *sd,\n \t\t\t struct v4l2_subdev_state *sd_state,\n \t\t\t struct v4l2_subdev_format *fmt)\n@@ -137,6 +180,20 @@ static int vimc_sensor_set_fmt(struct v4l2_subdev *sd,\n \t\tfmt->format.xfer_func, fmt->format.ycbcr_enc);\n \n \t*mf = fmt->format;\n+\tif (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {\n+\t\tu32 vblank_def = vimc_calc_vblank(fmt->format.width,\n+\t\t\t\t\t\t fmt->format.height,\n+\t\t\t\t\t\t vsensor->pixel_rate->val,\n+\t\t\t\t\t\t vsensor->hblank->val);\n+\t\tvsensor->hw.size.width = fmt->format.width;\n+\t\tvsensor->hw.size.height = fmt->format.height;\n+\t\t__v4l2_ctrl_modify_range(vsensor->vblank,\n+\t\t\t\t\t VIMC_VBLANK_MIN,\n+\t\t\t\t\t VIMC_VBLANK_MAX,\n+\t\t\t\t\t VIMC_VBLANK_STEP,\n+\t\t\t\t\t vblank_def);\n+\t\t__v4l2_ctrl_s_ctrl(vsensor->vblank, vblank_def);\n+\t}\n \n \treturn 0;\n }\n@@ -222,6 +279,8 @@ static int vimc_sensor_s_stream(struct v4l2_subdev *sd, int enable)\n \n \t\tvsensor->hw.size.width = format->width;\n \t\tvsensor->hw.size.height = format->height;\n+\t\tvimc_sensor_update_frame_timing(sd, format->width,\n+\t\t\t\t\t\tformat->height);\n \n \t\tv4l2_subdev_unlock_state(state);\n \n@@ -293,6 +352,15 @@ static int vimc_sensor_s_ctrl(struct v4l2_ctrl *ctrl)\n \tcase VIMC_CID_OSD_TEXT_MODE:\n \t\tvsensor->hw.osd_value = ctrl->val;\n \t\tbreak;\n+\tcase V4L2_CID_PIXEL_RATE:\n+\t\tbreak;\n+\tcase V4L2_CID_HBLANK:\n+\t\tbreak;\n+\tcase V4L2_CID_VBLANK:\n+\t\tvimc_sensor_update_frame_timing(&vsensor->sd,\n+\t\t\t\t\t\tvsensor->hw.size.width,\n+\t\t\t\t\t\tvsensor->hw.size.height);\n+\t\tbreak;\n \tdefault:\n \t\treturn -EINVAL;\n \t}\n@@ -377,6 +445,26 @@ static struct vimc_ent_device *vimc_sensor_add(struct vimc_device *vimc,\n \t\t\t V4L2_CID_HUE, -128, 127, 1, 0);\n \tv4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,\n \t\t\t V4L2_CID_SATURATION, 0, 255, 1, 128);\n+\t/* Timing controls for frame interval configuration */\n+\tvsensor->pixel_rate = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,\n+\t\t\t\t\t\tV4L2_CID_PIXEL_RATE,\n+\t\t\t\t\t\tVIMC_PIXEL_RATE_FIXED, VIMC_PIXEL_RATE_FIXED,\n+\t\t\t\t\t\t1, VIMC_PIXEL_RATE_FIXED);\n+\tif (vsensor->pixel_rate)\n+\t\tvsensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;\n+\n+\tvsensor->hblank = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,\n+\t\t\t\t\t V4L2_CID_HBLANK,\n+\t\t\t\t\t VIMC_HBLANK_FIXED, VIMC_HBLANK_FIXED,\n+\t\t\t\t\t 1, VIMC_HBLANK_FIXED);\n+\tif (vsensor->hblank)\n+\t\tvsensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;\n+\n+\tvsensor->vblank = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,\n+\t\t\t\t\t V4L2_CID_VBLANK,\n+\t\t\t\t\t VIMC_VBLANK_MIN, VIMC_VBLANK_MAX,\n+\t\t\t\t\t VIMC_VBLANK_STEP, VIMC_VBLANK_DEFAULT);\n+\n \tvsensor->sd.ctrl_handler = &vsensor->hdl;\n \tif (vsensor->hdl.error) {\n \t\tret = vsensor->hdl.error;\n", "prefixes": [ "RESEND", "v3", "2/3" ] }