From 01cb9a2eef4b167d5ea86bde16ab00e6693f1de1 Mon Sep 17 00:00:00 2001 From: Allon Huang Date: Fri, 16 Apr 2021 18:02:31 +0800 Subject: [PATCH] media: platform: rockchip: cif: mipi csi host add cru rst Signed-off-by: Allon Huang Change-Id: I8ad52b91d9f01c29b6316999f6983bb04eb6433d --- .../media/platform/rockchip/cif/mipi-csi2.c | 109 +++++++++++------- drivers/media/platform/rockchip/cif/version.h | 1 + 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/mipi-csi2.c b/drivers/media/platform/rockchip/cif/mipi-csi2.c index 8a29bb3f68d5..3f642f75bb5d 100644 --- a/drivers/media/platform/rockchip/cif/mipi-csi2.c +++ b/drivers/media/platform/rockchip/cif/mipi-csi2.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -100,28 +101,29 @@ struct csi2_err_stats { }; struct csi2_dev { - struct device *dev; - struct v4l2_subdev sd; - struct media_pad pad[CSI2_NUM_PADS]; - struct clk *pix_clk; /* what is this? */ - struct clk *srst_clk; - void __iomem *base; + struct device *dev; + struct v4l2_subdev sd; + struct media_pad pad[CSI2_NUM_PADS]; + struct clk_bulk_data *clks_bulk; + int clks_num; + struct reset_control *rsts_bulk; + + void __iomem *base; struct v4l2_async_notifier notifier; - struct v4l2_fwnode_bus_mipi_csi2 bus; + struct v4l2_fwnode_bus_mipi_csi2 bus; /* lock to protect all members below */ struct mutex lock; - struct v4l2_mbus_framefmt format_mbus; - struct v4l2_rect crop; - - int stream_count; - struct v4l2_subdev *src_sd; - bool sink_linked[CSI2_NUM_SRC_PADS]; + struct v4l2_mbus_framefmt format_mbus; + struct v4l2_rect crop; + int stream_count; + struct v4l2_subdev *src_sd; + bool sink_linked[CSI2_NUM_SRC_PADS]; struct csi2_sensor sensors[MAX_CSI2_SENSORS]; const struct csi2_match_data *match_data; - int num_sensors; - atomic_t frm_sync_seq; + int num_sensors; + atomic_t frm_sync_seq; struct csi2_err_stats err_list[RK_CSI2_ERR_MAX]; }; @@ -241,6 +243,31 @@ static void csi2_update_sensor_info(struct csi2_dev *csi2) } +static void csi2_hw_do_reset(struct csi2_dev *csi2) +{ + reset_control_assert(csi2->rsts_bulk); + + udelay(5); + + reset_control_deassert(csi2->rsts_bulk); +} + +static int csi2_enable_clks(struct csi2_dev *csi2) +{ + int ret = 0; + + ret = clk_bulk_prepare_enable(csi2->clks_num, csi2->clks_bulk); + if (ret) + dev_err(csi2->dev, "failed to enable clks\n"); + + return ret; +} + +static void csi2_disable_clks(struct csi2_dev *csi2) +{ + clk_bulk_disable_unprepare(csi2->clks_num, csi2->clks_bulk); +} + static void csi2_disable(struct csi2_dev *csi2) { void __iomem *base = csi2->base; @@ -283,16 +310,11 @@ static int csi2_start(struct csi2_dev *csi2) atomic_set(&csi2->frm_sync_seq, 0); - ret = clk_prepare_enable(csi2->pix_clk); - if (ret) + csi2_hw_do_reset(csi2); + ret = csi2_enable_clks(csi2); + if (ret) { + v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__); return ret; - - if (!IS_ERR(csi2->srst_clk)) { - ret = clk_prepare_enable(csi2->srst_clk); - if (ret) { - clk_disable_unprepare(csi2->pix_clk); - return ret; - } } csi2_update_sensor_info(csi2); @@ -317,8 +339,8 @@ static int csi2_start(struct csi2_dev *csi2) err_assert_reset: csi2_disable(csi2); - clk_disable_unprepare(csi2->pix_clk); - clk_disable_unprepare(csi2->srst_clk); + csi2_disable_clks(csi2); + return ret; } @@ -328,8 +350,7 @@ static void csi2_stop(struct csi2_dev *csi2) v4l2_subdev_call(csi2->src_sd, video, s_stream, 0); csi2_disable(csi2); - clk_disable_unprepare(csi2->pix_clk); - clk_disable_unprepare(csi2->srst_clk); + csi2_disable_clks(csi2); } /* @@ -850,17 +871,17 @@ static int csi2_notifier(struct csi2_dev *csi2) static const struct csi2_match_data rk1808_csi2_match_data = { .chip_id = CHIP_RK1808_CSI2, - .num_pads = CSI2_NUM_PADS + .num_pads = CSI2_NUM_PADS, }; static const struct csi2_match_data rk3288_csi2_match_data = { .chip_id = CHIP_RK3288_CSI2, - .num_pads = CSI2_NUM_PADS_SINGLE_LINK + .num_pads = CSI2_NUM_PADS_SINGLE_LINK, }; static const struct csi2_match_data rv1126_csi2_match_data = { .chip_id = CHIP_RV1126_CSI2, - .num_pads = CSI2_NUM_PADS + .num_pads = CSI2_NUM_PADS, }; static const struct csi2_match_data rk3568_csi2_match_data = { @@ -892,6 +913,7 @@ MODULE_DEVICE_TABLE(of, csi2_dt_ids); static int csi2_probe(struct platform_device *pdev) { const struct of_device_id *match; + struct device *dev = &pdev->dev; struct device_node *node = pdev->dev.of_node; struct csi2_dev *csi2 = NULL; struct resource *res; @@ -920,19 +942,16 @@ static int csi2_probe(struct platform_device *pdev) if (ret < 0) v4l2_err(&csi2->sd, "failed to copy name\n"); platform_set_drvdata(pdev, &csi2->sd); - /* csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; */ - /* csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2; */ - csi2->pix_clk = devm_clk_get(&pdev->dev, "pclk_csi2host"); - if (IS_ERR(csi2->pix_clk)) { - v4l2_err(&csi2->sd, "failed to get pixel clock\n"); - ret = PTR_ERR(csi2->pix_clk); - return ret; - } + csi2->clks_num = devm_clk_bulk_get_all(dev, &csi2->clks_bulk); + if (csi2->clks_num < 0) + dev_err(dev, "failed to get csi2 clks\n"); - csi2->srst_clk = devm_clk_get(&pdev->dev, "srst_csihost_p"); - if (IS_ERR(csi2->srst_clk)) { - v4l2_warn(&csi2->sd, "failed to get rst clock, maybe useless\n"); + csi2->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev); + if (IS_ERR(csi2->rsts_bulk)) { + if (PTR_ERR(csi2->rsts_bulk) != -EPROBE_DEFER) + dev_err(dev, "failed to get csi2 reset\n"); + return PTR_ERR(csi2->rsts_bulk); } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -985,9 +1004,13 @@ static int csi2_probe(struct platform_device *pdev) ret = csi2_notifier(csi2); if (ret) goto rmmutex; - v4l2_info(&csi2->sd, "probe success, v4l2_dev:%s!\n", csi2->sd.v4l2_dev->name); + + csi2_hw_do_reset(csi2); + g_csi2_dev = csi2; + v4l2_info(&csi2->sd, "probe success, v4l2_dev:%s!\n", csi2->sd.v4l2_dev->name); + return 0; rmmutex: diff --git a/drivers/media/platform/rockchip/cif/version.h b/drivers/media/platform/rockchip/cif/version.h index 0ff34f4aaeed..712befd13c65 100644 --- a/drivers/media/platform/rockchip/cif/version.h +++ b/drivers/media/platform/rockchip/cif/version.h @@ -62,6 +62,7 @@ *2. add dynamic cropping function *3. optimize dts config of cif's pipeline *4. register cif itf dev when clear unready subdev + *5. mipi csi host add cru rst */ #define RKCIF_DRIVER_VERSION RKCIF_API_VERSION