media: platform: rockchip: cif: mipi csi host add cru rst

Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: I8ad52b91d9f01c29b6316999f6983bb04eb6433d
This commit is contained in:
Allon Huang
2021-04-16 18:02:31 +08:00
committed by Tao Huang
parent 2bbda8ef09
commit 01cb9a2eef
2 changed files with 67 additions and 43 deletions

View File

@@ -14,6 +14,7 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -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:

View File

@@ -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