Show a patch.

GET /api/1.1/patches/26089/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 26089,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/26089/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/26089/",
    "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": "<20260204203726.1820226-3-faizel.kb@gmail.com>",
    "date": "2026-02-04T20:37:25",
    "name": "[v3,2/3] media: vimc: sensor: Add pixel_rate, vblank and hblank configuration",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "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/26089/mbox/",
    "series": [
        {
            "id": 5771,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5771/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5771",
            "date": "2026-02-04T20:37:23",
            "name": "media: vimc: Add timing controls for fps config",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/5771/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/26089/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/26089/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 53833BD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  4 Feb 2026 20:38:15 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0133762048;\n\tWed,  4 Feb 2026 21:38:15 +0100 (CET)",
            "from mail-pl1-x630.google.com (mail-pl1-x630.google.com\n\t[IPv6:2607:f8b0:4864:20::630])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E526262043\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  4 Feb 2026 21:38:12 +0100 (CET)",
            "by mail-pl1-x630.google.com with SMTP id\n\td9443c01a7336-2a097cc08d5so572565ad.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 04 Feb 2026 12:38:12 -0800 (PST)",
            "from FAIZEL-KB.. ([2001:569:5999:dc00:876b:c389:85e5:7957])\n\tby smtp.googlemail.com with ESMTPSA id\n\td9443c01a7336-2a933974884sm31136955ad.83.2026.02.04.12.38.10\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 04 Feb 2026 12:38:10 -0800 (PST)"
        ],
        "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=\"i9ex0h32\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1770237491; x=1770842291;\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=+YiPQWXH9LfFe5Ipw86gccMFuVs2bYaP/flxUeZTgEw=;\n\tb=i9ex0h32t/IeSVCPcVS6hqEHj/1TdN+wC9B4qpNhaUr4ZABLqvrHDr+BetyOoV6cbD\n\t+jxwmqIDx8Mz5AlOGBO7EniQUsC7Cr07Jow4v9l8wvPhnQKJpVOLx019+epGeu9zhVAw\n\taLHy5J4o0lqVyb5bDWIUp0fC8DSfoW032HfURinei5ed9H+JwjiO3r1UZTM6US5+iEN0\n\tMqhQlEnbs5wmv0ytVUJ00kV7vnSOkf4EN7oDcdZNRfRNJx9WMuFA4zm5EFvYT5KQtjT9\n\th4flx5dbBwWQXmKZDeYm4ofe6INsnE5O9PnbwT8qJPV8Z8YnDbJeE1t4Ldm6mVaZl20E\n\tpTXw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1770237491; x=1770842291;\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=+YiPQWXH9LfFe5Ipw86gccMFuVs2bYaP/flxUeZTgEw=;\n\tb=w25ldTcKYLJajZZvrZn39lnemvnLwnOZkZEHAIR7ePgqnAK5etVe2cOO9pqHjss+H+\n\t7Nli+pwFOXj53AQzSt0sks1ry+iK9m7dvR9oa9G1MHWPnFOPC20PGJ7+h0xT1G7hCCGK\n\tQF/GSqtX17/U55TGfj2CttU299sNNApJuyRqGo4lUPJhQ7vr9xInYwN0XLtFt1QGqL2M\n\t1vKemu+iqvVV2Qw53QqG/b3VVTZHuf6L4HBpZMWmRe3EhFB0LV2xLDOUcYXGknt3j8ni\n\tS7+EAgCxXzi5WwotnGdezqxOVDaxJ5RRSvGVkJ0FiwyoumbtS9zqTA5MR598RlbeG9rJ\n\twF5g==",
        "X-Forwarded-Encrypted": "i=1;\n\tAJvYcCXzrnllGdbKJ6EdCtdG214x0DoMzH+Z81PME/mYlfBQUJ/AX2kYwXcFmEbQYlrqZSIr3EJd6QbgiFXBlqmifTQ=@lists.libcamera.org",
        "X-Gm-Message-State": "AOJu0Yx5bI3JWg0M7d2TbZaAHrzNBAaxJd18rQ3zYnz/DclbC4ftPZcV\n\thCnghJWY5MOBOyKQqerzfhrfU2GprFzoBt6t4YjhP/1q93NSXKfTvZjS",
        "X-Gm-Gg": "AZuq6aJam2F6Re42qJTH8T2cXrQLjQv0vUMa5Ma79ze7WCNR0V7nYPuvVhdQka6m8+H\n\t9VmDxgdg1nChDam8HnNetgRrK2PWM7Y+OLTkIdqHCrI+r9hDUm0sRj0aT3VQPBM+Vw3lUEqBBtU\n\tUwC0KD5CgkKFc0yiQM30zOOukHKlR1xWRqQ0fNseA2ZH5zih6ANwm22vwPtIV97ndgZeRllCtgA\n\tvkmbCHivcqgiqWuIVfCfbT/y50Kyvtz+Ie5gIL1bjp5p0kO/8yc7ovwNSAPWYq0jP8C1d/pDpM3\n\t+nJtBWMiEQkZK82IkLiaPEOvKKNrAzKnrxVSDCbMI7mJhaagqtTbkcTlCqQw/NOzcWLod0OPopm\n\tDj9UI5ZrEwhQk0JJJhDx6kqjx0eTIkn9VIB9wUM9LqzFBC8A6pLFBPf8DMmEuQCRJ2zUwm5cTtQ\n\tQ6t2sSSyWb8qAL8+mA1mn7REIuokzjRQR9Xaq/FKbwzIfL",
        "X-Received": "by 2002:a17:902:cf07:b0:29a:56a:8b81 with SMTP id\n\td9443c01a7336-2a93400b5c5mr30910985ad.8.1770237491410; \n\tWed, 04 Feb 2026 12:38:11 -0800 (PST)",
        "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 v3 2/3] media: vimc: sensor: Add pixel_rate,\n\tvblank and hblank configuration",
        "Date": "Wed,  4 Feb 2026 12:37:25 -0800",
        "Message-ID": "<20260204203726.1820226-3-faizel.kb@gmail.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260204203726.1820226-1-faizel.kb@gmail.com>",
        "References": "<20260204203726.1820226-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 2b07dc1f1278..6c3e6066eaa5 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": [
        "v3",
        "2/3"
    ]
}