From patchwork Mon Oct 28 20:03:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13853998 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8808D3E2C7 for ; Mon, 28 Oct 2024 20:04:04 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web11.2544.1730145836643399470 for ; Mon, 28 Oct 2024 13:03:56 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219248" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:03:54 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 1867E408D216; Tue, 29 Oct 2024 05:03:52 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 01/27] media: i2c: ov5645: Drop fetching the clk reference by name Date: Mon, 28 Oct 2024 20:03:23 +0000 Message-ID: <20241028200349.9620-2-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:04 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17083 commit 9084e2c8617a63c478b48810ff7a8985de55f308 upstream. The OV5645 sensor has a single clock source, so just drop fetching the clk reference by name. This is in preparation to drop the "clock-names" property from the DT binding. Suggested-by: Laurent Pinchart Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index a6c17d15d7547..75baf5a67a691 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -1088,7 +1088,7 @@ static int ov5645_probe(struct i2c_client *client) } /* get system clock (xclk) */ - ov5645->xclk = devm_clk_get(dev, "xclk"); + ov5645->xclk = devm_clk_get(dev, NULL); if (IS_ERR(ov5645->xclk)) { dev_err(dev, "could not get xclk"); return PTR_ERR(ov5645->xclk); From patchwork Mon Oct 28 20:03:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13853997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D711DD3E2C6 for ; Mon, 28 Oct 2024 20:04:04 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2545.1730145837013840641 for ; Mon, 28 Oct 2024 13:03:57 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233415" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:03:56 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id E9602408D216; Tue, 29 Oct 2024 05:03:54 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 02/27] media: i2c: ov5645: Use runtime PM Date: Mon, 28 Oct 2024 20:03:24 +0000 Message-ID: <20241028200349.9620-3-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:04 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17084 commit b504503954c7c3741112d4260fbfc9214c66de9b upstream. Switch to using runtime PM for power management. Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 133 +++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 75baf5a67a691..d56f3197d6716 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,6 @@ struct ov5645 { u8 timing_tc_reg21; struct mutex power_lock; /* lock to protect power state */ - int power_count; struct gpio_desc *enable_gpio; struct gpio_desc *rst_gpio; @@ -635,8 +635,24 @@ static int ov5645_set_register_array(struct ov5645 *ov5645, return 0; } -static int ov5645_set_power_on(struct ov5645 *ov5645) +static int ov5645_set_power_off(struct device *dev) { + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov5645 *ov5645 = to_ov5645(sd); + + ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); + gpiod_set_value_cansleep(ov5645->rst_gpio, 1); + gpiod_set_value_cansleep(ov5645->enable_gpio, 0); + clk_disable_unprepare(ov5645->xclk); + regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); + + return 0; +} + +static int ov5645_set_power_on(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov5645 *ov5645 = to_ov5645(sd); int ret; ret = regulator_bulk_enable(OV5645_NUM_SUPPLIES, ov5645->supplies); @@ -658,57 +674,19 @@ static int ov5645_set_power_on(struct ov5645 *ov5645) msleep(20); - return 0; -} - -static void ov5645_set_power_off(struct ov5645 *ov5645) -{ - gpiod_set_value_cansleep(ov5645->rst_gpio, 1); - gpiod_set_value_cansleep(ov5645->enable_gpio, 0); - clk_disable_unprepare(ov5645->xclk); - regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); -} - -static int ov5645_s_power(struct v4l2_subdev *sd, int on) -{ - struct ov5645 *ov5645 = to_ov5645(sd); - int ret = 0; - - mutex_lock(&ov5645->power_lock); - - /* If the power count is modified from 0 to != 0 or from != 0 to 0, - * update the power state. - */ - if (ov5645->power_count == !on) { - if (on) { - ret = ov5645_set_power_on(ov5645); - if (ret < 0) - goto exit; - - ret = ov5645_set_register_array(ov5645, - ov5645_global_init_setting, + ret = ov5645_set_register_array(ov5645, ov5645_global_init_setting, ARRAY_SIZE(ov5645_global_init_setting)); - if (ret < 0) { - dev_err(ov5645->dev, - "could not set init registers\n"); - ov5645_set_power_off(ov5645); - goto exit; - } - - usleep_range(500, 1000); - } else { - ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); - ov5645_set_power_off(ov5645); - } + if (ret < 0) { + dev_err(ov5645->dev, "could not set init registers\n"); + goto exit; } - /* Update the power count. */ - ov5645->power_count += on ? 1 : -1; - WARN_ON(ov5645->power_count < 0); + usleep_range(500, 1000); -exit: - mutex_unlock(&ov5645->power_lock); + return 0; +exit: + ov5645_set_power_off(dev); return ret; } @@ -795,7 +773,7 @@ static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl) int ret; mutex_lock(&ov5645->power_lock); - if (!ov5645->power_count) { + if (!pm_runtime_get_if_in_use(ov5645->dev)) { mutex_unlock(&ov5645->power_lock); return 0; } @@ -827,6 +805,8 @@ static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl) break; } + pm_runtime_mark_last_busy(ov5645->dev); + pm_runtime_put_autosuspend(ov5645->dev); mutex_unlock(&ov5645->power_lock); return ret; @@ -989,6 +969,10 @@ static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable) int ret; if (enable) { + ret = pm_runtime_resume_and_get(ov5645->dev); + if (ret < 0) + return ret; + ret = ov5645_set_register_array(ov5645, ov5645->current_mode->data, ov5645->current_mode->data_size); @@ -996,22 +980,22 @@ static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable) dev_err(ov5645->dev, "could not set mode %dx%d\n", ov5645->current_mode->width, ov5645->current_mode->height); - return ret; + goto err_rpm_put; } ret = v4l2_ctrl_handler_setup(&ov5645->ctrls); if (ret < 0) { dev_err(ov5645->dev, "could not sync v4l2 controls\n"); - return ret; + goto err_rpm_put; } ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45); if (ret < 0) - return ret; + goto err_rpm_put; ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0, OV5645_SYSTEM_CTRL0_START); if (ret < 0) - return ret; + goto err_rpm_put; } else { ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40); if (ret < 0) @@ -1021,14 +1005,17 @@ static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable) OV5645_SYSTEM_CTRL0_STOP); if (ret < 0) return ret; + + pm_runtime_mark_last_busy(ov5645->dev); + pm_runtime_put_autosuspend(ov5645->dev); } return 0; -} -static const struct v4l2_subdev_core_ops ov5645_core_ops = { - .s_power = ov5645_s_power, -}; +err_rpm_put: + pm_runtime_put_sync(ov5645->dev); + return ret; +} static const struct v4l2_subdev_video_ops ov5645_video_ops = { .s_stream = ov5645_s_stream, @@ -1044,7 +1031,6 @@ static const struct v4l2_subdev_pad_ops ov5645_subdev_pad_ops = { }; static const struct v4l2_subdev_ops ov5645_subdev_ops = { - .core = &ov5645_core_ops, .video = &ov5645_video_ops, .pad = &ov5645_subdev_pad_ops, }; @@ -1186,11 +1172,9 @@ static int ov5645_probe(struct i2c_client *client) goto free_ctrl; } - ret = ov5645_s_power(&ov5645->sd, true); - if (ret < 0) { - dev_err(dev, "could not power up OV5645\n"); + ret = ov5645_set_power_on(dev); + if (ret) goto free_entity; - } ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high); if (ret < 0 || chip_id_high != OV5645_CHIP_ID_HIGH_BYTE) { @@ -1231,20 +1215,30 @@ static int ov5645_probe(struct i2c_client *client) goto power_down; } - ov5645_s_power(&ov5645->sd, false); + pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); + pm_runtime_enable(dev); ret = v4l2_async_register_subdev(&ov5645->sd); if (ret < 0) { dev_err(dev, "could not register v4l2 device\n"); - goto free_entity; + goto err_pm_runtime; } + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + ov5645_entity_init_cfg(&ov5645->sd, NULL); return 0; +err_pm_runtime: + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); power_down: - ov5645_s_power(&ov5645->sd, false); + ov5645_set_power_off(dev); free_entity: media_entity_cleanup(&ov5645->sd.entity); free_ctrl: @@ -1262,6 +1256,10 @@ static int ov5645_remove(struct i2c_client *client) v4l2_async_unregister_subdev(&ov5645->sd); media_entity_cleanup(&ov5645->sd.entity); v4l2_ctrl_handler_free(&ov5645->ctrls); + pm_runtime_disable(ov5645->dev); + if (!pm_runtime_status_suspended(ov5645->dev)) + ov5645_set_power_off(ov5645->dev); + pm_runtime_set_suspended(ov5645->dev); mutex_destroy(&ov5645->power_lock); return 0; @@ -1279,10 +1277,15 @@ static const struct of_device_id ov5645_of_match[] = { }; MODULE_DEVICE_TABLE(of, ov5645_of_match); +static const struct dev_pm_ops ov5645_pm_ops = { + SET_RUNTIME_PM_OPS(ov5645_set_power_off, ov5645_set_power_on, NULL) +}; + static struct i2c_driver ov5645_i2c_driver = { .driver = { .of_match_table = of_match_ptr(ov5645_of_match), .name = "ov5645", + .pm = &ov5645_pm_ops, }, .probe_new = ov5645_probe, .remove = ov5645_remove, From patchwork Mon Oct 28 20:03:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854000 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3DD2D3E2C8 for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2529.1730145845810430532 for ; Mon, 28 Oct 2024 13:04:06 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233423" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:05 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id CC020408CD26; Tue, 29 Oct 2024 05:03:56 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 03/27] media: i2c: ov5645: Drop empty comment Date: Mon, 28 Oct 2024 20:03:25 +0000 Message-ID: <20241028200349.9620-4-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17086 commit 9a018670dfa06b44efac08793b82a167d8a167ff upstream. Drop empty multiline comment. Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index d56f3197d6716..a5b6719c4dacb 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -14,9 +14,6 @@ * https://www.mail-archive.com/linux-media%40vger.kernel.org/msg92671.html */ -/* - */ - #include #include #include From patchwork Mon Oct 28 20:03:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854001 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8BA9D3E2CE for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2529.1730145845810430532 for ; Mon, 28 Oct 2024 13:04:06 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233426" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:05 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id A8DF7408D1FF; Tue, 29 Oct 2024 05:03:58 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 04/27] media: i2c: ov5645: Make sure to call PM functions Date: Mon, 28 Oct 2024 20:03:26 +0000 Message-ID: <20241028200349.9620-5-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17088 commit d781dce66df8e203c6593eaa855ce6843d69819d upstream. Make sure we call the PM functions while s_stream(0) even in case of errors in the code flow. v4l2-core takes care of warning the user so no need to add a warning message in the driver. Suggested-by: Sakari Ailus Signed-off-by: Lad Prabhakar Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index a5b6719c4dacb..7c49b169781d7 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -996,15 +996,12 @@ static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable) } else { ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40); if (ret < 0) - return ret; + goto stream_off_rpm_put; ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0, OV5645_SYSTEM_CTRL0_STOP); - if (ret < 0) - return ret; - pm_runtime_mark_last_busy(ov5645->dev); - pm_runtime_put_autosuspend(ov5645->dev); + goto stream_off_rpm_put; } return 0; @@ -1012,6 +1009,11 @@ static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable) err_rpm_put: pm_runtime_put_sync(ov5645->dev); return ret; + +stream_off_rpm_put: + pm_runtime_mark_last_busy(ov5645->dev); + pm_runtime_put_autosuspend(ov5645->dev); + return ret; } static const struct v4l2_subdev_video_ops ov5645_video_ops = { From patchwork Mon Oct 28 20:03:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854004 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BADAFD3E2C2 for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2529.1730145845810430532 for ; Mon, 28 Oct 2024 13:04:07 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233430" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:05 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 877A3408D425; Tue, 29 Oct 2024 05:04:00 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 05/27] media: i2c: ov5645: Call ov5645_entity_init_cfg() before registering the subdev Date: Mon, 28 Oct 2024 20:03:27 +0000 Message-ID: <20241028200349.9620-6-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17090 commit 87fab0eb25e98a2daa5824aff1adb05848332a9f upstream. Make sure we call ov5645_entity_init_cfg() before registering the subdev to make sure default formats are set up. Suggested-by: Sakari Ailus Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 7c49b169781d7..40e15a573964f 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -1218,6 +1218,8 @@ static int ov5645_probe(struct i2c_client *client) pm_runtime_get_noresume(dev); pm_runtime_enable(dev); + ov5645_entity_init_cfg(&ov5645->sd, NULL); + ret = v4l2_async_register_subdev(&ov5645->sd); if (ret < 0) { dev_err(dev, "could not register v4l2 device\n"); @@ -1229,8 +1231,6 @@ static int ov5645_probe(struct i2c_client *client) pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); - ov5645_entity_init_cfg(&ov5645->sd, NULL); - return 0; err_pm_runtime: From patchwork Mon Oct 28 20:03:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8AE8D3E2CB for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2530.1730145845815967010 for ; Mon, 28 Oct 2024 13:04:06 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219264" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:05 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 670E9408CD3A; Tue, 29 Oct 2024 05:04:02 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 06/27] media: i2c: ov5645: Remove software reset entry from ov5645_global_init_setting Date: Mon, 28 Oct 2024 20:03:28 +0000 Message-ID: <20241028200349.9620-7-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17087 From: Biju Das commit 25a3c0c7d0221465da5d89f9b6551a26ac12f9fd upstream. The SYSTEM_CTRL0 register in ov5645 is almost similar to ov5640. But the hard reset control is mandatory for the ov5645 device, so there is no need for soft reset in the driver. Add a 1msec delay for the software power up (OV5645_SYSTEM_CTRL0_START) register in ov5645_global_init_setting. Without this delay sometimes the image is not captured at all when the i2c frequency is 400kHz. The changes are fixing both the greenish issue and image capture at 400kHz i2c frequency on Renesas RZ/G2L SMARC EVK platforms. Signed-off-by: Biju Das Reviewed-by: Wolfram Sang Reviewed-by: Kieran Bingham Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- drivers/media/i2c/ov5645.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 40e15a573964f..f681531a5df7c 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -118,7 +118,6 @@ static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd) static const struct reg_value ov5645_global_init_setting[] = { { 0x3103, 0x11 }, - { 0x3008, 0x82 }, { 0x3008, 0x42 }, { 0x3103, 0x03 }, { 0x3503, 0x07 }, @@ -627,6 +626,10 @@ static int ov5645_set_register_array(struct ov5645 *ov5645, ret = ov5645_write_reg(ov5645, settings->reg, settings->val); if (ret < 0) return ret; + + if (settings->reg == OV5645_SYSTEM_CTRL0 && + settings->val == OV5645_SYSTEM_CTRL0_START) + usleep_range(1000, 2000); } return 0; From patchwork Mon Oct 28 20:03:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854002 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBA9AD3E2D0 for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2530.1730145845815967010 for ; Mon, 28 Oct 2024 13:04:06 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219267" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:05 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 45C2C408D907; Tue, 29 Oct 2024 05:04:04 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 07/27] media: v4l: subdev: Add pre_streamon and post_streamoff callbacks Date: Mon, 28 Oct 2024 20:03:29 +0000 Message-ID: <20241028200349.9620-8-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17089 From: Sakari Ailus commit 253171a0da67304f0ee7358b37df7b715c65dd77 upstream. Add pre_streamon and post_streamoff callbacks that can be used to set a CSI-2 transmitter to LP-11 or LP-111 mode. This can be used by receiver drivers to reliably initialise the receiver when its initialisation requires software involvement. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- include/media/v4l2-subdev.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 73150520c02d4..bb97106e1ae86 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -354,6 +354,16 @@ struct v4l2_mbus_frame_desc { unsigned short num_entries; }; +/** + * enum v4l2_subdev_pre_streamon_flags - Flags for pre_streamon subdev core op + * + * @V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP: Set the transmitter to either LP-11 + * or LP-111 mode before call to s_stream(). + */ +enum v4l2_subdev_pre_streamon_flags { + V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP = BIT(0), +}; + /** * struct v4l2_subdev_video_ops - Callbacks used when v4l device was opened * in video mode. @@ -409,6 +419,19 @@ struct v4l2_mbus_frame_desc { * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev * can adjust @size to a lower value and must not write more data to the * buffer starting at @data than the original value of @size. + * + * @pre_streamon: May be called before streaming is actually started, to help + * initialising the bus. Current usage is to set a CSI-2 transmitter to + * LP-11 or LP-111 mode before streaming. See &enum + * v4l2_subdev_pre_streamon_flags. + * + * pre_streamon shall return error if it cannot perform the operation as + * indicated by the flags argument. In particular, -EACCES indicates lack + * of support for the operation. The caller shall call post_streamoff for + * each successful call of pre_streamon. + * + * @post_streamoff: Called after streaming is stopped, but if and only if + * pre_streamon was called earlier. */ struct v4l2_subdev_video_ops { int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); @@ -435,6 +458,8 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, unsigned int *size); + int (*pre_streamon)(struct v4l2_subdev *sd, u32 flags); + int (*post_streamoff)(struct v4l2_subdev *sd); }; /** From patchwork Mon Oct 28 20:03:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13853999 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAE68D3E2CA for ; Mon, 28 Oct 2024 20:04:14 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2537.1730145853990506462 for ; Mon, 28 Oct 2024 13:04:14 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219276" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:13 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 21BD7408CD1D; Tue, 29 Oct 2024 05:04:05 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 08/27] media: dt-bindings: Document Renesas RZ/G2L CSI-2 block Date: Mon, 28 Oct 2024 20:03:30 +0000 Message-ID: <20241028200349.9620-9-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:14 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17091 commit 6c08bd7a6a7c7b3905de687519f80fd4b9fe8785 upstream. Document the CSI-2 block which is part of CRU found in Renesas RZ/G2L (and alike) SoCs. Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- .../bindings/media/renesas,rzg2l-csi2.yaml | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,rzg2l-csi2.yaml diff --git a/Documentation/devicetree/bindings/media/renesas,rzg2l-csi2.yaml b/Documentation/devicetree/bindings/media/renesas,rzg2l-csi2.yaml new file mode 100644 index 0000000000000..67eea2ac1d226 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,rzg2l-csi2.yaml @@ -0,0 +1,149 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright (C) 2022 Renesas Electronics Corp. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/renesas,rzg2l-csi2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G2L (and alike SoC's) MIPI CSI-2 receiver + +maintainers: + - Lad Prabhakar + +description: + The CSI-2 receiver device provides MIPI CSI-2 capabilities for the Renesas RZ/G2L + (and alike SoCs). MIPI CSI-2 is part of the CRU block which is used in conjunction + with the Image Processing module, which provides the video capture capabilities. + +properties: + compatible: + items: + - enum: + - renesas,r9a07g044-csi2 # RZ/G2{L,LC} + - renesas,r9a07g054-csi2 # RZ/V2L + - const: renesas,rzg2l-csi2 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Internal clock for connecting CRU and MIPI + - description: CRU Main clock + - description: CRU Register access clock + + clock-names: + items: + - const: system + - const: video + - const: apb + + power-domains: + maxItems: 1 + + resets: + items: + - description: CRU_PRESETN reset terminal + - description: CRU_CMN_RSTB reset terminal + + reset-names: + items: + - const: presetn + - const: cmn-rstb + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port node, single endpoint describing the CSI-2 transmitter. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + items: + maximum: 4 + + required: + - clock-lanes + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + Output port node, Image Processing block connected to the CSI-2 receiver. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + - resets + - reset-names + - ports + +additionalProperties: false + +examples: + - | + #include + #include + + csi: csi@10830400 { + compatible = "renesas,r9a07g044-csi2", "renesas,rzg2l-csi2"; + reg = <0x10830400 0xfc00>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A07G044_CRU_SYSCLK>, + <&cpg CPG_MOD R9A07G044_CRU_VCLK>, + <&cpg CPG_MOD R9A07G044_CRU_PCLK>; + clock-names = "system", "video", "apb"; + power-domains = <&cpg>; + resets = <&cpg R9A07G044_CRU_PRESETN>, + <&cpg R9A07G044_CRU_CMN_RSTB>; + reset-names = "presetn", "cmn-rstb"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi2_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&ov5645_ep>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + csi2cru: endpoint@0 { + reg = <0>; + remote-endpoint = <&crucsi2>; + }; + }; + }; + }; From patchwork Mon Oct 28 20:03:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854010 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8496D3E2CF for ; Mon, 28 Oct 2024 20:04:24 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2537.1730145853990506462 for ; Mon, 28 Oct 2024 13:04:15 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219282" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:15 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id F2130408D216; Tue, 29 Oct 2024 05:04:07 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 09/27] media: dt-bindings: Document Renesas RZ/G2L CRU block Date: Mon, 28 Oct 2024 20:03:31 +0000 Message-ID: <20241028200349.9620-10-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:24 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17092 commit a18004173a087573628ddc9910f0665a3829f48f upstream. Document the CRU block found on Renesas RZ/G2L (and alike) SoCs. Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- .../bindings/media/renesas,rzg2l-cru.yaml | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,rzg2l-cru.yaml diff --git a/Documentation/devicetree/bindings/media/renesas,rzg2l-cru.yaml b/Documentation/devicetree/bindings/media/renesas,rzg2l-cru.yaml new file mode 100644 index 0000000000000..7dde7967c8869 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,rzg2l-cru.yaml @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright (C) 2022 Renesas Electronics Corp. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/renesas,rzg2l-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G2L (and alike SoC's) Camera Data Receiving Unit (CRU) Image processing + +maintainers: + - Lad Prabhakar + +description: + The CRU image processing module is a data conversion module equipped with pixel + color space conversion, LUT, pixel format conversion, etc. An MIPI CSI-2 input and + parallel (including ITU-R BT.656) input are provided as the image sensor interface. + +properties: + compatible: + items: + - enum: + - renesas,r9a07g044-cru # RZ/G2{L,LC} + - renesas,r9a07g054-cru # RZ/V2L + - const: renesas,rzg2l-cru + + reg: + maxItems: 1 + + interrupts: + maxItems: 3 + + interrupt-names: + items: + - const: image_conv + - const: image_conv_err + - const: axi_mst_err + + clocks: + items: + - description: CRU Main clock + - description: CRU Register access clock + - description: CRU image transfer clock + + clock-names: + items: + - const: video + - const: apb + - const: axi + + power-domains: + maxItems: 1 + + resets: + items: + - description: CRU_PRESETN reset terminal + - description: CRU_ARESETN reset terminal + + reset-names: + items: + - const: presetn + - const: aresetn + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port node, single endpoint describing a parallel input source. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + hsync-active: true + vsync-active: true + bus-width: true + data-shift: true + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port node, describing the Image Processing module connected to the + CSI-2 receiver. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - resets + - reset-names + - power-domains + +additionalProperties: false + +examples: + # Device node example with CSI-2 + - | + #include + #include + + cru: video@10830000 { + compatible = "renesas,r9a07g044-cru", "renesas,rzg2l-cru"; + reg = <0x10830000 0x400>; + interrupts = , + , + ; + interrupt-names = "image_conv", "image_conv_err", "axi_mst_err"; + clocks = <&cpg CPG_MOD R9A07G044_CRU_VCLK>, + <&cpg CPG_MOD R9A07G044_CRU_PCLK>, + <&cpg CPG_MOD R9A07G044_CRU_ACLK>; + clock-names = "video", "apb", "axi"; + power-domains = <&cpg>; + resets = <&cpg R9A07G044_CRU_PRESETN>, + <&cpg R9A07G044_CRU_ARESETN>; + reset-names = "presetn", "aresetn"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + cru_parallel_in: endpoint@0 { + reg = <0>; + remote-endpoint= <&ov5642>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + cru_csi_in: endpoint@0 { + reg = <0>; + remote-endpoint= <&csi_cru_in>; + }; + }; + }; + }; From patchwork Mon Oct 28 20:03:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D82B0D3E2CA for ; Mon, 28 Oct 2024 20:04:24 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2541.1730145857718862963 for ; Mon, 28 Oct 2024 13:04:18 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233443" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:17 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id D009D408D425; Tue, 29 Oct 2024 05:04:09 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 10/27] media: platform: Add Renesas RZ/G2L MIPI CSI-2 receiver driver Date: Mon, 28 Oct 2024 20:03:32 +0000 Message-ID: <20241028200349.9620-11-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:24 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17093 commit 51e8415e39a962db2a753940fca18e9710c24902 upstream. Add MIPI CSI-2 receiver driver for Renesas RZ/G2L. The MIPI CSI-2 is part of the CRU module found on RZ/G2L family. Based on a patch in the BSP by Hien Huynh Signed-off-by: Lad Prabhakar Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab [PL: Updated driver to handle formats locally as subdev state apis are missing in the kernel. Also added UYVY8_2X8 code support as commit ba449bb56203 ("media: i2c: ov5645: Fix media bus format") changes it to UYVY8_1X16, so to avoid breakage UYVY8_2X8 is added.] Signed-off-by: Lad Prabhakar --- drivers/media/platform/Kconfig | 1 + drivers/media/platform/Makefile | 1 + drivers/media/platform/renesas/Kconfig | 0 drivers/media/platform/renesas/Makefile | 0 .../media/platform/renesas/rzg2l-cru/Kconfig | 17 + .../media/platform/renesas/rzg2l-cru/Makefile | 3 + .../platform/renesas/rzg2l-cru/rzg2l-csi2.c | 883 ++++++++++++++++++ 7 files changed, 905 insertions(+) create mode 100644 drivers/media/platform/renesas/Kconfig create mode 100644 drivers/media/platform/renesas/Makefile create mode 100644 drivers/media/platform/renesas/rzg2l-cru/Kconfig create mode 100644 drivers/media/platform/renesas/rzg2l-cru/Makefile create mode 100644 drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 7e152bbb4fa66..f4f062f6845ba 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -151,6 +151,7 @@ source "drivers/media/platform/exynos4-is/Kconfig" source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" source "drivers/media/platform/rcar-vin/Kconfig" +source "drivers/media/platform/renesas/rzg2l-cru/Kconfig" source "drivers/media/platform/atmel/Kconfig" source "drivers/media/platform/sunxi/Kconfig" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 62b6cdc8c7300..a25329c06ec30 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ obj-$(CONFIG_VIDEO_XILINX) += xilinx/ obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ +obj-y += renesas/rzg2l-cru/ obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/ diff --git a/drivers/media/platform/renesas/Kconfig b/drivers/media/platform/renesas/Kconfig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/drivers/media/platform/renesas/Makefile b/drivers/media/platform/renesas/Makefile new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/drivers/media/platform/renesas/rzg2l-cru/Kconfig b/drivers/media/platform/renesas/rzg2l-cru/Kconfig new file mode 100644 index 0000000000000..57c40bb499df9 --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 + +config VIDEO_RZG2L_CSI2 + tristate "RZ/G2L MIPI CSI-2 Receiver" + depends on ARCH_RENESAS || COMPILE_TEST + depends on V4L_PLATFORM_DRIVERS + depends on VIDEO_DEV && OF + select MEDIA_CONTROLLER + select RESET_CONTROLLER + select V4L2_FWNODE + select VIDEO_V4L2_SUBDEV_API + help + Support for Renesas RZ/G2L (and alike SoC's) MIPI CSI-2 + Receiver driver. + + To compile this driver as a module, choose M here: the + module will be called rzg2l-csi2. diff --git a/drivers/media/platform/renesas/rzg2l-cru/Makefile b/drivers/media/platform/renesas/rzg2l-cru/Makefile new file mode 100644 index 0000000000000..91ea97a944e6c --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_VIDEO_RZG2L_CSI2) += rzg2l-csi2.o diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c new file mode 100644 index 0000000000000..40e105613bc99 --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -0,0 +1,883 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Renesas RZ/G2L MIPI CSI-2 Receiver + * + * Copyright (C) 2022 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* LINK registers */ +/* Module Configuration Register */ +#define CSI2nMCG 0x0 +#define CSI2nMCG_SDLN GENMASK(11, 8) + +/* Module Control Register 0 */ +#define CSI2nMCT0 0x10 +#define CSI2nMCT0_VDLN(x) ((x) << 0) + +/* Module Control Register 2 */ +#define CSI2nMCT2 0x18 +#define CSI2nMCT2_FRRSKW(x) ((x) << 16) +#define CSI2nMCT2_FRRCLK(x) ((x) << 0) + +/* Module Control Register 3 */ +#define CSI2nMCT3 0x1c +#define CSI2nMCT3_RXEN BIT(0) + +/* Reset Control Register */ +#define CSI2nRTCT 0x28 +#define CSI2nRTCT_VSRST BIT(0) + +/* Reset Status Register */ +#define CSI2nRTST 0x2c +#define CSI2nRTST_VSRSTS BIT(0) + +/* Receive Data Type Enable Low Register */ +#define CSI2nDTEL 0x60 + +/* Receive Data Type Enable High Register */ +#define CSI2nDTEH 0x64 + +/* DPHY registers */ +/* D-PHY Control Register 0 */ +#define CSIDPHYCTRL0 0x400 +#define CSIDPHYCTRL0_EN_LDO1200 BIT(1) +#define CSIDPHYCTRL0_EN_BGR BIT(0) + +/* D-PHY Timing Register 0 */ +#define CSIDPHYTIM0 0x404 +#define CSIDPHYTIM0_TCLK_MISS(x) ((x) << 24) +#define CSIDPHYTIM0_T_INIT(x) ((x) << 0) + +/* D-PHY Timing Register 1 */ +#define CSIDPHYTIM1 0x408 +#define CSIDPHYTIM1_THS_PREPARE(x) ((x) << 24) +#define CSIDPHYTIM1_TCLK_PREPARE(x) ((x) << 16) +#define CSIDPHYTIM1_THS_SETTLE(x) ((x) << 8) +#define CSIDPHYTIM1_TCLK_SETTLE(x) ((x) << 0) + +/* D-PHY Skew Adjustment Function */ +#define CSIDPHYSKW0 0x460 +#define CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(x) ((x) & 0x3) +#define CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(x) (((x) & 0x3) << 4) +#define CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(x) (((x) & 0x3) << 8) +#define CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(x) (((x) & 0x3) << 12) +#define CSIDPHYSKW0_DEFAULT_SKW CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1) + +#define VSRSTS_RETRIES 20 + +#define RZG2L_CSI2_MIN_WIDTH 320 +#define RZG2L_CSI2_MIN_HEIGHT 240 +#define RZG2L_CSI2_MAX_WIDTH 2800 +#define RZG2L_CSI2_MAX_HEIGHT 4095 + +#define RZG2L_CSI2_DEFAULT_WIDTH RZG2L_CSI2_MIN_WIDTH +#define RZG2L_CSI2_DEFAULT_HEIGHT RZG2L_CSI2_MIN_HEIGHT +#define RZG2L_CSI2_DEFAULT_FMT MEDIA_BUS_FMT_UYVY8_1X16 + +enum rzg2l_csi2_pads { + RZG2L_CSI2_SINK = 0, + RZG2L_CSI2_SOURCE, + NR_OF_RZG2L_CSI2_PAD, +}; + +struct rzg2l_csi2 { + struct device *dev; + void __iomem *base; + struct reset_control *presetn; + struct reset_control *cmn_rstb; + struct clk *sysclk; + unsigned long vclk_rate; + + struct v4l2_subdev subdev; + struct media_pad pads[NR_OF_RZG2L_CSI2_PAD]; + struct v4l2_mbus_framefmt mf; + + struct v4l2_async_notifier notifier; + struct v4l2_subdev *remote_source; + + unsigned short lanes; + unsigned long hsfreq; + + bool dphy_enabled; +}; + +struct rzg2l_csi2_timings { + u32 t_init; + u32 tclk_miss; + u32 tclk_settle; + u32 ths_settle; + u32 tclk_prepare; + u32 ths_prepare; + u32 max_hsfreq; +}; + +static const struct rzg2l_csi2_timings rzg2l_csi2_global_timings[] = { + { + .max_hsfreq = 80, + .t_init = 79801, + .tclk_miss = 4, + .tclk_settle = 23, + .ths_settle = 31, + .tclk_prepare = 10, + .ths_prepare = 19, + }, + { + .max_hsfreq = 125, + .t_init = 79801, + .tclk_miss = 4, + .tclk_settle = 23, + .ths_settle = 28, + .tclk_prepare = 10, + .ths_prepare = 19, + }, + { + .max_hsfreq = 250, + .t_init = 79801, + .tclk_miss = 4, + .tclk_settle = 23, + .ths_settle = 22, + .tclk_prepare = 10, + .ths_prepare = 16, + }, + { + .max_hsfreq = 360, + .t_init = 79801, + .tclk_miss = 4, + .tclk_settle = 18, + .ths_settle = 19, + .tclk_prepare = 10, + .ths_prepare = 10, + }, + { + .max_hsfreq = 1500, + .t_init = 79801, + .tclk_miss = 4, + .tclk_settle = 18, + .ths_settle = 18, + .tclk_prepare = 10, + .ths_prepare = 10, + }, +}; + +struct rzg2l_csi2_format { + u32 code; + unsigned int datatype; + unsigned int bpp; +}; + +static const struct rzg2l_csi2_format rzg2l_csi2_formats[] = { + { .code = MEDIA_BUS_FMT_UYVY8_2X8, .datatype = 0x1e, .bpp = 16 }, + { .code = MEDIA_BUS_FMT_UYVY8_1X16, .datatype = 0x1e, .bpp = 16 }, +}; + +static inline struct rzg2l_csi2 *sd_to_csi2(struct v4l2_subdev *sd) +{ + return container_of(sd, struct rzg2l_csi2, subdev); +} + +static const struct rzg2l_csi2_format *rzg2l_csi2_code_to_fmt(unsigned int code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rzg2l_csi2_formats); i++) + if (rzg2l_csi2_formats[i].code == code) + return &rzg2l_csi2_formats[i]; + + return NULL; +} + +static inline struct rzg2l_csi2 *notifier_to_csi2(struct v4l2_async_notifier *n) +{ + return container_of(n, struct rzg2l_csi2, notifier); +} + +static u32 rzg2l_csi2_read(struct rzg2l_csi2 *csi2, unsigned int reg) +{ + return ioread32(csi2->base + reg); +} + +static void rzg2l_csi2_write(struct rzg2l_csi2 *csi2, unsigned int reg, + u32 data) +{ + iowrite32(data, csi2->base + reg); +} + +static void rzg2l_csi2_set(struct rzg2l_csi2 *csi2, unsigned int reg, u32 set) +{ + rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) | set); +} + +static void rzg2l_csi2_clr(struct rzg2l_csi2 *csi2, unsigned int reg, u32 clr) +{ + rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) & ~clr); +} + +static int rzg2l_csi2_calc_mbps(struct rzg2l_csi2 *csi2) +{ + struct v4l2_subdev *source = csi2->remote_source; + const struct rzg2l_csi2_format *format; + struct v4l2_ctrl *ctrl; + u64 mbps; + + /* Read the pixel rate control from remote. */ + ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE); + if (!ctrl) { + dev_err(csi2->dev, "no pixel rate control in subdev %s\n", + source->name); + return -EINVAL; + } + + format = rzg2l_csi2_code_to_fmt(csi2->mf.code); + + /* + * Calculate hsfreq in Mbps + * hsfreq = (pixel_rate * bits_per_sample) / number_of_lanes + */ + mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * format->bpp; + do_div(mbps, csi2->lanes * 1000000); + + return mbps; +} + +/* ----------------------------------------------------------------------------- + * DPHY setting + */ + +static int rzg2l_csi2_dphy_disable(struct rzg2l_csi2 *csi2) +{ + int ret; + + /* Reset the CRU (D-PHY) */ + ret = reset_control_assert(csi2->cmn_rstb); + if (ret) + return ret; + + /* Stop the D-PHY clock */ + clk_disable_unprepare(csi2->sysclk); + + /* Cancel the EN_LDO1200 register setting */ + rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); + + /* Cancel the EN_BGR register setting */ + rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); + + csi2->dphy_enabled = false; + + return 0; +} + +static int rzg2l_csi2_dphy_enable(struct rzg2l_csi2 *csi2) +{ + const struct rzg2l_csi2_timings *dphy_timing; + u32 dphytim0, dphytim1; + unsigned int i; + int mbps; + int ret; + + mbps = rzg2l_csi2_calc_mbps(csi2); + if (mbps < 0) + return mbps; + + csi2->hsfreq = mbps; + + /* Set DPHY timing parameters */ + for (i = 0; i < ARRAY_SIZE(rzg2l_csi2_global_timings); ++i) { + dphy_timing = &rzg2l_csi2_global_timings[i]; + + if (csi2->hsfreq <= dphy_timing->max_hsfreq) + break; + } + + if (i >= ARRAY_SIZE(rzg2l_csi2_global_timings)) + return -EINVAL; + + /* Set D-PHY timing parameters */ + dphytim0 = CSIDPHYTIM0_TCLK_MISS(dphy_timing->tclk_miss) | + CSIDPHYTIM0_T_INIT(dphy_timing->t_init); + dphytim1 = CSIDPHYTIM1_THS_PREPARE(dphy_timing->ths_prepare) | + CSIDPHYTIM1_TCLK_PREPARE(dphy_timing->tclk_prepare) | + CSIDPHYTIM1_THS_SETTLE(dphy_timing->ths_settle) | + CSIDPHYTIM1_TCLK_SETTLE(dphy_timing->tclk_settle); + rzg2l_csi2_write(csi2, CSIDPHYTIM0, dphytim0); + rzg2l_csi2_write(csi2, CSIDPHYTIM1, dphytim1); + + /* Enable D-PHY power control 0 */ + rzg2l_csi2_write(csi2, CSIDPHYSKW0, CSIDPHYSKW0_DEFAULT_SKW); + + /* Set the EN_BGR bit */ + rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); + + /* Delay 20us to be stable */ + usleep_range(20, 40); + + /* Enable D-PHY power control 1 */ + rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); + + /* Delay 10us to be stable */ + usleep_range(10, 20); + + /* Start supplying the internal clock for the D-PHY block */ + ret = clk_prepare_enable(csi2->sysclk); + if (ret) + rzg2l_csi2_dphy_disable(csi2); + + csi2->dphy_enabled = true; + + return ret; +} + +static int rzg2l_csi2_dphy_setting(struct v4l2_subdev *sd, bool on) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + + if (on) + return rzg2l_csi2_dphy_enable(csi2); + + return rzg2l_csi2_dphy_disable(csi2); +} + +static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) +{ + unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ; + u32 frrskw, frrclk, frrskw_coeff, frrclk_coeff; + + /* Select data lanes */ + rzg2l_csi2_write(csi2, CSI2nMCT0, CSI2nMCT0_VDLN(csi2->lanes)); + + frrskw_coeff = 3 * vclk_rate * 8; + frrclk_coeff = frrskw_coeff / 2; + frrskw = DIV_ROUND_UP(frrskw_coeff, csi2->hsfreq); + frrclk = DIV_ROUND_UP(frrclk_coeff, csi2->hsfreq); + rzg2l_csi2_write(csi2, CSI2nMCT2, CSI2nMCT2_FRRSKW(frrskw) | + CSI2nMCT2_FRRCLK(frrclk)); + + /* + * Select data type. + * FS, FE, LS, LE, Generic Short Packet Codes 1 to 8, + * Generic Long Packet Data Types 1 to 4 YUV422 8-bit, + * RGB565, RGB888, RAW8 to RAW20, User-defined 8-bit + * data types 1 to 8 + */ + rzg2l_csi2_write(csi2, CSI2nDTEL, 0xf778ff0f); + rzg2l_csi2_write(csi2, CSI2nDTEH, 0x00ffff1f); + + /* Enable LINK reception */ + rzg2l_csi2_write(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); +} + +static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) +{ + unsigned int timeout = VSRSTS_RETRIES; + + /* Stop LINK reception */ + rzg2l_csi2_clr(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); + + /* Request a software reset of the LINK Video Pixel Interface */ + rzg2l_csi2_write(csi2, CSI2nRTCT, CSI2nRTCT_VSRST); + + /* Make sure CSI2nRTST.VSRSTS bit is cleared */ + while (timeout--) { + if (!(rzg2l_csi2_read(csi2, CSI2nRTST) & CSI2nRTST_VSRSTS)) + break; + usleep_range(100, 200); + }; + + if (!timeout) + dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n"); +} + +static int rzg2l_csi2_mipi_link_setting(struct v4l2_subdev *sd, bool on) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + + if (on) + rzg2l_csi2_mipi_link_enable(csi2); + else + rzg2l_csi2_mipi_link_disable(csi2); + + return 0; +} + +static int rzg2l_csi2_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + int s_stream_ret = 0; + int ret; + + if (enable) { + int ret; + + ret = pm_runtime_resume_and_get(csi2->dev); + if (ret) + return ret; + + ret = rzg2l_csi2_mipi_link_setting(sd, 1); + if (ret) + goto err_pm_put; + + ret = reset_control_deassert(csi2->cmn_rstb); + if (ret) + goto err_mipi_link_disable; + } + + ret = v4l2_subdev_call(csi2->remote_source, video, s_stream, enable); + if (ret) + s_stream_ret = ret; + + if (enable && ret) + goto err_assert_rstb; + + if (!enable) { + ret = rzg2l_csi2_dphy_setting(sd, 0); + if (ret && !s_stream_ret) + s_stream_ret = ret; + ret = rzg2l_csi2_mipi_link_setting(sd, 0); + if (ret && !s_stream_ret) + s_stream_ret = ret; + + pm_runtime_put_sync(csi2->dev); + } + + return s_stream_ret; + +err_assert_rstb: + reset_control_assert(csi2->cmn_rstb); +err_mipi_link_disable: + rzg2l_csi2_mipi_link_setting(sd, 0); +err_pm_put: + pm_runtime_put_sync(csi2->dev); + return ret; +} + +static int rzg2l_csi2_pre_streamon(struct v4l2_subdev *sd, u32 flags) +{ + return rzg2l_csi2_dphy_setting(sd, 1); +} + +static int rzg2l_csi2_post_streamoff(struct v4l2_subdev *sd) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + + /* + * In ideal case D-PHY will be disabled in s_stream(0) callback + * as mentioned in the HW manual. The below will only happen when + * pre_streamon succeeds and further down the line s_stream(1) + * fails so we need to undo things in post_streamoff. + */ + if (csi2->dphy_enabled) + return rzg2l_csi2_dphy_setting(sd, 0); + + return 0; +} + +static int rzg2l_csi2_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) + fmt->format = csi2->mf; + else + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + + return 0; +} + +static int rzg2l_csi2_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + struct v4l2_mbus_framefmt *src_format; + struct v4l2_mbus_framefmt *sink_format; + + src_format = v4l2_subdev_get_try_format(sd, cfg, RZG2L_CSI2_SOURCE); + if (fmt->pad == RZG2L_CSI2_SOURCE) { + fmt->format = *src_format; + return 0; + } + + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + csi2->mf = fmt->format; + return 0; + } + + sink_format = v4l2_subdev_get_try_format(sd, cfg, RZG2L_CSI2_SINK); + + if (!rzg2l_csi2_code_to_fmt(fmt->format.code)) + sink_format->code = rzg2l_csi2_formats[0].code; + else + sink_format->code = fmt->format.code; + + fmt->format.field = V4L2_FIELD_NONE; + fmt->format.width = clamp_t(u32, fmt->format.width, + RZG2L_CSI2_MIN_WIDTH, RZG2L_CSI2_MAX_WIDTH); + fmt->format.height = clamp_t(u32, fmt->format.height, + RZG2L_CSI2_MIN_HEIGHT, RZG2L_CSI2_MAX_HEIGHT); + *sink_format = fmt->format; + + /* propagate format to source pad */ + *src_format = *sink_format; + + return 0; +} + +static int rzg2l_csi2_init_config(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_subdev_format fmt = { .pad = RZG2L_CSI2_SINK, }; + + fmt.format.width = RZG2L_CSI2_DEFAULT_WIDTH; + fmt.format.height = RZG2L_CSI2_DEFAULT_HEIGHT; + fmt.format.field = V4L2_FIELD_NONE; + fmt.format.code = RZG2L_CSI2_DEFAULT_FMT; + fmt.format.colorspace = V4L2_COLORSPACE_SRGB; + fmt.format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + fmt.format.quantization = V4L2_QUANTIZATION_DEFAULT; + fmt.format.xfer_func = V4L2_XFER_FUNC_DEFAULT; + + return rzg2l_csi2_set_format(sd, cfg, &fmt); +} + +static int rzg2l_csi2_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index >= ARRAY_SIZE(rzg2l_csi2_formats)) + return -EINVAL; + + code->code = rzg2l_csi2_formats[code->index].code; + + return 0; +} + +static int rzg2l_csi2_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index != 0) + return -EINVAL; + + fse->min_width = RZG2L_CSI2_MIN_WIDTH; + fse->min_height = RZG2L_CSI2_MIN_HEIGHT; + fse->max_width = RZG2L_CSI2_MAX_WIDTH; + fse->max_height = RZG2L_CSI2_MAX_HEIGHT; + + return 0; +} + +static const struct v4l2_subdev_video_ops rzg2l_csi2_video_ops = { + .s_stream = rzg2l_csi2_s_stream, + .pre_streamon = rzg2l_csi2_pre_streamon, + .post_streamoff = rzg2l_csi2_post_streamoff, +}; + +static const struct v4l2_subdev_pad_ops rzg2l_csi2_pad_ops = { + .enum_mbus_code = rzg2l_csi2_enum_mbus_code, + .init_cfg = rzg2l_csi2_init_config, + .enum_frame_size = rzg2l_csi2_enum_frame_size, + .set_fmt = rzg2l_csi2_set_format, + .get_fmt = rzg2l_csi2_get_pad_format, +}; + +static const struct v4l2_subdev_ops rzg2l_csi2_subdev_ops = { + .video = &rzg2l_csi2_video_ops, + .pad = &rzg2l_csi2_pad_ops, +}; + +/* ----------------------------------------------------------------------------- + * Async handling and registration of subdevices and links. + */ + +static int rzg2l_csi2_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); + + csi2->remote_source = subdev; + + dev_dbg(csi2->dev, "Bound subdev: %s pad\n", subdev->name); + + return media_create_pad_link(&subdev->entity, RZG2L_CSI2_SINK, + &csi2->subdev.entity, 0, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); +} + +static void rzg2l_csi2_notify_unbind(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); + + csi2->remote_source = NULL; + + dev_dbg(csi2->dev, "Unbind subdev %s\n", subdev->name); +} + +static const struct v4l2_async_notifier_operations rzg2l_csi2_notify_ops = { + .bound = rzg2l_csi2_notify_bound, + .unbind = rzg2l_csi2_notify_unbind, +}; + +static int rzg2l_csi2_parse_v4l2(struct rzg2l_csi2 *csi2, + struct v4l2_fwnode_endpoint *vep) +{ + /* Only port 0 endpoint 0 is valid. */ + if (vep->base.port || vep->base.id) + return -ENOTCONN; + + csi2->lanes = vep->bus.mipi_csi2.num_data_lanes; + + return 0; +} + +static int rzg2l_csi2_parse_dt(struct rzg2l_csi2 *csi2) +{ + struct v4l2_fwnode_endpoint v4l2_ep = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; + struct v4l2_async_subdev *asd; + struct fwnode_handle *fwnode; + struct fwnode_handle *ep; + int ret; + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, 0); + if (!ep) { + dev_err(csi2->dev, "Not connected to subdevice\n"); + return -EINVAL; + } + + ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep); + if (ret) { + dev_err(csi2->dev, "Could not parse v4l2 endpoint\n"); + fwnode_handle_put(ep); + return -EINVAL; + } + + ret = rzg2l_csi2_parse_v4l2(csi2, &v4l2_ep); + if (ret) { + fwnode_handle_put(ep); + return ret; + } + + fwnode = fwnode_graph_get_remote_endpoint(ep); + fwnode_handle_put(ep); + + v4l2_async_notifier_init(&csi2->notifier); + csi2->notifier.ops = &rzg2l_csi2_notify_ops; + + asd = v4l2_async_notifier_add_fwnode_subdev(&csi2->notifier, fwnode, + sizeof(*asd)); + fwnode_handle_put(fwnode); + if (IS_ERR(asd)) + return PTR_ERR(asd); + + ret = v4l2_async_subdev_notifier_register(&csi2->subdev, &csi2->notifier); + if (ret) + v4l2_async_notifier_cleanup(&csi2->notifier); + + return ret; +} + +static int rzg2l_validate_csi2_lanes(struct rzg2l_csi2 *csi2) +{ + int lanes; + int ret; + + if (csi2->lanes != 1 && csi2->lanes != 2 && csi2->lanes != 4) { + dev_err(csi2->dev, "Unsupported number of data-lanes: %u\n", + csi2->lanes); + return -EINVAL; + } + + ret = pm_runtime_resume_and_get(csi2->dev); + if (ret) + return ret; + + /* Checking the maximum lanes support for CSI-2 module */ + lanes = (rzg2l_csi2_read(csi2, CSI2nMCG) & CSI2nMCG_SDLN) >> 8; + if (lanes < csi2->lanes) { + dev_err(csi2->dev, + "Failed to support %d data lanes\n", csi2->lanes); + ret = -EINVAL; + } + + pm_runtime_put_sync(csi2->dev); + + return ret; +} + +/* ----------------------------------------------------------------------------- + * Platform Device Driver. + */ + +static const struct media_entity_operations rzg2l_csi2_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static int rzg2l_csi2_probe(struct platform_device *pdev) +{ + struct rzg2l_csi2 *csi2; + struct clk *vclk; + int ret; + + csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL); + if (!csi2) + return -ENOMEM; + + csi2->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(csi2->base)) + return PTR_ERR(csi2->base); + + csi2->cmn_rstb = devm_reset_control_get_exclusive(&pdev->dev, "cmn-rstb"); + if (IS_ERR(csi2->cmn_rstb)) + return dev_err_probe(&pdev->dev, PTR_ERR(csi2->cmn_rstb), + "Failed to get cpg cmn-rstb\n"); + + csi2->presetn = devm_reset_control_get_shared(&pdev->dev, "presetn"); + if (IS_ERR(csi2->presetn)) + return dev_err_probe(&pdev->dev, PTR_ERR(csi2->presetn), + "Failed to get cpg presetn\n"); + + csi2->sysclk = devm_clk_get(&pdev->dev, "system"); + if (IS_ERR(csi2->sysclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(csi2->sysclk), + "Failed to get system clk\n"); + + vclk = clk_get(&pdev->dev, "video"); + if (IS_ERR(vclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(vclk), + "Failed to get video clock\n"); + csi2->vclk_rate = clk_get_rate(vclk); + clk_put(vclk); + + csi2->dev = &pdev->dev; + + platform_set_drvdata(pdev, csi2); + + ret = rzg2l_csi2_parse_dt(csi2); + if (ret) + return ret; + + pm_runtime_enable(&pdev->dev); + + ret = rzg2l_validate_csi2_lanes(csi2); + if (ret) + goto error_pm; + + csi2->subdev.dev = &pdev->dev; + v4l2_subdev_init(&csi2->subdev, &rzg2l_csi2_subdev_ops); + v4l2_set_subdevdata(&csi2->subdev, &pdev->dev); + snprintf(csi2->subdev.name, sizeof(csi2->subdev.name), + "csi-%s", dev_name(&pdev->dev)); + csi2->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + + csi2->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + csi2->subdev.entity.ops = &rzg2l_csi2_entity_ops; + + csi2->pads[RZG2L_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; + /* + * TODO: RZ/G2L CSI2 supports 4 virtual channels, as virtual + * channels should be implemented by streams API which is under + * development lets hardcode to VC0 for now. + */ + csi2->pads[RZG2L_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&csi2->subdev.entity, 2, csi2->pads); + if (ret) + goto error_pm; + + ret = v4l2_async_register_subdev(&csi2->subdev); + if (ret < 0) + goto error_async; + + return 0; + +error_async: + v4l2_async_notifier_unregister(&csi2->notifier); + v4l2_async_notifier_cleanup(&csi2->notifier); + media_entity_cleanup(&csi2->subdev.entity); +error_pm: + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int rzg2l_csi2_remove(struct platform_device *pdev) +{ + struct rzg2l_csi2 *csi2 = platform_get_drvdata(pdev); + + v4l2_async_notifier_unregister(&csi2->notifier); + v4l2_async_notifier_cleanup(&csi2->notifier); + v4l2_async_unregister_subdev(&csi2->subdev); + media_entity_cleanup(&csi2->subdev.entity); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int __maybe_unused rzg2l_csi2_pm_runtime_suspend(struct device *dev) +{ + struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); + + reset_control_assert(csi2->presetn); + + return 0; +} + +static int __maybe_unused rzg2l_csi2_pm_runtime_resume(struct device *dev) +{ + struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); + + return reset_control_deassert(csi2->presetn); +} + +static const struct dev_pm_ops rzg2l_csi2_pm_ops = { + SET_RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend, rzg2l_csi2_pm_runtime_resume, NULL) +}; + +static const struct of_device_id rzg2l_csi2_of_table[] = { + { .compatible = "renesas,rzg2l-csi2", }, + { /* sentinel */ } +}; + +static struct platform_driver rzg2l_csi2_pdrv = { + .remove = rzg2l_csi2_remove, + .probe = rzg2l_csi2_probe, + .driver = { + .name = "rzg2l-csi2", + .of_match_table = rzg2l_csi2_of_table, + .pm = &rzg2l_csi2_pm_ops, + }, +}; + +module_platform_driver(rzg2l_csi2_pdrv); + +MODULE_AUTHOR("Lad Prabhakar "); +MODULE_DESCRIPTION("Renesas RZ/G2L MIPI CSI2 receiver driver"); +MODULE_LICENSE("GPL"); From patchwork Mon Oct 28 20:03:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854006 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE3C5D3E2D0 for ; Mon, 28 Oct 2024 20:04:24 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2541.1730145857718862963 for ; Mon, 28 Oct 2024 13:04:23 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233450" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:22 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id B4BB9408D45B; Tue, 29 Oct 2024 05:04:11 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 11/27] media: platform: Add Renesas RZ/G2L CRU driver Date: Mon, 28 Oct 2024 20:03:33 +0000 Message-ID: <20241028200349.9620-12-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:24 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17098 commit 07fc05bd0a797dcc34620869933993e1cbf56b98 upstream. Add v4l driver for Renesas RZ/G2L Camera data Receiving Unit. Based on a patch in the BSP by Hien Huynh Signed-off-by: Lad Prabhakar Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab [PL: Updated driver to handle formats locally as subdev state apis are missing in the kernel. Also added UYVY8_2X8 code support as commit ba449bb56203 ("media: i2c: ov5645: Fix media bus format") changes it to UYVY8_1X16, so to avoid breakage UYVY8_2X8 is added.] Signed-off-by: Lad Prabhakar --- .../media/platform/renesas/rzg2l-cru/Kconfig | 16 + .../media/platform/renesas/rzg2l-cru/Makefile | 3 + .../platform/renesas/rzg2l-cru/rzg2l-core.c | 338 ++++++ .../platform/renesas/rzg2l-cru/rzg2l-cru.h | 153 +++ .../platform/renesas/rzg2l-cru/rzg2l-ip.c | 263 ++++ .../platform/renesas/rzg2l-cru/rzg2l-video.c | 1059 +++++++++++++++++ 6 files changed, 1832 insertions(+) create mode 100644 drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c create mode 100644 drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h create mode 100644 drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c create mode 100644 drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c diff --git a/drivers/media/platform/renesas/rzg2l-cru/Kconfig b/drivers/media/platform/renesas/rzg2l-cru/Kconfig index 57c40bb499df9..b39818c1f0534 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/Kconfig +++ b/drivers/media/platform/renesas/rzg2l-cru/Kconfig @@ -15,3 +15,19 @@ config VIDEO_RZG2L_CSI2 To compile this driver as a module, choose M here: the module will be called rzg2l-csi2. + +config VIDEO_RZG2L_CRU + tristate "RZ/G2L Camera Receiving Unit (CRU) Driver" + depends on ARCH_RENESAS || COMPILE_TEST + depends on V4L_PLATFORM_DRIVERS + depends on VIDEO_DEV && OF + select MEDIA_CONTROLLER + select V4L2_FWNODE + select VIDEOBUF2_DMA_CONTIG + select VIDEO_V4L2_SUBDEV_API + help + Support for Renesas RZ/G2L (and alike SoC's) Camera Receiving + Unit (CRU) driver. + + To compile this driver as a module, choose M here: the + module will be called rzg2l-cru. diff --git a/drivers/media/platform/renesas/rzg2l-cru/Makefile b/drivers/media/platform/renesas/rzg2l-cru/Makefile index 91ea97a944e6c..c4db2632874fb 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/Makefile +++ b/drivers/media/platform/renesas/rzg2l-cru/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VIDEO_RZG2L_CSI2) += rzg2l-csi2.o + +rzg2l-cru-objs = rzg2l-core.o rzg2l-ip.o rzg2l-video.o +obj-$(CONFIG_VIDEO_RZG2L_CRU) += rzg2l-cru.o diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c new file mode 100644 index 0000000000000..17c24aa54bf19 --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for Renesas RZ/G2L CRU + * + * Copyright (C) 2022 Renesas Electronics Corp. + * + * Based on Renesas R-Car VIN + * Copyright (C) 2011-2013 Renesas Solutions Corp. + * Copyright (C) 2013 Cogent Embedded, Inc., + * Copyright (C) 2008 Magnus Damm + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "rzg2l-cru.h" + +static inline struct rzg2l_cru_dev *notifier_to_cru(struct v4l2_async_notifier *n) +{ + return container_of(n, struct rzg2l_cru_dev, notifier); +} + +static const struct media_device_ops rzg2l_cru_media_ops = { + .link_notify = v4l2_pipeline_link_notify, +}; + +/* ----------------------------------------------------------------------------- + * Group async notifier + */ + +static int rzg2l_cru_group_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct rzg2l_cru_dev *cru = notifier_to_cru(notifier); + struct media_entity *source, *sink; + int ret; + + ret = rzg2l_cru_ip_subdev_register(cru); + if (ret) + return ret; + + ret = v4l2_device_register_subdev_nodes(&cru->v4l2_dev); + if (ret) { + dev_err(cru->dev, "Failed to register subdev nodes\n"); + return ret; + } + + ret = rzg2l_cru_video_register(cru); + if (ret) + return ret; + + /* + * CRU can be connected either to CSI2 or PARALLEL device + * For now we are only supporting CSI2 + * + * Create media device link between CSI-2 <-> CRU IP + */ + source = &cru->csi.subdev->entity; + sink = &cru->ip.subdev.entity; + ret = media_create_pad_link(source, 1, sink, 0, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret) { + dev_err(cru->dev, "Error creating link from %s to %s\n", + source->name, sink->name); + return ret; + } + cru->csi.channel = 0; + cru->ip.remote = cru->csi.subdev; + + /* Create media device link between CRU IP <-> CRU OUTPUT */ + source = &cru->ip.subdev.entity; + sink = &cru->vdev.entity; + ret = media_create_pad_link(source, 1, sink, 0, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret) { + dev_err(cru->dev, "Error creating link from %s to %s\n", + source->name, sink->name); + return ret; + } + + return 0; +} + +static void rzg2l_cru_group_notify_unbind(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct rzg2l_cru_dev *cru = notifier_to_cru(notifier); + + rzg2l_cru_ip_subdev_unregister(cru); + + mutex_lock(&cru->mdev_lock); + + if (cru->csi.asd == asd) { + cru->csi.subdev = NULL; + dev_dbg(cru->dev, "Unbind CSI-2 %s\n", subdev->name); + } + + mutex_unlock(&cru->mdev_lock); +} + +static int rzg2l_cru_group_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct rzg2l_cru_dev *cru = notifier_to_cru(notifier); + + mutex_lock(&cru->mdev_lock); + + if (cru->csi.asd == asd) { + cru->csi.subdev = subdev; + dev_dbg(cru->dev, "Bound CSI-2 %s\n", subdev->name); + } + + mutex_unlock(&cru->mdev_lock); + + return 0; +} + +static const struct v4l2_async_notifier_operations rzg2l_cru_async_ops = { + .bound = rzg2l_cru_group_notify_bound, + .unbind = rzg2l_cru_group_notify_unbind, + .complete = rzg2l_cru_group_notify_complete, +}; + +static int rzg2l_cru_mc_parse_of(struct rzg2l_cru_dev *cru) +{ + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; + struct fwnode_handle *ep, *fwnode; + struct v4l2_async_subdev *asd; + int ret; + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(cru->dev), 1, 0, 0); + if (!ep) + return 0; + + fwnode = fwnode_graph_get_remote_endpoint(ep); + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + fwnode_handle_put(ep); + if (ret) { + dev_err(cru->dev, "Failed to parse %pOF\n", to_of_node(fwnode)); + ret = -EINVAL; + goto out; + } + + if (!of_device_is_available(to_of_node(fwnode))) { + dev_dbg(cru->dev, "OF device %pOF disabled, ignoring\n", + to_of_node(fwnode)); + ret = -ENOTCONN; + goto out; + } + + asd = v4l2_async_notifier_add_fwnode_subdev(&cru->notifier, fwnode, + sizeof(*asd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto out; + } + + cru->csi.asd = asd; + + dev_dbg(cru->dev, "Added OF device %pOF to slot %u\n", + to_of_node(fwnode), vep.base.id); +out: + fwnode_handle_put(fwnode); + + return ret; +} + +static int rzg2l_cru_mc_parse_of_graph(struct rzg2l_cru_dev *cru) +{ + int ret; + + v4l2_async_notifier_init(&cru->notifier); + + ret = rzg2l_cru_mc_parse_of(cru); + if (ret) + return ret; + + cru->notifier.ops = &rzg2l_cru_async_ops; + + if (list_empty(&cru->notifier.asd_list)) + return 0; + + ret = v4l2_async_notifier_register(&cru->v4l2_dev, &cru->notifier); + if (ret < 0) { + dev_err(cru->dev, "Notifier registration failed\n"); + v4l2_async_notifier_cleanup(&cru->notifier); + return ret; + } + + return 0; +} + +static int rzg2l_cru_media_init(struct rzg2l_cru_dev *cru) +{ + struct media_device *mdev = NULL; + const struct of_device_id *match; + int ret; + + cru->pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_pads_init(&cru->vdev.entity, 1, &cru->pad); + if (ret) + return ret; + + mutex_init(&cru->mdev_lock); + mdev = &cru->mdev; + mdev->dev = cru->dev; + mdev->ops = &rzg2l_cru_media_ops; + + match = of_match_node(cru->dev->driver->of_match_table, + cru->dev->of_node); + + strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); + strscpy(mdev->model, match->compatible, sizeof(mdev->model)); + + cru->v4l2_dev.mdev = &cru->mdev; + + media_device_init(mdev); + + ret = rzg2l_cru_mc_parse_of_graph(cru); + if (ret) { + mutex_lock(&cru->mdev_lock); + cru->v4l2_dev.mdev = NULL; + mutex_unlock(&cru->mdev_lock); + } + + return 0; +} + +static int rzg2l_cru_probe(struct platform_device *pdev) +{ + struct rzg2l_cru_dev *cru; + int ret; + + cru = devm_kzalloc(&pdev->dev, sizeof(*cru), GFP_KERNEL); + if (!cru) + return -ENOMEM; + + cru->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(cru->base)) + return PTR_ERR(cru->base); + + cru->presetn = devm_reset_control_get_shared(&pdev->dev, "presetn"); + if (IS_ERR(cru->presetn)) + return dev_err_probe(&pdev->dev, PTR_ERR(cru->presetn), + "Failed to get cpg presetn\n"); + + cru->aresetn = devm_reset_control_get_exclusive(&pdev->dev, "aresetn"); + if (IS_ERR(cru->aresetn)) + return dev_err_probe(&pdev->dev, PTR_ERR(cru->aresetn), + "Failed to get cpg aresetn\n"); + + cru->vclk = devm_clk_get(&pdev->dev, "video"); + if (IS_ERR(cru->vclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(cru->vclk), + "Failed to get video clock\n"); + + cru->dev = &pdev->dev; + cru->info = of_device_get_match_data(&pdev->dev); + + cru->image_conv_irq = platform_get_irq(pdev, 0); + if (cru->image_conv_irq < 0) + return cru->image_conv_irq; + + platform_set_drvdata(pdev, cru); + + ret = rzg2l_cru_dma_register(cru); + if (ret) + return ret; + + cru->num_buf = RZG2L_CRU_HW_BUFFER_DEFAULT; + pm_suspend_ignore_children(&pdev->dev, true); + pm_runtime_enable(&pdev->dev); + + ret = rzg2l_cru_media_init(cru); + if (ret) + goto error_dma_unregister; + + return 0; + +error_dma_unregister: + rzg2l_cru_dma_unregister(cru); + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int rzg2l_cru_remove(struct platform_device *pdev) +{ + struct rzg2l_cru_dev *cru = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + + v4l2_async_notifier_unregister(&cru->notifier); + v4l2_async_notifier_cleanup(&cru->notifier); + + rzg2l_cru_video_unregister(cru); + media_device_cleanup(&cru->mdev); + mutex_destroy(&cru->mdev_lock); + + rzg2l_cru_dma_unregister(cru); + + return 0; +} + +static const struct of_device_id rzg2l_cru_of_id_table[] = { + { .compatible = "renesas,rzg2l-cru", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rzg2l_cru_of_id_table); + +static struct platform_driver rzg2l_cru_driver = { + .driver = { + .name = "rzg2l-cru", + .of_match_table = rzg2l_cru_of_id_table, + }, + .probe = rzg2l_cru_probe, + .remove = rzg2l_cru_remove, +}; + +module_platform_driver(rzg2l_cru_driver); + +MODULE_AUTHOR("Lad Prabhakar "); +MODULE_DESCRIPTION("Renesas RZ/G2L CRU driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h new file mode 100644 index 0000000000000..5b576d99bee88 --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Driver for Renesas RZ/G2L CRU + * + * Copyright (C) 2022 Renesas Electronics Corp. + */ + +#ifndef __RZG2L_CRU__ +#define __RZG2L_CRU__ + +#include + +#include +#include +#include +#include + +/* Number of HW buffers */ +#define RZG2L_CRU_HW_BUFFER_MAX 8 +#define RZG2L_CRU_HW_BUFFER_DEFAULT 3 + +/* Address alignment mask for HW buffers */ +#define RZG2L_CRU_HW_BUFFER_MASK 0x1ff + +/* Maximum number of CSI2 virtual channels */ +#define RZG2L_CRU_CSI2_VCHANNEL 4 + +#define RZG2L_CRU_MIN_INPUT_WIDTH 320 +#define RZG2L_CRU_MAX_INPUT_WIDTH 2800 +#define RZG2L_CRU_MIN_INPUT_HEIGHT 240 +#define RZG2L_CRU_MAX_INPUT_HEIGHT 4095 + +/** + * enum rzg2l_cru_dma_state - DMA states + * @RZG2L_CRU_DMA_STOPPED: No operation in progress + * @RZG2L_CRU_DMA_STARTING: Capture starting up + * @RZG2L_CRU_DMA_RUNNING: Operation in progress have buffers + * @RZG2L_CRU_DMA_STOPPING: Stopping operation + */ +enum rzg2l_cru_dma_state { + RZG2L_CRU_DMA_STOPPED = 0, + RZG2L_CRU_DMA_STARTING, + RZG2L_CRU_DMA_RUNNING, + RZG2L_CRU_DMA_STOPPING, +}; + +struct rzg2l_cru_csi { + struct v4l2_async_subdev *asd; + struct v4l2_subdev *subdev; + u32 channel; +}; + +struct rzg2l_cru_ip { + struct v4l2_subdev subdev; + struct media_pad pads[2]; + struct v4l2_mbus_framefmt mf; + struct v4l2_async_notifier notifier; + struct v4l2_subdev *remote; +}; + +/** + * struct rzg2l_cru_dev - Renesas CRU device structure + * @dev: (OF) device + * @base: device I/O register space remapped to virtual memory + * @info: info about CRU instance + * + * @presetn: CRU_PRESETN reset line + * @aresetn: CRU_ARESETN reset line + * + * @vclk: CRU Main clock + * + * @vdev: V4L2 video device associated with CRU + * @v4l2_dev: V4L2 device + * @num_buf: Holds the current number of buffers enabled + * @notifier: V4L2 asynchronous subdevs notifier + * + * @ip: Image processing subdev info + * @csi: CSI info + * @mdev: media device + * @mdev_lock: protects the count, notifier and csi members + * @pad: media pad for the video device entity + * + * @lock: protects @queue + * @queue: vb2 buffers queue + * @scratch: cpu address for scratch buffer + * @scratch_phys: physical address of the scratch buffer + * + * @qlock: protects @queue_buf, @buf_list, @sequence + * @state + * @queue_buf: Keeps track of buffers given to HW slot + * @buf_list: list of queued buffers + * @sequence: V4L2 buffers sequence number + * @state: keeps track of operation state + * + * @format: active V4L2 pixel format + */ +struct rzg2l_cru_dev { + struct device *dev; + void __iomem *base; + const struct rzg2l_cru_info *info; + + struct reset_control *presetn; + struct reset_control *aresetn; + + struct clk *vclk; + + int image_conv_irq; + + struct video_device vdev; + struct v4l2_device v4l2_dev; + u8 num_buf; + + struct v4l2_async_notifier notifier; + + struct rzg2l_cru_ip ip; + struct rzg2l_cru_csi csi; + struct media_device mdev; + struct mutex mdev_lock; + struct media_pad pad; + + struct mutex lock; + struct vb2_queue queue; + void *scratch; + dma_addr_t scratch_phys; + + spinlock_t qlock; + struct vb2_v4l2_buffer *queue_buf[RZG2L_CRU_HW_BUFFER_MAX]; + struct list_head buf_list; + unsigned int sequence; + enum rzg2l_cru_dma_state state; + + struct v4l2_pix_format format; +}; + +void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru); +int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru); + +int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru); +void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru); + +int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru); +void rzg2l_cru_dma_unregister(struct rzg2l_cru_dev *cru); + +int rzg2l_cru_video_register(struct rzg2l_cru_dev *cru); +void rzg2l_cru_video_unregister(struct rzg2l_cru_dev *cru); + +const struct v4l2_format_info *rzg2l_cru_format_from_pixel(u32 format); + +int rzg2l_cru_ip_subdev_register(struct rzg2l_cru_dev *cru); +void rzg2l_cru_ip_subdev_unregister(struct rzg2l_cru_dev *cru); +struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru); + +#endif diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c new file mode 100644 index 0000000000000..3a9f282a87bbb --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Renesas RZ/G2L CRU + * + * Copyright (C) 2022 Renesas Electronics Corp. + */ + +#include "rzg2l-cru.h" + +struct rzg2l_cru_ip_format { + u32 code; + unsigned int datatype; + unsigned int bpp; +}; + +static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { + { .code = MEDIA_BUS_FMT_UYVY8_2X8, .datatype = 0x1e, .bpp = 16 }, + { .code = MEDIA_BUS_FMT_UYVY8_1X16, .datatype = 0x1e, .bpp = 16 }, +}; + +enum rzg2l_csi2_pads { + RZG2L_CRU_IP_SINK = 0, + RZG2L_CRU_IP_SOURCE, +}; + +static inline struct rzg2l_cru_ip *sd_to_ip(struct v4l2_subdev *sd) +{ + return container_of(sd, struct rzg2l_cru_ip, subdev); +} + +static const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) + if (rzg2l_cru_ip_formats[i].code == code) + return &rzg2l_cru_ip_formats[i]; + + return NULL; +} + +struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru) +{ + return &cru->ip.mf; +} + +static int rzg2l_cru_ip_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct rzg2l_cru_dev *cru; + int s_stream_ret = 0; + int ret; + + cru = v4l2_get_subdevdata(sd); + + if (!enable) { + ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable); + if (ret) + s_stream_ret = ret; + + ret = v4l2_subdev_call(cru->ip.remote, video, post_streamoff); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret && !s_stream_ret) + s_stream_ret = ret; + rzg2l_cru_stop_image_processing(cru); + } else { + ret = v4l2_subdev_call(cru->ip.remote, video, pre_streamon, 0); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + return ret; + + ret = rzg2l_cru_start_image_processing(cru); + if (ret) { + v4l2_subdev_call(cru->ip.remote, video, post_streamoff); + return ret; + } + + rzg2l_cru_vclk_unprepare(cru); + + ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (!ret) { + ret = rzg2l_cru_vclk_prepare(cru); + if (!ret) + return 0; + } else { + /* enable back vclk so that s_stream in error path disables it */ + if (rzg2l_cru_vclk_prepare(cru)) + dev_err(cru->dev, "Failed to enable vclk\n"); + } + + s_stream_ret = ret; + + v4l2_subdev_call(cru->ip.remote, video, post_streamoff); + rzg2l_cru_stop_image_processing(cru); + } + + return s_stream_ret; +} + +static int rzg2l_cru_ip_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct rzg2l_cru_ip *ip = sd_to_ip(sd); + + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + else + fmt->format = ip->mf; + + return 0; +} + +static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct rzg2l_cru_ip *ip = sd_to_ip(sd); + struct v4l2_mbus_framefmt *src_format; + struct v4l2_mbus_framefmt *sink_format; + + src_format = v4l2_subdev_get_try_format(sd, cfg, RZG2L_CRU_IP_SOURCE); + if (fmt->pad == RZG2L_CRU_IP_SOURCE) { + fmt->format = *src_format; + return 0; + } + + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + ip->mf = fmt->format; + return 0; + } + + sink_format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + + if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code)) + sink_format->code = rzg2l_cru_ip_formats[0].code; + else + sink_format->code = fmt->format.code; + + fmt->format.field = V4L2_FIELD_NONE; + fmt->format.width = clamp_t(u32, fmt->format.width, + RZG2L_CRU_MIN_INPUT_WIDTH, RZG2L_CRU_MAX_INPUT_WIDTH); + fmt->format.height = clamp_t(u32, fmt->format.height, + RZG2L_CRU_MIN_INPUT_HEIGHT, RZG2L_CRU_MAX_INPUT_HEIGHT); + + *sink_format = fmt->format; + + /* propagate format to source pad */ + *src_format = *sink_format; + + return 0; +} + +static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats)) + return -EINVAL; + + code->code = rzg2l_cru_ip_formats[code->index].code; + return 0; +} + +static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index != 0) + return -EINVAL; + + if (!rzg2l_cru_ip_code_to_fmt(fse->code)) + return -EINVAL; + + fse->min_width = RZG2L_CRU_MIN_INPUT_WIDTH; + fse->min_height = RZG2L_CRU_MIN_INPUT_HEIGHT; + fse->max_width = RZG2L_CRU_MAX_INPUT_WIDTH; + fse->max_height = RZG2L_CRU_MAX_INPUT_HEIGHT; + + return 0; +} + +static int rzg2l_cru_ip_init_config(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_subdev_format fmt = { .pad = RZG2L_CRU_IP_SINK, }; + + fmt.format.width = RZG2L_CRU_MIN_INPUT_WIDTH; + fmt.format.height = RZG2L_CRU_MIN_INPUT_HEIGHT; + fmt.format.field = V4L2_FIELD_NONE; + fmt.format.code = MEDIA_BUS_FMT_UYVY8_1X16; + fmt.format.colorspace = V4L2_COLORSPACE_SRGB; + fmt.format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + fmt.format.quantization = V4L2_QUANTIZATION_DEFAULT; + fmt.format.xfer_func = V4L2_XFER_FUNC_DEFAULT; + + return rzg2l_cru_ip_set_format(sd, cfg, &fmt); +} + +static const struct v4l2_subdev_video_ops rzg2l_cru_ip_video_ops = { + .s_stream = rzg2l_cru_ip_s_stream, +}; + +static const struct v4l2_subdev_pad_ops rzg2l_cru_ip_pad_ops = { + .enum_mbus_code = rzg2l_cru_ip_enum_mbus_code, + .enum_frame_size = rzg2l_cru_ip_enum_frame_size, + .init_cfg = rzg2l_cru_ip_init_config, + .get_fmt = rzg2l_cru_ip_get_format, + .set_fmt = rzg2l_cru_ip_set_format, +}; + +static const struct v4l2_subdev_ops rzg2l_cru_ip_subdev_ops = { + .video = &rzg2l_cru_ip_video_ops, + .pad = &rzg2l_cru_ip_pad_ops, +}; + +static const struct media_entity_operations rzg2l_cru_ip_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +int rzg2l_cru_ip_subdev_register(struct rzg2l_cru_dev *cru) +{ + struct rzg2l_cru_ip *ip = &cru->ip; + int ret; + + ip->subdev.dev = cru->dev; + v4l2_subdev_init(&ip->subdev, &rzg2l_cru_ip_subdev_ops); + v4l2_set_subdevdata(&ip->subdev, cru); + snprintf(ip->subdev.name, sizeof(ip->subdev.name), + "cru-ip-%s", dev_name(cru->dev)); + ip->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + + ip->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; + ip->subdev.entity.ops = &rzg2l_cru_ip_entity_ops; + + ip->pads[0].flags = MEDIA_PAD_FL_SINK; + ip->pads[1].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&ip->subdev.entity, 2, ip->pads); + if (ret) + return ret; + + ret = v4l2_device_register_subdev(&cru->v4l2_dev, &ip->subdev); + if (ret < 0) + goto entity_cleanup; + + return 0; +entity_cleanup: + media_entity_cleanup(&ip->subdev.entity); + + return ret; +} + +void rzg2l_cru_ip_subdev_unregister(struct rzg2l_cru_dev *cru) +{ + struct rzg2l_cru_ip *ip = &cru->ip; + + media_entity_cleanup(&ip->subdev.entity); + v4l2_device_unregister_subdev(&ip->subdev); +} diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c new file mode 100644 index 0000000000000..b837050d9591e --- /dev/null +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -0,0 +1,1059 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for Renesas RZ/G2L CRU + * + * Copyright (C) 2022 Renesas Electronics Corp. + * + * Based on Renesas R-Car VIN + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2011-2013 Renesas Solutions Corp. + * Copyright (C) 2013 Cogent Embedded, Inc., + * Copyright (C) 2008 Magnus Damm + */ + +#include +#include +#include + +#include +#include + +#include "rzg2l-cru.h" + +/* HW CRU Registers Definition */ + +/* CRU Control Register */ +#define CRUnCTRL 0x0 +#define CRUnCTRL_VINSEL(x) ((x) << 0) + +/* CRU Interrupt Enable Register */ +#define CRUnIE 0x4 +#define CRUnIE_EFE BIT(17) + +/* CRU Interrupt Status Register */ +#define CRUnINTS 0x8 +#define CRUnINTS_SFS BIT(16) + +/* CRU Reset Register */ +#define CRUnRST 0xc +#define CRUnRST_VRESETN BIT(0) + +/* Memory Bank Base Address (Lower) Register for CRU Image Data */ +#define AMnMBxADDRL(x) (0x100 + ((x) * 8)) + +/* Memory Bank Base Address (Higher) Register for CRU Image Data */ +#define AMnMBxADDRH(x) (0x104 + ((x) * 8)) + +/* Memory Bank Enable Register for CRU Image Data */ +#define AMnMBVALID 0x148 +#define AMnMBVALID_MBVALID(x) GENMASK(x, 0) + +/* Memory Bank Status Register for CRU Image Data */ +#define AMnMBS 0x14c +#define AMnMBS_MBSTS 0x7 + +/* AXI Master FIFO Pointer Register for CRU Image Data */ +#define AMnFIFOPNTR 0x168 +#define AMnFIFOPNTR_FIFOWPNTR GENMASK(7, 0) +#define AMnFIFOPNTR_FIFORPNTR_Y GENMASK(23, 16) + +/* AXI Master Transfer Stop Register for CRU Image Data */ +#define AMnAXISTP 0x174 +#define AMnAXISTP_AXI_STOP BIT(0) + +/* AXI Master Transfer Stop Status Register for CRU Image Data */ +#define AMnAXISTPACK 0x178 +#define AMnAXISTPACK_AXI_STOP_ACK BIT(0) + +/* CRU Image Processing Enable Register */ +#define ICnEN 0x200 +#define ICnEN_ICEN BIT(0) + +/* CRU Image Processing Main Control Register */ +#define ICnMC 0x208 +#define ICnMC_CSCTHR BIT(5) +#define ICnMC_INF_YUV8_422 (0x1e << 16) +#define ICnMC_INF_USER (0x30 << 16) +#define ICnMC_VCSEL(x) ((x) << 22) +#define ICnMC_INF_MASK GENMASK(21, 16) + +/* CRU Module Status Register */ +#define ICnMS 0x254 +#define ICnMS_IA BIT(2) + +/* CRU Data Output Mode Register */ +#define ICnDMR 0x26c +#define ICnDMR_YCMODE_UYVY (1 << 4) + +#define RZG2L_TIMEOUT_MS 100 +#define RZG2L_RETRIES 10 + +#define RZG2L_CRU_DEFAULT_FORMAT V4L2_PIX_FMT_UYVY +#define RZG2L_CRU_DEFAULT_WIDTH RZG2L_CRU_MIN_INPUT_WIDTH +#define RZG2L_CRU_DEFAULT_HEIGHT RZG2L_CRU_MIN_INPUT_HEIGHT +#define RZG2L_CRU_DEFAULT_FIELD V4L2_FIELD_NONE +#define RZG2L_CRU_DEFAULT_COLORSPACE V4L2_COLORSPACE_SRGB + +struct rzg2l_cru_buffer { + struct vb2_v4l2_buffer vb; + struct list_head list; +}; + +#define to_buf_list(vb2_buffer) \ + (&container_of(vb2_buffer, struct rzg2l_cru_buffer, vb)->list) + +/* ----------------------------------------------------------------------------- + * DMA operations + */ +static void rzg2l_cru_write(struct rzg2l_cru_dev *cru, u32 offset, u32 value) +{ + iowrite32(value, cru->base + offset); +} + +static u32 rzg2l_cru_read(struct rzg2l_cru_dev *cru, u32 offset) +{ + return ioread32(cru->base + offset); +} + +/* Need to hold qlock before calling */ +static void return_unused_buffers(struct rzg2l_cru_dev *cru, + enum vb2_buffer_state state) +{ + struct rzg2l_cru_buffer *buf, *node; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&cru->qlock, flags); + for (i = 0; i < cru->num_buf; i++) { + if (cru->queue_buf[i]) { + vb2_buffer_done(&cru->queue_buf[i]->vb2_buf, + state); + cru->queue_buf[i] = NULL; + } + } + + list_for_each_entry_safe(buf, node, &cru->buf_list, list) { + vb2_buffer_done(&buf->vb.vb2_buf, state); + list_del(&buf->list); + } + spin_unlock_irqrestore(&cru->qlock, flags); +} + +static int rzg2l_cru_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, + unsigned int *nplanes, unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); + + /* Make sure the image size is large enough. */ + if (*nplanes) + return sizes[0] < cru->format.sizeimage ? -EINVAL : 0; + + *nplanes = 1; + sizes[0] = cru->format.sizeimage; + + return 0; +}; + +static int rzg2l_cru_buffer_prepare(struct vb2_buffer *vb) +{ + struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vb->vb2_queue); + unsigned long size = cru->format.sizeimage; + + if (vb2_plane_size(vb, 0) < size) { + dev_err(cru->dev, "buffer too small (%lu < %lu)\n", + vb2_plane_size(vb, 0), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, 0, size); + + return 0; +} + +static void rzg2l_cru_buffer_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vb->vb2_queue); + unsigned long flags; + + spin_lock_irqsave(&cru->qlock, flags); + + list_add_tail(to_buf_list(vbuf), &cru->buf_list); + + spin_unlock_irqrestore(&cru->qlock, flags); +} + +static int rzg2l_cru_mc_validate_format(struct rzg2l_cru_dev *cru, + struct v4l2_subdev *sd, + struct media_pad *pad) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + fmt.pad = pad->index; + if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) + return -EPIPE; + + switch (fmt.format.code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: + break; + default: + return -EPIPE; + } + + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + break; + default: + return -EPIPE; + } + + if (fmt.format.width != cru->format.width || + fmt.format.height != cru->format.height) + return -EPIPE; + + return 0; +} + +static void rzg2l_cru_set_slot_addr(struct rzg2l_cru_dev *cru, + int slot, dma_addr_t addr) +{ + /* + * The address needs to be 512 bytes aligned. Driver should never accept + * settings that do not satisfy this in the first place... + */ + if (WARN_ON((addr) & RZG2L_CRU_HW_BUFFER_MASK)) + return; + + /* Currently, we just use the buffer in 32 bits address */ + rzg2l_cru_write(cru, AMnMBxADDRL(slot), addr); + rzg2l_cru_write(cru, AMnMBxADDRH(slot), 0); +} + +/* + * Moves a buffer from the queue to the HW slot. If no buffer is + * available use the scratch buffer. The scratch buffer is never + * returned to userspace, its only function is to enable the capture + * loop to keep running. + */ +static void rzg2l_cru_fill_hw_slot(struct rzg2l_cru_dev *cru, int slot) +{ + struct vb2_v4l2_buffer *vbuf; + struct rzg2l_cru_buffer *buf; + dma_addr_t phys_addr; + + /* A already populated slot shall never be overwritten. */ + if (WARN_ON(cru->queue_buf[slot])) + return; + + dev_dbg(cru->dev, "Filling HW slot: %d\n", slot); + + if (list_empty(&cru->buf_list)) { + cru->queue_buf[slot] = NULL; + phys_addr = cru->scratch_phys; + } else { + /* Keep track of buffer we give to HW */ + buf = list_entry(cru->buf_list.next, + struct rzg2l_cru_buffer, list); + vbuf = &buf->vb; + list_del_init(to_buf_list(vbuf)); + cru->queue_buf[slot] = vbuf; + + /* Setup DMA */ + phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); + } + + rzg2l_cru_set_slot_addr(cru, slot, phys_addr); +} + +static void rzg2l_cru_initialize_axi(struct rzg2l_cru_dev *cru) +{ + unsigned int slot; + + /* + * Set image data memory banks. + * Currently, we will use maximum address. + */ + rzg2l_cru_write(cru, AMnMBVALID, AMnMBVALID_MBVALID(cru->num_buf - 1)); + + for (slot = 0; slot < cru->num_buf; slot++) + rzg2l_cru_fill_hw_slot(cru, slot); +} + +static void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru, bool *input_is_yuv, + struct v4l2_mbus_framefmt *ip_sd_fmt) +{ + u32 icnmc; + + switch (ip_sd_fmt->code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: + icnmc = ICnMC_INF_YUV8_422; + *input_is_yuv = true; + break; + default: + *input_is_yuv = false; + icnmc = ICnMC_INF_USER; + break; + } + + icnmc |= (rzg2l_cru_read(cru, ICnMC) & ~ICnMC_INF_MASK); + + /* Set virtual channel CSI2 */ + icnmc |= ICnMC_VCSEL(cru->csi.channel); + + rzg2l_cru_write(cru, ICnMC, icnmc); +} + +static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru, + struct v4l2_mbus_framefmt *ip_sd_fmt) +{ + bool output_is_yuv = false; + bool input_is_yuv = false; + u32 icndmr; + + rzg2l_cru_csi2_setup(cru, &input_is_yuv, ip_sd_fmt); + + /* Output format */ + switch (cru->format.pixelformat) { + case V4L2_PIX_FMT_UYVY: + icndmr = ICnDMR_YCMODE_UYVY; + output_is_yuv = true; + break; + default: + dev_err(cru->dev, "Invalid pixelformat (0x%x)\n", + cru->format.pixelformat); + return -EINVAL; + } + + /* If input and output use same colorspace, do bypass mode */ + if (output_is_yuv == input_is_yuv) + rzg2l_cru_write(cru, ICnMC, + rzg2l_cru_read(cru, ICnMC) | ICnMC_CSCTHR); + else + rzg2l_cru_write(cru, ICnMC, + rzg2l_cru_read(cru, ICnMC) & (~ICnMC_CSCTHR)); + + /* Set output data format */ + rzg2l_cru_write(cru, ICnDMR, icndmr); + + return 0; +} + +void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru) +{ + u32 amnfifopntr, amnfifopntr_w, amnfifopntr_r_y; + unsigned int retries = 0; + unsigned long flags; + u32 icnms; + + spin_lock_irqsave(&cru->qlock, flags); + + /* Disable and clear the interrupt */ + rzg2l_cru_write(cru, CRUnIE, 0); + rzg2l_cru_write(cru, CRUnINTS, 0x001F0F0F); + + /* Stop the operation of image conversion */ + rzg2l_cru_write(cru, ICnEN, 0); + + /* Wait for streaming to stop */ + while ((rzg2l_cru_read(cru, ICnMS) & ICnMS_IA) && retries++ < RZG2L_RETRIES) { + spin_unlock_irqrestore(&cru->qlock, flags); + msleep(RZG2L_TIMEOUT_MS); + spin_lock_irqsave(&cru->qlock, flags); + } + + icnms = rzg2l_cru_read(cru, ICnMS) & ICnMS_IA; + if (icnms) + dev_err(cru->dev, "Failed stop HW, something is seriously broken\n"); + + cru->state = RZG2L_CRU_DMA_STOPPED; + + /* Wait until the FIFO becomes empty */ + for (retries = 5; retries > 0; retries--) { + amnfifopntr = rzg2l_cru_read(cru, AMnFIFOPNTR); + + amnfifopntr_w = amnfifopntr & AMnFIFOPNTR_FIFOWPNTR; + amnfifopntr_r_y = + (amnfifopntr & AMnFIFOPNTR_FIFORPNTR_Y) >> 16; + if (amnfifopntr_w == amnfifopntr_r_y) + break; + + usleep_range(10, 20); + } + + /* Notify that FIFO is not empty here */ + if (!retries) + dev_err(cru->dev, "Failed to empty FIFO\n"); + + /* Stop AXI bus */ + rzg2l_cru_write(cru, AMnAXISTP, AMnAXISTP_AXI_STOP); + + /* Wait until the AXI bus stop */ + for (retries = 5; retries > 0; retries--) { + if (rzg2l_cru_read(cru, AMnAXISTPACK) & + AMnAXISTPACK_AXI_STOP_ACK) + break; + + usleep_range(10, 20); + }; + + /* Notify that AXI bus can not stop here */ + if (!retries) + dev_err(cru->dev, "Failed to stop AXI bus\n"); + + /* Cancel the AXI bus stop request */ + rzg2l_cru_write(cru, AMnAXISTP, 0); + + /* Reset the CRU (AXI-master) */ + reset_control_assert(cru->aresetn); + + /* Resets the image processing module */ + rzg2l_cru_write(cru, CRUnRST, 0); + + spin_unlock_irqrestore(&cru->qlock, flags); +} + +int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru) +{ + struct v4l2_mbus_framefmt *fmt = rzg2l_cru_ip_get_src_fmt(cru); + unsigned long flags; + int ret; + + spin_lock_irqsave(&cru->qlock, flags); + + /* Initialize image convert */ + ret = rzg2l_cru_initialize_image_conv(cru, fmt); + if (ret) { + spin_unlock_irqrestore(&cru->qlock, flags); + return ret; + } + + /* Select a video input */ + rzg2l_cru_write(cru, CRUnCTRL, CRUnCTRL_VINSEL(0)); + + /* Cancel the software reset for image processing block */ + rzg2l_cru_write(cru, CRUnRST, CRUnRST_VRESETN); + + /* Disable and clear the interrupt before using */ + rzg2l_cru_write(cru, CRUnIE, 0); + rzg2l_cru_write(cru, CRUnINTS, 0x001f000f); + + /* Initialize the AXI master */ + rzg2l_cru_initialize_axi(cru); + + /* Enable interrupt */ + rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE); + + /* Enable image processing reception */ + rzg2l_cru_write(cru, ICnEN, ICnEN_ICEN); + + spin_unlock_irqrestore(&cru->qlock, flags); + + return 0; +} + +void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru) +{ + clk_disable_unprepare(cru->vclk); +} + +int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru) +{ + return clk_prepare_enable(cru->vclk); +} + +static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on) +{ + struct media_pipeline *pipe; + struct v4l2_subdev *sd; + struct media_pad *pad; + int ret; + + pad = media_entity_remote_pad(&cru->pad); + if (!pad) + return -EPIPE; + + sd = media_entity_to_v4l2_subdev(pad->entity); + + if (!on) { + int stream_off_ret = 0; + + ret = v4l2_subdev_call(sd, video, s_stream, 0); + if (ret) + stream_off_ret = ret; + + ret = v4l2_subdev_call(sd, video, post_streamoff); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret && !stream_off_ret) + stream_off_ret = ret; + + media_pipeline_stop(&cru->vdev.entity); + + pm_runtime_put_sync(cru->dev); + clk_disable_unprepare(cru->vclk); + + return stream_off_ret; + } + + ret = pm_runtime_resume_and_get(cru->dev); + if (ret) + return ret; + + ret = clk_prepare_enable(cru->vclk); + if (ret) + goto err_pm_put; + + ret = rzg2l_cru_mc_validate_format(cru, sd, pad); + if (ret) + goto err_vclk_disable; + + pipe = sd->entity.pipe ? : &cru->vdev.pipe; + ret = media_pipeline_start(&cru->vdev.entity, pipe); + if (ret) + goto err_vclk_disable; + + ret = v4l2_subdev_call(sd, video, pre_streamon, 0); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + goto pipe_line_stop; + + ret = v4l2_subdev_call(sd, video, s_stream, 1); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + goto err_s_stream; + + return 0; + +err_s_stream: + v4l2_subdev_call(sd, video, post_streamoff); + +pipe_line_stop: + media_pipeline_stop(&cru->vdev.entity); + +err_vclk_disable: + clk_disable_unprepare(cru->vclk); + +err_pm_put: + pm_runtime_put_sync(cru->dev); + + return ret; +} + +static void rzg2l_cru_stop_streaming(struct rzg2l_cru_dev *cru) +{ + cru->state = RZG2L_CRU_DMA_STOPPING; + + rzg2l_cru_set_stream(cru, 0); +} + +static irqreturn_t rzg2l_cru_irq(int irq, void *data) +{ + struct rzg2l_cru_dev *cru = data; + unsigned int handled = 0; + unsigned long flags; + u32 irq_status; + u32 amnmbs; + int slot; + + spin_lock_irqsave(&cru->qlock, flags); + + irq_status = rzg2l_cru_read(cru, CRUnINTS); + if (!irq_status) + goto done; + + handled = 1; + + rzg2l_cru_write(cru, CRUnINTS, rzg2l_cru_read(cru, CRUnINTS)); + + /* Nothing to do if capture status is 'RZG2L_CRU_DMA_STOPPED' */ + if (cru->state == RZG2L_CRU_DMA_STOPPED) { + dev_dbg(cru->dev, "IRQ while state stopped\n"); + goto done; + } + + /* Increase stop retries if capture status is 'RZG2L_CRU_DMA_STOPPING' */ + if (cru->state == RZG2L_CRU_DMA_STOPPING) { + if (irq_status & CRUnINTS_SFS) + dev_dbg(cru->dev, "IRQ while state stopping\n"); + goto done; + } + + /* Prepare for capture and update state */ + amnmbs = rzg2l_cru_read(cru, AMnMBS); + slot = amnmbs & AMnMBS_MBSTS; + + /* + * AMnMBS.MBSTS indicates the destination of Memory Bank (MB). + * Recalculate to get the current transfer complete MB. + */ + if (slot == 0) + slot = cru->num_buf - 1; + else + slot--; + + /* + * To hand buffers back in a known order to userspace start + * to capture first from slot 0. + */ + if (cru->state == RZG2L_CRU_DMA_STARTING) { + if (slot != 0) { + dev_dbg(cru->dev, "Starting sync slot: %d\n", slot); + goto done; + } + + dev_dbg(cru->dev, "Capture start synced!\n"); + cru->state = RZG2L_CRU_DMA_RUNNING; + } + + /* Capture frame */ + if (cru->queue_buf[slot]) { + cru->queue_buf[slot]->field = cru->format.field; + cru->queue_buf[slot]->sequence = cru->sequence; + cru->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); + vb2_buffer_done(&cru->queue_buf[slot]->vb2_buf, + VB2_BUF_STATE_DONE); + cru->queue_buf[slot] = NULL; + } else { + /* Scratch buffer was used, dropping frame. */ + dev_dbg(cru->dev, "Dropping frame %u\n", cru->sequence); + } + + cru->sequence++; + + /* Prepare for next frame */ + rzg2l_cru_fill_hw_slot(cru, slot); + +done: + spin_unlock_irqrestore(&cru->qlock, flags); + + return IRQ_RETVAL(handled); +} + +static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count) +{ + struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); + int ret; + + /* Release reset state */ + ret = reset_control_deassert(cru->aresetn); + if (ret) { + dev_err(cru->dev, "failed to deassert aresetn\n"); + return ret; + } + + ret = reset_control_deassert(cru->presetn); + if (ret) { + reset_control_assert(cru->aresetn); + dev_err(cru->dev, "failed to deassert presetn\n"); + return ret; + } + + ret = request_irq(cru->image_conv_irq, rzg2l_cru_irq, + IRQF_SHARED, KBUILD_MODNAME, cru); + if (ret) { + dev_err(cru->dev, "failed to request irq\n"); + goto assert_resets; + } + + /* Allocate scratch buffer. */ + cru->scratch = dma_alloc_coherent(cru->dev, cru->format.sizeimage, + &cru->scratch_phys, GFP_KERNEL); + if (!cru->scratch) { + return_unused_buffers(cru, VB2_BUF_STATE_QUEUED); + dev_err(cru->dev, "Failed to allocate scratch buffer\n"); + goto free_image_conv_irq; + } + + cru->sequence = 0; + + ret = rzg2l_cru_set_stream(cru, 1); + if (ret) { + return_unused_buffers(cru, VB2_BUF_STATE_QUEUED); + goto out; + } + + cru->state = RZG2L_CRU_DMA_STARTING; + dev_dbg(cru->dev, "Starting to capture\n"); + return 0; + +out: + if (ret) + dma_free_coherent(cru->dev, cru->format.sizeimage, cru->scratch, + cru->scratch_phys); +free_image_conv_irq: + free_irq(cru->image_conv_irq, cru); + +assert_resets: + reset_control_assert(cru->presetn); + reset_control_assert(cru->aresetn); + + return ret; +} + +static void rzg2l_cru_stop_streaming_vq(struct vb2_queue *vq) +{ + struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); + + rzg2l_cru_stop_streaming(cru); + + /* Free scratch buffer */ + dma_free_coherent(cru->dev, cru->format.sizeimage, + cru->scratch, cru->scratch_phys); + + free_irq(cru->image_conv_irq, cru); + reset_control_assert(cru->presetn); + + return_unused_buffers(cru, VB2_BUF_STATE_ERROR); +} + +static const struct vb2_ops rzg2l_cru_qops = { + .queue_setup = rzg2l_cru_queue_setup, + .buf_prepare = rzg2l_cru_buffer_prepare, + .buf_queue = rzg2l_cru_buffer_queue, + .start_streaming = rzg2l_cru_start_streaming_vq, + .stop_streaming = rzg2l_cru_stop_streaming_vq, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +void rzg2l_cru_dma_unregister(struct rzg2l_cru_dev *cru) +{ + mutex_destroy(&cru->lock); + + v4l2_device_unregister(&cru->v4l2_dev); + vb2_queue_release(&cru->queue); +} + +int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru) +{ + struct vb2_queue *q = &cru->queue; + unsigned int i; + int ret; + + /* Initialize the top-level structure */ + ret = v4l2_device_register(cru->dev, &cru->v4l2_dev); + if (ret) + return ret; + + mutex_init(&cru->lock); + INIT_LIST_HEAD(&cru->buf_list); + + spin_lock_init(&cru->qlock); + + cru->state = RZG2L_CRU_DMA_STOPPED; + + for (i = 0; i < RZG2L_CRU_HW_BUFFER_MAX; i++) + cru->queue_buf[i] = NULL; + + /* buffer queue */ + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_DMABUF; + q->lock = &cru->lock; + q->drv_priv = cru; + q->buf_struct_size = sizeof(struct rzg2l_cru_buffer); + q->ops = &rzg2l_cru_qops; + q->mem_ops = &vb2_dma_contig_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 4; + q->dev = cru->dev; + + ret = vb2_queue_init(q); + if (ret < 0) { + dev_err(cru->dev, "failed to initialize VB2 queue\n"); + goto error; + } + + return 0; + +error: + mutex_destroy(&cru->lock); + v4l2_device_unregister(&cru->v4l2_dev); + return ret; +} + +/* ----------------------------------------------------------------------------- + * V4L2 stuff + */ + +static const struct v4l2_format_info rzg2l_cru_formats[] = { + { + .format = V4L2_PIX_FMT_UYVY, + .bpp[0] = 2, + }, +}; + +const struct v4l2_format_info *rzg2l_cru_format_from_pixel(u32 format) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_formats); i++) + if (rzg2l_cru_formats[i].format == format) + return rzg2l_cru_formats + i; + + return NULL; +} + +static u32 rzg2l_cru_format_bytesperline(struct v4l2_pix_format *pix) +{ + const struct v4l2_format_info *fmt; + + fmt = rzg2l_cru_format_from_pixel(pix->pixelformat); + + if (WARN_ON(!fmt)) + return -EINVAL; + + return pix->width * fmt->bpp[0]; +} + +static u32 rzg2l_cru_format_sizeimage(struct v4l2_pix_format *pix) +{ + return pix->bytesperline * pix->height; +} + +static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, + struct v4l2_pix_format *pix) +{ + if (!rzg2l_cru_format_from_pixel(pix->pixelformat)) + pix->pixelformat = RZG2L_CRU_DEFAULT_FORMAT; + + switch (pix->field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + default: + pix->field = RZG2L_CRU_DEFAULT_FIELD; + break; + } + + /* Limit to CRU capabilities */ + v4l_bound_align_image(&pix->width, 320, RZG2L_CRU_MAX_INPUT_WIDTH, 1, + &pix->height, 240, RZG2L_CRU_MAX_INPUT_HEIGHT, 2, 0); + + pix->bytesperline = rzg2l_cru_format_bytesperline(pix); + pix->sizeimage = rzg2l_cru_format_sizeimage(pix); + + dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); +} + +static void rzg2l_cru_try_format(struct rzg2l_cru_dev *cru, + struct v4l2_pix_format *pix) +{ + /* + * The V4L2 specification clearly documents the colorspace fields + * as being set by drivers for capture devices. Using the values + * supplied by userspace thus wouldn't comply with the API. Until + * the API is updated force fixed values. + */ + pix->colorspace = RZG2L_CRU_DEFAULT_COLORSPACE; + pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace); + pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace); + pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace, + pix->ycbcr_enc); + + rzg2l_cru_format_align(cru, pix); +} + +static int rzg2l_cru_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strscpy(cap->card, "RZG2L_CRU", sizeof(cap->card)); + + return 0; +} + +static int rzg2l_cru_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rzg2l_cru_dev *cru = video_drvdata(file); + + rzg2l_cru_try_format(cru, &f->fmt.pix); + + return 0; +} + +static int rzg2l_cru_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rzg2l_cru_dev *cru = video_drvdata(file); + + if (vb2_is_busy(&cru->queue)) + return -EBUSY; + + rzg2l_cru_try_format(cru, &f->fmt.pix); + + cru->format = f->fmt.pix; + + return 0; +} + +static int rzg2l_cru_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rzg2l_cru_dev *cru = video_drvdata(file); + + f->fmt.pix = cru->format; + + return 0; +} + +static int rzg2l_cru_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->index >= ARRAY_SIZE(rzg2l_cru_formats)) + return -EINVAL; + + f->pixelformat = rzg2l_cru_formats[f->index].format; + + return 0; +} + +static const struct v4l2_ioctl_ops rzg2l_cru_ioctl_ops = { + .vidioc_querycap = rzg2l_cru_querycap, + .vidioc_try_fmt_vid_cap = rzg2l_cru_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = rzg2l_cru_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = rzg2l_cru_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = rzg2l_cru_enum_fmt_vid_cap, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, +}; + +/* ----------------------------------------------------------------------------- + * Media controller file operations + */ + +static int rzg2l_cru_open(struct file *file) +{ + struct rzg2l_cru_dev *cru = video_drvdata(file); + int ret; + + ret = mutex_lock_interruptible(&cru->lock); + if (ret) + return ret; + + file->private_data = cru; + ret = v4l2_fh_open(file); + if (ret) + goto err_unlock; + + mutex_unlock(&cru->lock); + + return 0; + +err_unlock: + mutex_unlock(&cru->lock); + + return ret; +} + +static int rzg2l_cru_release(struct file *file) +{ + struct rzg2l_cru_dev *cru = video_drvdata(file); + int ret; + + mutex_lock(&cru->lock); + + /* the release helper will cleanup any on-going streaming. */ + ret = _vb2_fop_release(file, NULL); + + mutex_unlock(&cru->lock); + + return ret; +} + +static const struct v4l2_file_operations rzg2l_cru_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = video_ioctl2, + .open = rzg2l_cru_open, + .release = rzg2l_cru_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .read = vb2_fop_read, +}; + +static void rzg2l_cru_v4l2_init(struct rzg2l_cru_dev *cru) +{ + struct video_device *vdev = &cru->vdev; + + vdev->v4l2_dev = &cru->v4l2_dev; + vdev->queue = &cru->queue; + snprintf(vdev->name, sizeof(vdev->name), "CRU output"); + vdev->release = video_device_release_empty; + vdev->lock = &cru->lock; + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + vdev->device_caps |= V4L2_CAP_IO_MC; + vdev->fops = &rzg2l_cru_fops; + vdev->ioctl_ops = &rzg2l_cru_ioctl_ops; + + /* Set a default format */ + cru->format.pixelformat = RZG2L_CRU_DEFAULT_FORMAT; + cru->format.width = RZG2L_CRU_DEFAULT_WIDTH; + cru->format.height = RZG2L_CRU_DEFAULT_HEIGHT; + cru->format.field = RZG2L_CRU_DEFAULT_FIELD; + cru->format.colorspace = RZG2L_CRU_DEFAULT_COLORSPACE; + rzg2l_cru_format_align(cru, &cru->format); +} + +void rzg2l_cru_video_unregister(struct rzg2l_cru_dev *cru) +{ + media_device_unregister(&cru->mdev); + video_unregister_device(&cru->vdev); +} + +int rzg2l_cru_video_register(struct rzg2l_cru_dev *cru) +{ + struct video_device *vdev = &cru->vdev; + int ret; + + if (video_is_registered(&cru->vdev)) { + struct media_entity *entity; + + entity = &cru->vdev.entity; + if (!entity->graph_obj.mdev) + entity->graph_obj.mdev = &cru->mdev; + return 0; + } + + rzg2l_cru_v4l2_init(cru); + video_set_drvdata(vdev, cru); + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); + if (ret) { + dev_err(cru->dev, "Failed to register video device\n"); + return ret; + } + + ret = media_device_register(&cru->mdev); + if (ret) { + video_unregister_device(&cru->vdev); + return ret; + } + + return 0; +} From patchwork Mon Oct 28 20:03:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED518D3E2D1 for ; Mon, 28 Oct 2024 20:04:24 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2537.1730145853990506462 for ; Mon, 28 Oct 2024 13:04:22 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219301" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:22 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 9786A408CD3A; Tue, 29 Oct 2024 05:04:13 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 12/27] media: rzg2l-cru: Remove unnecessary shadowing of ret in rzg2l_csi2_s_stream() Date: Mon, 28 Oct 2024 20:03:34 +0000 Message-ID: <20241028200349.9620-13-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:24 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17096 From: Nathan Chancellor commit 1aba7930c63ea57b4918dc61dcc315f451cec21e upstream. Clang warns: drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:445:7: error: variable 'ret' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] if (ret) ^~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:475:9: note: uninitialized use occurs here return ret; ^~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:445:3: note: remove the 'if' if its condition is always false if (ret) ^~~~~~~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:441:7: error: variable 'ret' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] if (ret) ^~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:475:9: note: uninitialized use occurs here return ret; ^~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:441:3: note: remove the 'if' if its condition is always false if (ret) ^~~~~~~~ drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:431:9: note: initialize the variable 'ret' to silence this warning int ret; ^ = 0 2 errors generated. ret is unnecessarily shadowed, meaning the assignments to ret within the first 'if (enable)' block are only applied to the inner scope, not the outer one as intended. Remove the shadowing to fix the warnings and make everything work correctly. Link: https://github.com/ClangBuiltLinux/linux/issues/1764 Fixes: 51e8415e39a9 ("media: platform: Add Renesas RZ/G2L MIPI CSI-2 receiver driver") Signed-off-by: Nathan Chancellor Reviewed-by: Lad Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index 40e105613bc99..306c5d3a9fb6e 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -428,8 +428,6 @@ static int rzg2l_csi2_s_stream(struct v4l2_subdev *sd, int enable) int ret; if (enable) { - int ret; - ret = pm_runtime_resume_and_get(csi2->dev); if (ret) return ret; From patchwork Mon Oct 28 20:03:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854008 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E74D9D3E2D2 for ; Mon, 28 Oct 2024 20:04:24 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2567.1730145862871518952 for ; Mon, 28 Oct 2024 13:04:23 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233453" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:22 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 812BD408CD1D; Tue, 29 Oct 2024 05:04:15 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 13/27] media: platform: renesas: rzg2l-cru: Add missing documentation for image_conv_irq Date: Mon, 28 Oct 2024 20:03:35 +0000 Message-ID: <20241028200349.9620-14-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:24 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17097 commit 7de53a06ea6899e14786eba17d40e853cad6680b upstream. Add missing documentation for image_conv_irq element in struct rzg2l_cru_dev. Documentation needed to avoid build warning with W=1 builds. It doesn't really add any non obvious information but good to have it anyway. Reported-by: Hans Verkuil Signed-off-by: Lad Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h index 5b576d99bee88..e376f06ca3e22 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -69,6 +69,8 @@ struct rzg2l_cru_ip { * * @vclk: CRU Main clock * + * @image_conv_irq: Holds image conversion interrupt number + * * @vdev: V4L2 video device associated with CRU * @v4l2_dev: V4L2 device * @num_buf: Holds the current number of buffers enabled From patchwork Mon Oct 28 20:03:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854011 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EB6AD3E2D8 for ; Mon, 28 Oct 2024 20:04:25 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2537.1730145853990506462 for ; Mon, 28 Oct 2024 13:04:19 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219286" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:18 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 5D702408D425; Tue, 29 Oct 2024 05:04:17 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 14/27] media: rzg2l-cru: Fix missing error code in rzg2l_cru_start_streaming_vq() Date: Mon, 28 Oct 2024 20:03:36 +0000 Message-ID: <20241028200349.9620-15-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:25 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17094 From: Jiapeng Chong commit e54334cdf86960cc781a6d457fbad1277ca4267c upstream. Failed to allocate scratch buffer, add the error code '-ENOMEM' to the return value 'ret'. drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c:676 rzg2l_cru_start_streaming_vq() warn: missing error code 'ret'. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3275 Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index b837050d9591e..0f50dcc713217 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -675,6 +675,7 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count if (!cru->scratch) { return_unused_buffers(cru, VB2_BUF_STATE_QUEUED); dev_err(cru->dev, "Failed to allocate scratch buffer\n"); + ret = -ENOMEM; goto free_image_conv_irq; } From patchwork Mon Oct 28 20:03:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854009 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01EB9D3E2D6 for ; Mon, 28 Oct 2024 20:04:25 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2537.1730145853990506462 for ; Mon, 28 Oct 2024 13:04:21 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219295" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:20 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 45FBD408D216; Tue, 29 Oct 2024 05:04:19 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 15/27] media: rzg2l-cru: fix a test for timeout Date: Mon, 28 Oct 2024 20:03:37 +0000 Message-ID: <20241028200349.9620-16-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:25 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17095 From: Dan Carpenter commit 94ae11885fae1717f2017cb96ceef5d0f6d6dd4a upstream. The test for if the loop timed out is wrong and Smatch complains: drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:411 rzg2l_csi2_mipi_link_disable() warn: should this be 'timeout == -1' Let's change it to a preop loop instead of a post op loop. Fixes: 51e8415e39a9 ("media: platform: Add Renesas RZ/G2L MIPI CSI-2 receiver driver") Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index 306c5d3a9fb6e..e73c44385cd5e 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -399,7 +399,7 @@ static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) rzg2l_csi2_write(csi2, CSI2nRTCT, CSI2nRTCT_VSRST); /* Make sure CSI2nRTST.VSRSTS bit is cleared */ - while (timeout--) { + while (--timeout) { if (!(rzg2l_csi2_read(csi2, CSI2nRTST) & CSI2nRTST_VSRSTS)) break; usleep_range(100, 200); From patchwork Mon Oct 28 20:03:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854012 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14316D3E2D5 for ; Mon, 28 Oct 2024 20:04:25 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2567.1730145862871518952 for ; Mon, 28 Oct 2024 13:04:23 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233456" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:22 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 23CA5408D216; Tue, 29 Oct 2024 05:04:20 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 16/27] media: rzg2l-cru: Remove unneeded semicolon Date: Mon, 28 Oct 2024 20:03:38 +0000 Message-ID: <20241028200349.9620-17-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:25 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17099 From: Yang Li commit 7206fcc59399729667260d58c63e3db4503ac511 upstream. ./drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c:409:2-3: Unneeded semicolon ./drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c:407:2-3: Unneeded semicolon Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3273 Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 2 +- drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index e73c44385cd5e..b413ad7ff6388 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -403,7 +403,7 @@ static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) if (!(rzg2l_csi2_read(csi2, CSI2nRTST) & CSI2nRTST_VSRSTS)) break; usleep_range(100, 200); - }; + } if (!timeout) dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n"); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index 0f50dcc713217..1ab0cc741c05b 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -406,7 +406,7 @@ void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru) break; usleep_range(10, 20); - }; + } /* Notify that AXI bus can not stop here */ if (!retries) From patchwork Mon Oct 28 20:03:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1196BD3E2CF for ; Mon, 28 Oct 2024 20:04:35 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2546.1730145864859774087 for ; Mon, 28 Oct 2024 13:04:25 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233460" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:24 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 06082408CD1D; Tue, 29 Oct 2024 05:04:22 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 17/27] media: platform: rzg2l-cru: rzg2l-csi2: Enclose the macro in parentheses Date: Mon, 28 Oct 2024 20:03:39 +0000 Message-ID: <20241028200349.9620-18-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:35 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17100 commit e5f29bb9c4350dd9692f3b98eb8538dbbebccbaf upstream. Fix the below error reported by checkpatch: ERROR: Macros with complex values should be enclosed in parentheses CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1) Signed-off-by: Lad Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index b413ad7ff6388..3f874edcabed8 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -81,10 +81,10 @@ #define CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(x) (((x) & 0x3) << 4) #define CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(x) (((x) & 0x3) << 8) #define CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(x) (((x) & 0x3) << 12) -#define CSIDPHYSKW0_DEFAULT_SKW CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ - CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1) +#define CSIDPHYSKW0_DEFAULT_SKW (CSIDPHYSKW0_UTIL_DL0_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL1_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL2_SKW_ADJ(1) | \ + CSIDPHYSKW0_UTIL_DL3_SKW_ADJ(1)) #define VSRSTS_RETRIES 20 From patchwork Mon Oct 28 20:03:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854013 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C37DD3E2D0 for ; Mon, 28 Oct 2024 20:04:35 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2549.1730145872634760555 for ; Mon, 28 Oct 2024 13:04:32 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233465" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:32 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id D7AE5408CD1D; Tue, 29 Oct 2024 05:04:24 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 18/27] media: platform: rzg2l-cru: rzg2l-csi2: Switch to RUNTIME_PM_OPS() Date: Mon, 28 Oct 2024 20:03:40 +0000 Message-ID: <20241028200349.9620-19-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:35 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17101 From: Biju Das commit f243df0a0be0bee39d60136a8f2d1616c63deb1c upstream. Replace the old SET_RUNTIME_PM_OPS() helpers with its modern alternative RUNTIME_PM_OPS(). The usage of pm_ptr and RUNTIME_PM_OPS() allows the compiler to see where it's used but still drop the dead code. After this we can get rid of the unnecessary '__maybe_unused' annotations on PM functions. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240213181233.242316-2-biju.das.jz@bp.renesas.com Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil [PL: Replaced RUNTIME_PM_OPS->SET_RUNTIME_PM_OPS] Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index 3f874edcabed8..88bacd12de129 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -839,7 +839,7 @@ static int rzg2l_csi2_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused rzg2l_csi2_pm_runtime_suspend(struct device *dev) +static int rzg2l_csi2_pm_runtime_suspend(struct device *dev) { struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); @@ -848,7 +848,7 @@ static int __maybe_unused rzg2l_csi2_pm_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused rzg2l_csi2_pm_runtime_resume(struct device *dev) +static int rzg2l_csi2_pm_runtime_resume(struct device *dev) { struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); @@ -856,7 +856,8 @@ static int __maybe_unused rzg2l_csi2_pm_runtime_resume(struct device *dev) } static const struct dev_pm_ops rzg2l_csi2_pm_ops = { - SET_RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend, rzg2l_csi2_pm_runtime_resume, NULL) + SET_RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend, + rzg2l_csi2_pm_runtime_resume, NULL) }; static const struct of_device_id rzg2l_csi2_of_table[] = { @@ -870,7 +871,7 @@ static struct platform_driver rzg2l_csi2_pdrv = { .driver = { .name = "rzg2l-csi2", .of_match_table = rzg2l_csi2_of_table, - .pm = &rzg2l_csi2_pm_ops, + .pm = pm_ptr(&rzg2l_csi2_pm_ops), }, }; From patchwork Mon Oct 28 20:03:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E5A1D3E2D6 for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2554.1730145876235235871 for ; Mon, 28 Oct 2024 13:04:36 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219310" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:35 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id C87EC408CD26; Tue, 29 Oct 2024 05:04:26 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 19/27] media: platform: rzg2l-cru: rzg2l-ip: Add delay after D-PHY reset Date: Mon, 28 Oct 2024 20:03:41 +0000 Message-ID: <20241028200349.9620-20-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17102 From: Biju Das commit 9c7fa014ca320b0eb95062922a73563aa9734cd0 upstream. As per section 35.3.1 Starting Reception for the MIPI CSI-2 Input on the latest hardware manual (R01UH0914EJ0140 Rev.1.40) it is mentioned that after DPHY reset, we need to wait for 1 msec or more before start receiving data from the sensor. So add a delay after pre_streamon(). Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240213181233.242316-3-biju.das.jz@bp.renesas.com Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c index 3a9f282a87bbb..fc1270f849cb0 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c @@ -5,6 +5,7 @@ * Copyright (C) 2022 Renesas Electronics Corp. */ +#include #include "rzg2l-cru.h" struct rzg2l_cru_ip_format { @@ -70,6 +71,8 @@ static int rzg2l_cru_ip_s_stream(struct v4l2_subdev *sd, int enable) if (ret) return ret; + fsleep(1000); + ret = rzg2l_cru_start_image_processing(cru); if (ret) { v4l2_subdev_call(cru->ip.remote, video, post_streamoff); From patchwork Mon Oct 28 20:03:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854018 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20827D3E2DE for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2556.1730145879123798506 for ; Mon, 28 Oct 2024 13:04:39 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219319" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:38 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id A95F7408D1FF; Tue, 29 Oct 2024 05:04:28 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 20/27] media: platform: rzg2l-cru: rzg2l-video: Fix image processing initialization Date: Mon, 28 Oct 2024 20:03:42 +0000 Message-ID: <20241028200349.9620-21-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17104 From: Biju Das commit 276739485501e61096034ec036337feab4c07dc5 upstream. As per section 35.3.1 Starting Reception for the MIPI CSI-2 Input on the latest hardware manual (R01UH0914EJ0140 Rev.1.40) it is mentioned that initialize the AXI master first and then initialize the image processing. Fix the start procedure as per the hardware manual. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240213181233.242316-4-biju.das.jz@bp.renesas.com Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- .../media/platform/renesas/rzg2l-cru/rzg2l-video.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index 1ab0cc741c05b..f8632481cdb82 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -432,13 +432,6 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru) spin_lock_irqsave(&cru->qlock, flags); - /* Initialize image convert */ - ret = rzg2l_cru_initialize_image_conv(cru, fmt); - if (ret) { - spin_unlock_irqrestore(&cru->qlock, flags); - return ret; - } - /* Select a video input */ rzg2l_cru_write(cru, CRUnCTRL, CRUnCTRL_VINSEL(0)); @@ -452,6 +445,13 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru) /* Initialize the AXI master */ rzg2l_cru_initialize_axi(cru); + /* Initialize image convert */ + ret = rzg2l_cru_initialize_image_conv(cru, fmt); + if (ret) { + spin_unlock_irqrestore(&cru->qlock, flags); + return ret; + } + /* Enable interrupt */ rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE); From patchwork Mon Oct 28 20:03:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854020 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D508D3E2DF for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2576.1730145879125009277 for ; Mon, 28 Oct 2024 13:04:39 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233478" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:38 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 8B9E2408D216; Tue, 29 Oct 2024 05:04:30 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 21/27] media: platform: rzg2l-cru: rzg2l-csi2: Restructure vclk handling Date: Mon, 28 Oct 2024 20:03:43 +0000 Message-ID: <20241028200349.9620-22-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17105 From: Biju Das commit fdc7bd5b3a64277c9427576a596df572d563dc3d upstream. As per section 35.3.1 Starting Reception for the MIPI CSI-2 Input on the latest hardware manual (R01UH0914EJ0145 Rev.1.45) we need to disable the vclk before enabling the LINK reception and enable the vclk after enabling the link Reception. So restructure vclk handling as per the HW manual. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240213181233.242316-5-biju.das.jz@bp.renesas.com Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- .../platform/renesas/rzg2l-cru/rzg2l-cru.h | 3 -- .../platform/renesas/rzg2l-cru/rzg2l-csi2.c | 28 +++++++++++-------- .../platform/renesas/rzg2l-cru/rzg2l-ip.c | 15 ++-------- .../platform/renesas/rzg2l-cru/rzg2l-video.c | 10 ------- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h index e376f06ca3e22..d45d6e8267251 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -134,9 +134,6 @@ struct rzg2l_cru_dev { struct v4l2_pix_format format; }; -void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru); -int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru); - int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru); void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index 88bacd12de129..f4805bca05342 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -109,6 +109,7 @@ struct rzg2l_csi2 { struct reset_control *presetn; struct reset_control *cmn_rstb; struct clk *sysclk; + struct clk *vclk; unsigned long vclk_rate; struct v4l2_subdev subdev; @@ -359,7 +360,7 @@ static int rzg2l_csi2_dphy_setting(struct v4l2_subdev *sd, bool on) return rzg2l_csi2_dphy_disable(csi2); } -static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) +static int rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) { unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ; u32 frrskw, frrclk, frrskw_coeff, frrclk_coeff; @@ -384,11 +385,15 @@ static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) rzg2l_csi2_write(csi2, CSI2nDTEL, 0xf778ff0f); rzg2l_csi2_write(csi2, CSI2nDTEH, 0x00ffff1f); + clk_disable_unprepare(csi2->vclk); + /* Enable LINK reception */ rzg2l_csi2_write(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); + + return clk_prepare_enable(csi2->vclk); } -static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) +static int rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) { unsigned int timeout = VSRSTS_RETRIES; @@ -407,18 +412,21 @@ static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) if (!timeout) dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n"); + + return 0; } static int rzg2l_csi2_mipi_link_setting(struct v4l2_subdev *sd, bool on) { struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); + int ret; if (on) - rzg2l_csi2_mipi_link_enable(csi2); + ret = rzg2l_csi2_mipi_link_enable(csi2); else - rzg2l_csi2_mipi_link_disable(csi2); + ret = rzg2l_csi2_mipi_link_disable(csi2); - return 0; + return ret; } static int rzg2l_csi2_s_stream(struct v4l2_subdev *sd, int enable) @@ -742,7 +750,6 @@ static const struct media_entity_operations rzg2l_csi2_entity_ops = { static int rzg2l_csi2_probe(struct platform_device *pdev) { struct rzg2l_csi2 *csi2; - struct clk *vclk; int ret; csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL); @@ -768,12 +775,11 @@ static int rzg2l_csi2_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(csi2->sysclk), "Failed to get system clk\n"); - vclk = clk_get(&pdev->dev, "video"); - if (IS_ERR(vclk)) - return dev_err_probe(&pdev->dev, PTR_ERR(vclk), + csi2->vclk = devm_clk_get(&pdev->dev, "video"); + if (IS_ERR(csi2->vclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(csi2->vclk), "Failed to get video clock\n"); - csi2->vclk_rate = clk_get_rate(vclk); - clk_put(vclk); + csi2->vclk_rate = clk_get_rate(csi2->vclk); csi2->dev = &pdev->dev; diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c index fc1270f849cb0..1c10078ad4331 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c @@ -79,20 +79,9 @@ static int rzg2l_cru_ip_s_stream(struct v4l2_subdev *sd, int enable) return ret; } - rzg2l_cru_vclk_unprepare(cru); - ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable); - if (ret == -ENOIOCTLCMD) - ret = 0; - if (!ret) { - ret = rzg2l_cru_vclk_prepare(cru); - if (!ret) - return 0; - } else { - /* enable back vclk so that s_stream in error path disables it */ - if (rzg2l_cru_vclk_prepare(cru)) - dev_err(cru->dev, "Failed to enable vclk\n"); - } + if (!ret || ret == -ENOIOCTLCMD) + return 0; s_stream_ret = ret; diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index f8632481cdb82..98f7835cb60f1 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -463,16 +463,6 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru) return 0; } -void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru) -{ - clk_disable_unprepare(cru->vclk); -} - -int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru) -{ - return clk_prepare_enable(cru->vclk); -} - static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on) { struct media_pipeline *pipe; From patchwork Mon Oct 28 20:03:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854019 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 207F4D3E2DD for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web10.2554.1730145876235235871 for ; Mon, 28 Oct 2024 13:04:39 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219318" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:38 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 6DC33408D45B; Tue, 29 Oct 2024 05:04:32 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 22/27] media: platform: rzg2l-cru: rzg2l-video: Fix start reception procedure Date: Mon, 28 Oct 2024 20:03:44 +0000 Message-ID: <20241028200349.9620-23-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17103 From: Biju Das commit 6bcff5f958e45a21f74d140c58e061999e97cd50 upstream. As per section 35.3.1 Starting Reception for the MIPI CSI-2 Input on the latest hardware manual (R01UH0914EJ0145 Rev.1.45) we need to supply all the clocks and then release the CRU resets. Currently we are releasing the resets and then supplying the clocks. So, fix the start reception procedure. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240213181233.242316-6-biju.das.jz@bp.renesas.com Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Lad Prabhakar --- .../platform/renesas/rzg2l-cru/rzg2l-video.c | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index 98f7835cb60f1..cd5278146f507 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -491,39 +491,24 @@ static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on) media_pipeline_stop(&cru->vdev.entity); - pm_runtime_put_sync(cru->dev); - clk_disable_unprepare(cru->vclk); - return stream_off_ret; } - ret = pm_runtime_resume_and_get(cru->dev); - if (ret) - return ret; - - ret = clk_prepare_enable(cru->vclk); - if (ret) - goto err_pm_put; - ret = rzg2l_cru_mc_validate_format(cru, sd, pad); if (ret) - goto err_vclk_disable; + return ret; pipe = sd->entity.pipe ? : &cru->vdev.pipe; ret = media_pipeline_start(&cru->vdev.entity, pipe); if (ret) - goto err_vclk_disable; + return ret; ret = v4l2_subdev_call(sd, video, pre_streamon, 0); - if (ret == -ENOIOCTLCMD) - ret = 0; - if (ret) + if (ret && ret != -ENOIOCTLCMD) goto pipe_line_stop; ret = v4l2_subdev_call(sd, video, s_stream, 1); - if (ret == -ENOIOCTLCMD) - ret = 0; - if (ret) + if (ret && ret != -ENOIOCTLCMD) goto err_s_stream; return 0; @@ -534,12 +519,6 @@ static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on) pipe_line_stop: media_pipeline_stop(&cru->vdev.entity); -err_vclk_disable: - clk_disable_unprepare(cru->vclk); - -err_pm_put: - pm_runtime_put_sync(cru->dev); - return ret; } @@ -638,25 +617,33 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); int ret; + ret = pm_runtime_resume_and_get(cru->dev); + if (ret) + return ret; + + ret = clk_prepare_enable(cru->vclk); + if (ret) + goto err_pm_put; + /* Release reset state */ ret = reset_control_deassert(cru->aresetn); if (ret) { dev_err(cru->dev, "failed to deassert aresetn\n"); - return ret; + goto err_vclk_disable; } ret = reset_control_deassert(cru->presetn); if (ret) { reset_control_assert(cru->aresetn); dev_err(cru->dev, "failed to deassert presetn\n"); - return ret; + goto assert_aresetn; } ret = request_irq(cru->image_conv_irq, rzg2l_cru_irq, IRQF_SHARED, KBUILD_MODNAME, cru); if (ret) { dev_err(cru->dev, "failed to request irq\n"); - goto assert_resets; + goto assert_presetn; } /* Allocate scratch buffer. */ @@ -688,10 +675,18 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count free_image_conv_irq: free_irq(cru->image_conv_irq, cru); -assert_resets: +assert_presetn: reset_control_assert(cru->presetn); + +assert_aresetn: reset_control_assert(cru->aresetn); +err_vclk_disable: + clk_disable_unprepare(cru->vclk); + +err_pm_put: + pm_runtime_put_sync(cru->dev); + return ret; } @@ -706,9 +701,11 @@ static void rzg2l_cru_stop_streaming_vq(struct vb2_queue *vq) cru->scratch, cru->scratch_phys); free_irq(cru->image_conv_irq, cru); - reset_control_assert(cru->presetn); - return_unused_buffers(cru, VB2_BUF_STATE_ERROR); + + reset_control_assert(cru->presetn); + clk_disable_unprepare(cru->vclk); + pm_runtime_put_sync(cru->dev); } static const struct vb2_ops rzg2l_cru_qops = { From patchwork Mon Oct 28 20:03:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854016 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 121EED3E2D0 for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2576.1730145879125009277 for ; Mon, 28 Oct 2024 13:04:39 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233481" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:38 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 8F20B408D45E; Tue, 29 Oct 2024 05:04:34 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 23/27] media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE Date: Mon, 28 Oct 2024 20:03:45 +0000 Message-ID: <20241028200349.9620-24-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17106 From: Biju Das commit 07668fb0f867388bfdac0b60dbf51a4ad789f8e7 upstream. The rzg2l-csi2 driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this. Fixes: 51e8415e39a9 ("media: platform: Add Renesas RZ/G2L MIPI CSI-2 receiver driver") Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240731164935.308994-1-biju.das.jz@bp.renesas.com Signed-off-by: Laurent Pinchart [PL: manually applied the patch] Signed-off-by: Lad Prabhakar --- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c index f4805bca05342..245fda83d524d 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c @@ -870,6 +870,7 @@ static const struct of_device_id rzg2l_csi2_of_table[] = { { .compatible = "renesas,rzg2l-csi2", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, rzg2l_csi2_of_table); static struct platform_driver rzg2l_csi2_pdrv = { .remove = rzg2l_csi2_remove, From patchwork Mon Oct 28 20:03:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854017 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1229FD3E2DA for ; Mon, 28 Oct 2024 20:04:45 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2576.1730145879125009277 for ; Mon, 28 Oct 2024 13:04:40 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233482" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:38 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 6EDD0408CD1D; Tue, 29 Oct 2024 05:04:36 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 24/27] clk: renesas: r9a07g044: Add clock and reset entries for CRU Date: Mon, 28 Oct 2024 20:03:46 +0000 Message-ID: <20241028200349.9620-25-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:45 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17107 commit a278d0c92be9d90307114b05c3edb1e7354d8412 upstream. Add CRU clock and reset entries to CPG driver. CRU_SYSCLK and CRU_VCLK clocks need to be turned ON/OFF in particular sequence for the CRU block hence add these clocks to r9a07g044_no_pm_mod_clks[] array and pass it as part of CPG data for both RZ/G2L and RZ/V2L SoCs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20221221212703.348278-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Lad Prabhakar --- drivers/clk/renesas/r9a07g044-cpg.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 22c03c8d46362..bc822b9fd7ce6 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -197,7 +197,7 @@ static const struct { }; static const struct { - struct rzg2l_mod_clk common[75]; + struct rzg2l_mod_clk common[79]; #ifdef CONFIG_CLK_R9A07G054 struct rzg2l_mod_clk drp[0]; #endif @@ -265,6 +265,14 @@ static const struct { 0x558, 1), DEF_MOD("gpu_ace_clk", R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1, 0x558, 2), + DEF_MOD("cru_sysclk", R9A07G044_CRU_SYSCLK, CLK_M2_DIV2, + 0x564, 0), + DEF_MOD("cru_vclk", R9A07G044_CRU_VCLK, R9A07G044_CLK_M2, + 0x564, 1), + DEF_MOD("cru_pclk", R9A07G044_CRU_PCLK, R9A07G044_CLK_ZT, + 0x564, 2), + DEF_MOD("cru_aclk", R9A07G044_CRU_ACLK, R9A07G044_CLK_M0, + 0x564, 3), DEF_MOD("dsi_pll_clk", R9A07G044_MIPI_DSI_PLLCLK, R9A07G044_CLK_M1, 0x568, 0), DEF_MOD("dsi_sys_clk", R9A07G044_MIPI_DSI_SYSCLK, CLK_M2_DIV2, @@ -383,6 +391,9 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GPU_RESETN, 0x858, 0), DEF_RST(R9A07G044_GPU_AXI_RESETN, 0x858, 1), DEF_RST(R9A07G044_GPU_ACE_RESETN, 0x858, 2), + DEF_RST(R9A07G044_CRU_CMN_RSTB, 0x864, 0), + DEF_RST(R9A07G044_CRU_PRESETN, 0x864, 1), + DEF_RST(R9A07G044_CRU_ARESETN, 0x864, 2), DEF_RST(R9A07G044_MIPI_DSI_CMN_RSTB, 0x868, 0), DEF_RST(R9A07G044_MIPI_DSI_ARESET_N, 0x868, 1), DEF_RST(R9A07G044_MIPI_DSI_PRESET_N, 0x868, 2), @@ -427,6 +438,11 @@ static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { MOD_CLK_BASE + R9A07G044_DMAC_ACLK, }; +static const unsigned int r9a07g044_no_pm_mod_clks[] = { + MOD_CLK_BASE + R9A07G044_CRU_SYSCLK, + MOD_CLK_BASE + R9A07G044_CRU_VCLK, +}; + #ifdef CONFIG_CLK_R9A07G044 const struct rzg2l_cpg_info r9a07g044_cpg_info = { /* Core Clocks */ @@ -444,6 +460,10 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = { .num_mod_clks = ARRAY_SIZE(mod_clks.common), .num_hw_mod_clks = R9A07G044_TSU_PCLK + 1, + /* No PM Module Clocks */ + .no_pm_mod_clks = r9a07g044_no_pm_mod_clks, + .num_no_pm_mod_clks = ARRAY_SIZE(r9a07g044_no_pm_mod_clks), + /* Resets */ .resets = r9a07g044_resets, .num_resets = R9A07G044_TSU_PRESETN + 1, /* Last reset ID + 1 */ @@ -469,6 +489,10 @@ const struct rzg2l_cpg_info r9a07g054_cpg_info = { .num_mod_clks = ARRAY_SIZE(mod_clks.common) + ARRAY_SIZE(mod_clks.drp), .num_hw_mod_clks = R9A07G054_STPAI_ACLK_DRP + 1, + /* No PM Module Clocks */ + .no_pm_mod_clks = r9a07g044_no_pm_mod_clks, + .num_no_pm_mod_clks = ARRAY_SIZE(r9a07g044_no_pm_mod_clks), + /* Resets */ .resets = r9a07g044_resets, .num_resets = R9A07G054_STPAI_ARESETN + 1, /* Last reset ID + 1 */ From patchwork Mon Oct 28 20:03:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854022 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D93FD5B143 for ; Mon, 28 Oct 2024 20:04:55 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web11.2588.1730145889181522298 for ; Mon, 28 Oct 2024 13:04:49 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233488" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:48 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 4B149408D907; Tue, 29 Oct 2024 05:04:38 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 25/27] arm64: dts: renesas: r9a07g044: Add CSI and CRU nodes Date: Mon, 28 Oct 2024 20:03:47 +0000 Message-ID: <20241028200349.9620-26-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:55 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17108 commit 95c91e77664866517a999abdb246ffb207882c30 upstream. Add CSI and CRU nodes r9a07g044 (RZ/G2L) SoC DTSI. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230322125648.24948-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven [PL: manually applied the patch] Signed-off-by: Lad Prabhakar --- arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi index 267fbfcccc2b7..327e7bf983a7d 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi @@ -687,6 +687,85 @@ sbc: spi@10060000 { status = "disabled"; }; + cru: video@10830000 { + compatible = "renesas,r9a07g044-cru", "renesas,rzg2l-cru"; + reg = <0 0x10830000 0 0x400>; + clocks = <&cpg CPG_MOD R9A07G044_CRU_VCLK>, + <&cpg CPG_MOD R9A07G044_CRU_PCLK>, + <&cpg CPG_MOD R9A07G044_CRU_ACLK>; + clock-names = "video", "apb", "axi"; + interrupts = , + , + ; + interrupt-names = "image_conv", "image_conv_err", "axi_mst_err"; + resets = <&cpg R9A07G044_CRU_PRESETN>, + <&cpg R9A07G044_CRU_ARESETN>; + reset-names = "presetn", "aresetn"; + power-domains = <&cpg>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <0>; + cruparallel: endpoint@0 { + reg = <0>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + crucsi2: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi2cru>; + }; + }; + }; + }; + + csi2: csi2@10830400 { + compatible = "renesas,r9a07g044-csi2", "renesas,rzg2l-csi2"; + reg = <0 0x10830400 0 0xfc00>; + interrupts = ; + clocks = <&cpg CPG_MOD R9A07G044_CRU_SYSCLK>, + <&cpg CPG_MOD R9A07G044_CRU_VCLK>, + <&cpg CPG_MOD R9A07G044_CRU_PCLK>; + clock-names = "system", "video", "apb"; + resets = <&cpg R9A07G044_CRU_PRESETN>, + <&cpg R9A07G044_CRU_CMN_RSTB>; + reset-names = "presetn", "cmn-rstb"; + power-domains = <&cpg>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + csi2cru: endpoint@0 { + reg = <0>; + remote-endpoint = <&crucsi2>; + }; + }; + }; + }; + dsi: dsi@10850000 { compatible = "renesas,r9a07g044-mipi-dsi", "renesas,rzg2l-mipi-dsi"; From patchwork Mon Oct 28 20:03:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854021 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F65BD5B144 for ; Mon, 28 Oct 2024 20:04:55 +0000 (UTC) Received: from relmlie6.idc.renesas.com (relmlie6.idc.renesas.com [210.160.252.172]) by mx.groups.io with SMTP id smtpd.web11.2590.1730145893157259107 for ; Mon, 28 Oct 2024 13:04:53 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.172, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="227219335" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 29 Oct 2024 05:04:52 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 29932408CD26; Tue, 29 Oct 2024 05:04:39 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 26/27] arm64: dts: renesas: rzg2l-smarc: Enable CRU, CSI support Date: Mon, 28 Oct 2024 20:03:48 +0000 Message-ID: <20241028200349.9620-27-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:04:55 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17109 commit 3d52973db7457362e54b5b62242671eee80b2c14 upstream. Enable CRU, CSI on RZ/G2L SMARC EVK and tie the CSI to OV5645 sensor using Device Tree overlay. rz-smarc-cru-csi-ov5645.dtsi is created so that RZ/G2L alike EVKs can make use of it. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230322125648.24948-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven [PL: dropped overlay support and enabled directly in board dts] Signed-off-by: Lad Prabhakar --- .../dts/renesas/rz-smarc-cru-csi-ov5645.dtsi | 80 +++++++++++++++++++ arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 8 ++ 2 files changed, 88 insertions(+) create mode 100644 arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi new file mode 100644 index 0000000000000..c5bb63c63b470 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rz-smarc-cru-csi-ov5645.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Device Tree for the RZ/G2L SMARC EVK (and alike EVKs) with + * OV5645 camera connected to CSI and CRU enabled. + * + * Copyright (C) 2023 Renesas Electronics Corp. + */ + +&{/} { + ov5645_vdddo_1v8: 1p8v { + compatible = "regulator-fixed"; + regulator-name = "camera_vdddo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ov5645_vdda_2v8: 2p8v { + compatible = "regulator-fixed"; + regulator-name = "camera_vdda"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + ov5645_vddd_1v5: 1p5v { + compatible = "regulator-fixed"; + regulator-name = "camera_vddd"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + ov5645_fixed_clk: osc25250-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; +}; + +&cru { + status = "okay"; +}; + +&csi2 { + status = "okay"; + + ports { + port@0 { + csi2_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&ov5645_ep>; + }; + }; + }; +}; + +&OV5645_PARENT_I2C { + #address-cells = <1>; + #size-cells = <0>; + + ov5645: camera@3c { + compatible = "ovti,ov5645"; + reg = <0x3c>; + clocks = <&ov5645_fixed_clk>; + clock-frequency = <24000000>; + vdddo-supply = <&ov5645_vdddo_1v8>; + vdda-supply = <&ov5645_vdda_2v8>; + vddd-supply = <&ov5645_vddd_1v5>; + + port { + ov5645_ep: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&csi2_in>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi index ee3d96fdb6168..90ae3259fd825 100644 --- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi @@ -8,6 +8,9 @@ #include #include +#define OV5645_PARENT_I2C i2c0 +#include "rz-smarc-cru-csi-ov5645.dtsi" + / { aliases { serial1 = &scif2; @@ -159,6 +162,11 @@ &spi1 { }; #endif /* PMOD_MTU3 */ +&ov5645 { + enable-gpios = <&pinctrl RZG2L_GPIO(2, 0) GPIO_ACTIVE_HIGH>; + reset-gpios = <&pinctrl RZG2L_GPIO(40, 2) GPIO_ACTIVE_LOW>; +}; + /* * To enable SCIF2 (SER0) on PMOD1 (CN7) * SW1 should be at position 2->3 so that SER0_CTS# line is activated From patchwork Mon Oct 28 20:03:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lad Prabhakar X-Patchwork-Id: 13854023 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27DBED5B143 for ; Mon, 28 Oct 2024 20:05:05 +0000 (UTC) Received: from relmlie5.idc.renesas.com (relmlie5.idc.renesas.com [210.160.252.171]) by mx.groups.io with SMTP id smtpd.web10.2570.1730145900677548138 for ; Mon, 28 Oct 2024 13:05:00 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: bp.renesas.com, ip: 210.160.252.171, mailfrom: prabhakar.mahadev-lad.rj@bp.renesas.com) X-IronPort-AV: E=Sophos;i="6.11,239,1725289200"; d="scan'208";a="223233498" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie5.idc.renesas.com with ESMTP; 29 Oct 2024 05:05:00 +0900 Received: from Ubuntu-22.. (unknown [10.226.93.179]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 0AE44408CD1D; Tue, 29 Oct 2024 05:04:41 +0900 (JST) From: Lad Prabhakar To: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu , Pavel Machek Cc: Biju Das Subject: [PATCH 5.10.y-cip 27/27] arm64: defconfig: Enable RZ/G2L MIPI CSI-2 and CRU support Date: Mon, 28 Oct 2024 20:03:49 +0000 Message-ID: <20241028200349.9620-28-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20241028200349.9620-1-prabhakar.mahadev-lad.rj@bp.renesas.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 28 Oct 2024 20:05:05 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/17110 From: Geert Uytterhoeven commit 3ad69c496d488cd1b6c3a20b2f7945b45a0f7f18 upstream. Increase build and test coverage by enabling support for the Renesas RZ/G2L MIPI CSI-2 Receiver and the RZ/G2L Camera Receiving Unit, as used on the RZ/G2L SMARC EVK development board. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/32098bf6a5e78a4bcc6398ccb5db0b01f1afc9b9.1672747428.git.geert+renesas@glider.be [PL: manually applied the patch] Signed-off-by: Lad Prabhakar --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8a2f7a67cdacd..297d671306ce7 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -627,6 +627,8 @@ CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_RCAR_CSI2=m CONFIG_VIDEO_RCAR_VIN=m +CONFIG_VIDEO_RZG2L_CSI2=m +CONFIG_VIDEO_RZG2L_CRU=m CONFIG_VIDEO_SUN6I_CSI=m CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m