From 08f87f769b595151be1afeff53e144f543faa614 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 06 Dec 2023 09:51:13 +0000
Subject: [PATCH] add dts config
---
kernel/drivers/media/platform/rockchip/isp/dev.c | 274 ++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 203 insertions(+), 71 deletions(-)
diff --git a/kernel/drivers/media/platform/rockchip/isp/dev.c b/kernel/drivers/media/platform/rockchip/isp/dev.c
index 0501a38..cf981d6 100644
--- a/kernel/drivers/media/platform/rockchip/isp/dev.c
+++ b/kernel/drivers/media/platform/rockchip/isp/dev.c
@@ -63,6 +63,14 @@
module_param_named(monitor, rkisp_monitor, bool, 0644);
MODULE_PARM_DESC(monitor, "rkisp abnormal restart monitor");
+bool rkisp_irq_dbg;
+module_param_named(irq_dbg, rkisp_irq_dbg, bool, 0644);
+MODULE_PARM_DESC(irq_dbg, "rkisp interrupt runtime");
+
+static bool rkisp_rdbk_auto;
+module_param_named(rdbk_auto, rkisp_rdbk_auto, bool, 0644);
+MODULE_PARM_DESC(irq_dbg, "rkisp and vicap auto readback mode");
+
static bool rkisp_clk_dbg;
module_param_named(clk_dbg, rkisp_clk_dbg, bool, 0644);
MODULE_PARM_DESC(clk_dbg, "rkisp clk set by user");
@@ -78,6 +86,10 @@
static unsigned int rkisp_wait_line;
module_param_named(wait_line, rkisp_wait_line, uint, 0644);
MODULE_PARM_DESC(wait_line, "rkisp wait line to buf done early");
+
+static unsigned int rkisp_wrap_line;
+module_param_named(wrap_line, rkisp_wrap_line, uint, 0644);
+MODULE_PARM_DESC(wrap_line, "rkisp wrap line for mpp");
static DEFINE_MUTEX(rkisp_dev_mutex);
static LIST_HEAD(rkisp_device_list);
@@ -126,7 +138,7 @@
p->num_subdevs = 0;
memset(p->subdevs, 0, sizeof(p->subdevs));
- if (!(dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS)))
+ if (!(dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS | INP_CIF)))
return 0;
while (1) {
@@ -164,21 +176,35 @@
{
struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
struct rkisp_hw_dev *hw_dev = dev->hw_dev;
- u32 w = hw_dev->max_in.w ? hw_dev->max_in.w : dev->isp_sdev.in_frm.width;
struct v4l2_subdev *sd;
struct v4l2_ctrl *ctrl;
- u64 data_rate;
- int i;
+ u64 data_rate = 0;
+ int i, fps;
- if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF)) {
- for (i = 0; i < hw_dev->num_clk_rate_tbl; i++) {
- if (w <= hw_dev->clk_rate_tbl[i].refer_data)
- break;
+ hw_dev->isp_size[dev->dev_id].is_on = true;
+ if (hw_dev->is_runing) {
+ if (dev->isp_ver >= ISP_V30 && !rkisp_clk_dbg)
+ hw_dev->is_dvfs = true;
+ return 0;
+ }
+
+ if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2) ||
+ (dev->is_pre_on && hw_dev->dev_num > 1)) {
+ if (dev->isp_ver < ISP_V30 || dev->is_pre_on) {
+ /* isp with mipi no support dvfs, calculate max data rate */
+ for (i = 0; i < hw_dev->dev_num; i++) {
+ fps = hw_dev->isp_size[i].fps;
+ if (!fps)
+ fps = 30;
+ data_rate += (fps * hw_dev->isp_size[i].size);
+ }
+ } else {
+ i = dev->dev_id;
+ fps = hw_dev->isp_size[i].fps;
+ if (!fps)
+ fps = 30;
+ data_rate = fps * hw_dev->isp_size[i].size;
}
- if (!hw_dev->is_single)
- i++;
- if (i > hw_dev->num_clk_rate_tbl - 1)
- i = hw_dev->num_clk_rate_tbl - 1;
goto end;
}
@@ -187,11 +213,12 @@
return 0;
}
- /* find the subdev of active sensor */
+ /* find the subdev of active sensor or vicap itf */
sd = p->subdevs[0];
for (i = 0; i < p->num_subdevs; i++) {
sd = p->subdevs[i];
- if (sd->entity.function == MEDIA_ENT_F_CAM_SENSOR)
+ if (sd->entity.function == MEDIA_ENT_F_CAM_SENSOR ||
+ sd->entity.function == MEDIA_ENT_F_PROC_VIDEO_COMPOSER)
break;
}
@@ -210,6 +237,7 @@
data_rate = v4l2_ctrl_g_ctrl_int64(ctrl) *
dev->isp_sdev.in_fmt.bus_width;
data_rate >>= 3;
+end:
do_div(data_rate, 1000 * 1000);
/* increase 25% margin */
@@ -221,10 +249,15 @@
break;
if (i == hw_dev->num_clk_rate_tbl)
i--;
-end:
+
/* set isp clock rate */
rkisp_set_clk_rate(hw_dev->clks[0], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
- dev_dbg(hw_dev->dev, "set isp clk = %luHz\n", clk_get_rate(hw_dev->clks[0]));
+ if (hw_dev->is_unite)
+ rkisp_set_clk_rate(hw_dev->clks[5], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
+ /* aclk equal to core clk */
+ if (dev->isp_ver == ISP_V32)
+ rkisp_set_clk_rate(hw_dev->clks[1], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
+ dev_info(hw_dev->dev, "set isp clk = %luHz\n", clk_get_rate(hw_dev->clks[0]));
return 0;
}
@@ -259,8 +292,15 @@
static int rkisp_pipeline_close(struct rkisp_pipeline *p)
{
- atomic_dec(&p->power_cnt);
+ struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
+ if (atomic_dec_return(&p->power_cnt))
+ return 0;
+
+ rkisp_rx_buf_pool_free(dev);
+ dev->hw_dev->isp_size[dev->dev_id].is_on = false;
+ if (dev->hw_dev->is_runing && (dev->isp_ver >= ISP_V30) && !rkisp_clk_dbg)
+ dev->hw_dev->is_dvfs = true;
return 0;
}
@@ -281,9 +321,14 @@
if (dev->vs_irq >= 0)
enable_irq(dev->vs_irq);
rockchip_set_system_status(SYS_STATUS_ISP);
- v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, true);
+ ret = v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, true);
+ if (ret < 0)
+ goto err;
/* phy -> sensor */
for (i = 0; i < p->num_subdevs; ++i) {
+ if ((dev->vicap_in.merge_num > 1) &&
+ (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR))
+ continue;
ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
if (on && ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
goto err_stream_off;
@@ -296,8 +341,12 @@
complete(&dev->hw_dev->monitor.cmpl);
}
/* sensor -> phy */
- for (i = p->num_subdevs - 1; i >= 0; --i)
+ for (i = p->num_subdevs - 1; i >= 0; --i) {
+ if ((dev->vicap_in.merge_num > 1) &&
+ (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR))
+ continue;
v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
+ }
if (dev->vs_irq >= 0)
disable_irq(dev->vs_irq);
v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
@@ -310,7 +359,9 @@
for (--i; i >= 0; --i)
v4l2_subdev_call(p->subdevs[i], video, s_stream, false);
v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
+err:
rockchip_clear_system_status(SYS_STATUS_ISP);
+ atomic_dec_return(&p->stream_cnt);
return ret;
}
@@ -326,7 +377,7 @@
for (s = 0; s < dev->num_sensors; ++s) {
struct rkisp_sensor_info *sensor = &dev->sensors[s];
u32 type = sensor->sd->entity.function;
- bool en = s ? 0 : MEDIA_LNK_FL_ENABLED;
+ bool en = s ? 0 : true;
for (pad = 0; pad < sensor->sd->entity.num_pads; pad++)
if (sensor->sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)
@@ -348,8 +399,8 @@
ret = media_create_pad_link(&sensor->sd->entity, pad,
&dev->isp_sdev.sd.entity, RKISP_ISP_PAD_SINK, en);
} else {
- v4l2_subdev_call(sensor->sd, video,
- g_mbus_config, &sensor->mbus);
+ v4l2_subdev_call(sensor->sd, pad,
+ get_mbus_config, 0, &sensor->mbus);
if (sensor->mbus.type == V4L2_MBUS_CCP2) {
/* mipi-phy lvds link -> isp */
dev->isp_inp = INP_LVDS;
@@ -372,16 +423,27 @@
return ret;
}
-static int _set_pipeline_default_fmt(struct rkisp_device *dev)
+static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init)
{
struct v4l2_subdev *isp;
struct v4l2_subdev_format fmt;
struct v4l2_subdev_selection sel;
- u32 width, height, code;
+ u32 i, width, height, code;
+ memset(&sel, 0, sizeof(sel));
+ memset(&fmt, 0, sizeof(fmt));
isp = &dev->isp_sdev.sd;
- fmt = dev->active_sensor->fmt[0];
+ if (dev->active_sensor) {
+ fmt = dev->active_sensor->fmt[0];
+ if (!is_init &&
+ fmt.format.code == dev->isp_sdev.in_frm.code &&
+ fmt.format.width == dev->isp_sdev.in_frm.width &&
+ fmt.format.height == dev->isp_sdev.in_frm.height)
+ return 0;
+ } else {
+ fmt.format = dev->isp_sdev.in_frm;
+ }
code = fmt.format.code;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.pad = RKISP_ISP_PAD_SINK;
@@ -417,7 +479,7 @@
rkisp_set_stream_def_fmt(dev, RKISP_STREAM_SP,
width, height, V4L2_PIX_FMT_NV12);
if ((dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) &&
- dev->isp_inp == INP_CSI) {
+ dev->isp_inp == INP_CSI && dev->active_sensor) {
width = dev->active_sensor->fmt[1].format.width;
height = dev->active_sensor->fmt[1].format.height;
code = dev->active_sensor->fmt[1].format.code;
@@ -437,12 +499,49 @@
width, height, rkisp_mbus_pixelcode_to_v4l2(code));
}
- if (dev->isp_ver == ISP_V20 && dev->isp_inp == INP_CSI) {
+ if (dev->isp_ver == ISP_V20 &&
+ dev->isp_inp == INP_CSI && dev->active_sensor) {
width = dev->active_sensor->fmt[2].format.width;
height = dev->active_sensor->fmt[2].format.height;
code = dev->active_sensor->fmt[2].format.code;
rkisp_set_stream_def_fmt(dev, RKISP_STREAM_DMATX1,
width, height, rkisp_mbus_pixelcode_to_v4l2(code));
+ }
+
+ if (dev->isp_ver == ISP_V30) {
+ struct v4l2_pix_format_mplane pixm = {
+ .width = width,
+ .height = height,
+ .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code),
+ };
+
+ for (i = RKISP_STREAM_RAWRD0; i <= RKISP_STREAM_RAWRD2; i++)
+ rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[i], pixm);
+ rkisp_set_stream_def_fmt(dev, RKISP_STREAM_FBC,
+ width, height, V4L2_PIX_FMT_FBC0);
+#ifdef RKISP_STREAM_BP_EN
+ rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP,
+ width, height, V4L2_PIX_FMT_NV12);
+#endif
+ }
+
+ if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) {
+ struct v4l2_pix_format_mplane pixm = {
+ .width = width,
+ .height = height,
+ .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code),
+ };
+
+ rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0], pixm);
+ rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2], pixm);
+ if (dev->isp_ver == ISP_V32) {
+ rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP,
+ width, height, V4L2_PIX_FMT_NV12);
+ rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MPDS,
+ width / 4, height / 4, V4L2_PIX_FMT_NV12);
+ rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BPDS,
+ width / 4, height / 4, V4L2_PIX_FMT_NV12);
+ }
}
return 0;
}
@@ -462,13 +561,16 @@
if (ret < 0)
goto unlock;
- ret = rkisp_update_sensor_info(dev);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "update sensor failed\n");
- goto unlock;
+ if (dev->isp_inp) {
+ ret = rkisp_update_sensor_info(dev);
+ if (ret < 0) {
+ v4l2_err(&dev->v4l2_dev, "update sensor failed\n");
+ goto unlock;
+ }
+ dev->is_hw_link = true;
}
- ret = _set_pipeline_default_fmt(dev);
+ ret = _set_pipeline_default_fmt(dev, true);
if (ret < 0)
goto unlock;
@@ -476,6 +578,8 @@
unlock:
mutex_unlock(&dev->media_dev.graph_mutex);
+ if (!ret && dev->is_thunderboot)
+ schedule_work(&dev->cap_dev.fast_work);
return ret;
}
@@ -527,9 +631,28 @@
return 0;
}
+static void subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ struct rkisp_device *isp_dev = container_of(notifier, struct rkisp_device, notifier);
+ struct rkisp_isp_subdev *isp_sdev = &isp_dev->isp_sdev;
+ struct v4l2_subdev *isp_sd = &isp_sdev->sd;
+ int i;
+
+ for (i = 0; i < isp_dev->num_sensors; i++) {
+ if (isp_dev->sensors[i].sd == subdev) {
+ media_entity_call(&isp_sd->entity, link_setup,
+ isp_sd->entity.pads, subdev->entity.pads, 0);
+ isp_dev->sensors[i].sd = NULL;
+ }
+ }
+}
+
static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
.bound = subdev_notifier_bound,
.complete = subdev_notifier_complete,
+ .unbind = subdev_notifier_unbind,
};
static int isp_subdev_notifier(struct rkisp_device *isp_dev)
@@ -538,14 +661,13 @@
struct device *dev = isp_dev->dev;
int ret;
+ v4l2_async_notifier_init(ntf);
+
ret = v4l2_async_notifier_parse_fwnode_endpoints(
dev, ntf, sizeof(struct rkisp_async_subdev),
rkisp_fwnode_parse);
if (ret < 0)
return ret;
-
- if (!ntf->num_subdevs)
- return -ENODEV; /* no endpoint */
ntf->ops = &subdev_notifier_ops;
@@ -594,10 +716,6 @@
if (ret < 0) {
v4l2_err(&dev->v4l2_dev,
"Failed to register subdev notifier(%d)\n", ret);
- /* maybe use dmarx to input image */
- ret = v4l2_device_register_subdev_nodes(&dev->v4l2_dev);
- if (ret == 0)
- return 0;
goto err_unreg_luma_vdev;
}
@@ -694,12 +812,8 @@
sizeof(struct rkisp_thunderboot_resmem_head),
DMA_BIDIRECTIONAL);
ret = dma_mapping_error(dev, isp_dev->resmem_addr);
-
isp_dev->is_thunderboot = true;
- atomic_inc(&isp_dev->hw_dev->tb_ref);
-
- dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n",
- (u32)isp_dev->resmem_pa);
+ dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa);
return ret;
}
@@ -708,41 +822,49 @@
struct device *dev = &pdev->dev;
struct v4l2_device *v4l2_dev;
struct rkisp_device *isp_dev;
- int i, ret;
+ int i, ret, mult = 1;
- sprintf(rkisp_version, "v%02x.%02x.%02x",
- RKISP_DRIVER_VERSION >> 16,
- (RKISP_DRIVER_VERSION & 0xff00) >> 8,
- RKISP_DRIVER_VERSION & 0x00ff);
+ snprintf(rkisp_version, sizeof(rkisp_version),
+ "v%02x.%02x.%02x",
+ RKISP_DRIVER_VERSION >> 16,
+ (RKISP_DRIVER_VERSION & 0xff00) >> 8,
+ RKISP_DRIVER_VERSION & 0x00ff);
dev_info(dev, "rkisp driver version: %s\n", rkisp_version);
isp_dev = devm_kzalloc(dev, sizeof(*isp_dev), GFP_KERNEL);
if (!isp_dev)
return -ENOMEM;
- isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE, GFP_KERNEL);
- if (!isp_dev->sw_base_addr)
- return -ENOMEM;
dev_set_drvdata(dev, isp_dev);
isp_dev->dev = dev;
+ ret = rkisp_attach_hw(isp_dev);
+ if (ret)
+ return ret;
+
+ if (isp_dev->hw_dev->is_unite)
+ mult = 2;
+ isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL);
+ if (!isp_dev->sw_base_addr)
+ return -ENOMEM;
ret = rkisp_vs_irq_parse(dev);
if (ret)
return ret;
- ret = rkisp_attach_hw(isp_dev);
+ snprintf(isp_dev->media_dev.model, sizeof(isp_dev->media_dev.model),
+ "%s%d", DRIVER_NAME, isp_dev->dev_id);
+ if (!isp_dev->hw_dev->is_unite)
+ strscpy(isp_dev->name, dev_name(dev), sizeof(isp_dev->name));
+ else
+ snprintf(isp_dev->name, sizeof(isp_dev->name),
+ "%s%d", "rkisp-unite", isp_dev->dev_id);
+ strscpy(isp_dev->media_dev.driver_name, isp_dev->name,
+ sizeof(isp_dev->media_dev.driver_name));
+
+ ret = rkisp_get_reserved_mem(isp_dev);
if (ret)
return ret;
-
- sprintf(isp_dev->media_dev.model, "%s%d",
- DRIVER_NAME, isp_dev->dev_id);
-
- if (isp_dev->hw_dev->is_thunderboot) {
- ret = rkisp_get_reserved_mem(isp_dev);
- if (ret)
- return ret;
- }
mutex_init(&isp_dev->apilock);
mutex_init(&isp_dev->iqlock);
@@ -761,9 +883,6 @@
}
}
- strscpy(isp_dev->name, dev_name(dev), sizeof(isp_dev->name));
- strscpy(isp_dev->media_dev.driver_name, isp_dev->name,
- sizeof(isp_dev->media_dev.driver_name));
isp_dev->media_dev.dev = dev;
isp_dev->media_dev.ops = &rkisp_media_ops;
@@ -786,11 +905,13 @@
goto err_unreg_v4l2_dev;
}
+ pm_runtime_enable(dev);
/* create & register platefom subdev (from of_node) */
ret = rkisp_register_platform_subdevs(isp_dev);
- if (ret < 0)
+ if (ret < 0) {
+ v4l2_err(v4l2_dev, "Failed to register platform subdevs:%d\n", ret);
goto err_unreg_media_dev;
-
+ }
rkisp_wait_line = 0;
of_property_read_u32(dev->of_node, "wait-line", &rkisp_wait_line);
@@ -799,10 +920,7 @@
mutex_lock(&rkisp_dev_mutex);
list_add_tail(&isp_dev->list, &rkisp_device_list);
mutex_unlock(&rkisp_dev_mutex);
-
- pm_runtime_enable(dev);
- if (isp_dev->hw_dev->is_thunderboot && isp_dev->is_thunderboot)
- pm_runtime_get_noresume(isp_dev->hw_dev->dev);
+ isp_dev->is_probe_end = true;
return 0;
err_unreg_media_dev:
@@ -816,11 +934,17 @@
{
struct rkisp_device *isp_dev = platform_get_drvdata(pdev);
+ isp_dev->is_hw_link = false;
+ isp_dev->hw_dev->isp[isp_dev->dev_id] = NULL;
+
pm_runtime_disable(&pdev->dev);
rkisp_proc_cleanup(isp_dev);
media_device_unregister(&isp_dev->media_dev);
+ v4l2_async_notifier_unregister(&isp_dev->notifier);
+ v4l2_async_notifier_cleanup(&isp_dev->notifier);
v4l2_device_unregister(&isp_dev->v4l2_dev);
+ v4l2_ctrl_handler_free(&isp_dev->ctrl_handler);
rkisp_unregister_luma_vdev(&isp_dev->luma_vdev);
rkisp_unregister_params_vdev(&isp_dev->params_vdev);
rkisp_unregister_stats_vdev(&isp_dev->stats_vdev);
@@ -849,7 +973,14 @@
struct rkisp_device *isp_dev = dev_get_drvdata(dev);
int ret;
+ /* power on to config default format from sensor */
+ if (isp_dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS | INP_CIF) &&
+ rkisp_update_sensor_info(isp_dev) >= 0)
+ _set_pipeline_default_fmt(isp_dev, false);
+
isp_dev->cap_dev.wait_line = rkisp_wait_line;
+ isp_dev->cap_dev.wrap_line = rkisp_wrap_line;
+ isp_dev->is_rdbk_auto = rkisp_rdbk_auto;
mutex_lock(&isp_dev->hw_dev->dev_lock);
ret = pm_runtime_get_sync(isp_dev->hw_dev->dev);
mutex_unlock(&isp_dev->hw_dev->dev_lock);
@@ -894,3 +1025,4 @@
MODULE_AUTHOR("Rockchip Camera/ISP team");
MODULE_DESCRIPTION("Rockchip ISP platform driver");
MODULE_LICENSE("Dual BSD/GPL");
+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
--
Gitblit v1.6.2