media: rockchip: vicap compatible with rk3588s2

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: Idd8312275b97b690de378094116d558e85b4cb00
This commit is contained in:
Zefa Chen
2022-12-21 10:19:50 +08:00
committed by Tao Huang
parent a8c5673b5b
commit a9ed7b93e6
7 changed files with 110 additions and 21 deletions

View File

@@ -847,10 +847,11 @@ static int get_csi_crop_align(const struct cif_input_fmt *fmt_in)
}
const struct
cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd, struct v4l2_rect *rect,
cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev, struct v4l2_rect *rect,
u32 pad_id, struct csi_channel_info *csi_info)
{
struct v4l2_subdev_format fmt;
struct v4l2_subdev *sd = dev->terminal_sensor.sd;
struct rkmodule_channel_info ch_info = {0};
struct rkmodule_capture_info capture_info;
int ret;
@@ -914,8 +915,22 @@ cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd, struct v4l2_rect *rect,
core, ioctl,
RKMODULE_GET_CAPTURE_MODE,
&capture_info);
if (!ret)
if (!ret) {
if (capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
dev->hw_dev->is_rk3588s2) {
for (i = 0; i < capture_info.multi_dev.dev_num; i++) {
if (capture_info.multi_dev.dev_idx[i] == 0)
capture_info.multi_dev.dev_idx[i] = 2;
else if (capture_info.multi_dev.dev_idx[i] == 2)
capture_info.multi_dev.dev_idx[i] = 4;
else if (capture_info.multi_dev.dev_idx[i] == 3)
capture_info.multi_dev.dev_idx[i] = 5;
}
}
csi_info->capture_info = capture_info;
} else {
csi_info->capture_info.mode = RKMODULE_CAPTURE_MODE_NONE;
}
for (i = 0; i < ARRAY_SIZE(in_fmts); i++)
if (fmt.format.code == in_fmts[i].mbus_code &&
fmt.format.field == in_fmts[i].field)
@@ -5362,9 +5377,9 @@ static int rkcif_sanity_check_fmt(struct rkcif_stream *stream,
struct v4l2_rect input, *crop;
if (dev->terminal_sensor.sd) {
stream->cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
&input, stream->id,
&dev->channels[stream->id]);
stream->cif_fmt_in = rkcif_get_input_fmt(dev,
&input, stream->id,
&dev->channels[stream->id]);
if (!stream->cif_fmt_in) {
v4l2_err(v4l2_dev, "Input fmt is invalid\n");
return -EINVAL;
@@ -6146,10 +6161,15 @@ int rkcif_do_start_stream(struct rkcif_stream *stream, unsigned int mode)
csi_info.csi_num, RKCIF_MAX_CSI_NUM);
goto out;
}
for (i = 0; i < csi_info.csi_num; i++)
for (i = 0; i < csi_info.csi_num; i++) {
csi_info.csi_idx[i] = dev->channels[0].capture_info.multi_dev.dev_idx[i];
if (dev->hw_dev->is_rk3588s2)
v4l2_info(v4l2_dev, "rk3588s2 combine mode attach to mipi%d\n",
csi_info.csi_idx[i]);
}
} else {
csi_info.csi_num = 1;
dev->csi_host_idx = dev->csi_host_idx_def;
csi_info.csi_idx[0] = dev->csi_host_idx;
}
ret = v4l2_subdev_call(dev->active_sensor->sd,
@@ -6350,9 +6370,9 @@ int rkcif_set_fmt(struct rkcif_stream *stream,
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (dev->terminal_sensor.sd) {
cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
&input_rect, stream->id,
channel_info);
cif_fmt_in = rkcif_get_input_fmt(dev,
&input_rect, stream->id,
channel_info);
stream->cif_fmt_in = cif_fmt_in;
} else {
v4l2_err(&stream->cifdev->v4l2_dev,
@@ -6720,9 +6740,9 @@ static int rkcif_enum_framesizes(struct file *file, void *prov,
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (dev->terminal_sensor.sd)
get_input_fmt(dev->terminal_sensor.sd,
&input_rect, stream->id,
&csi_info);
rkcif_get_input_fmt(dev,
&input_rect, stream->id,
&csi_info);
if (dev->hw_dev->adapt_to_usbcamerahal) {
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
@@ -6801,7 +6821,7 @@ static int rkcif_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
return -EINVAL;
if (dev->terminal_sensor.sd) {
cif_fmt_in = get_input_fmt(dev->terminal_sensor.sd,
cif_fmt_in = rkcif_get_input_fmt(dev,
&input_rect, stream->id,
&dev->channels[stream->id]);
stream->cif_fmt_in = cif_fmt_in;
@@ -7187,8 +7207,8 @@ static long rkcif_ioctl_default(struct file *file, void *fh,
break;
case RKCIF_CMD_SET_CSI_MEMORY_MODE:
if (dev->terminal_sensor.sd) {
in_fmt = get_input_fmt(dev->terminal_sensor.sd,
&rect, 0, &csi_info);
in_fmt = rkcif_get_input_fmt(dev,
&rect, 0, &csi_info);
if (in_fmt == NULL) {
v4l2_err(&dev->v4l2_dev, "can't get sensor input format\n");
return -EINVAL;

View File

@@ -364,8 +364,8 @@ static int rkcif_scale_enum_framesizes(struct file *file, void *prov,
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (terminal_sensor && terminal_sensor->sd)
get_input_fmt(terminal_sensor->sd,
&input_rect, 0, &csi_info);
rkcif_get_input_fmt(dev,
&input_rect, 0, &csi_info);
switch (fsize->index) {
case SCALE_8TIMES:

View File

@@ -300,8 +300,8 @@ static int rkcif_tools_enum_framesizes(struct file *file, void *prov,
input_rect.height = RKCIF_DEFAULT_HEIGHT;
if (terminal_sensor && terminal_sensor->sd)
get_input_fmt(terminal_sensor->sd,
&input_rect, 0, &csi_info);
rkcif_get_input_fmt(dev,
&input_rect, 0, &csi_info);
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
s->width = input_rect.width;

View File

@@ -1998,6 +1998,17 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
cif_dev->csi_host_idx = of_alias_get_id(node, "rkcif_mipi_lvds");
if (cif_dev->csi_host_idx < 0 || cif_dev->csi_host_idx > 5)
cif_dev->csi_host_idx = 0;
if (cif_dev->hw_dev->is_rk3588s2) {
if (cif_dev->csi_host_idx == 0)
cif_dev->csi_host_idx = 2;
else if (cif_dev->csi_host_idx == 2)
cif_dev->csi_host_idx = 4;
else if (cif_dev->csi_host_idx == 3)
cif_dev->csi_host_idx = 5;
v4l2_info(&cif_dev->v4l2_dev, "rk3588s2 attach to mipi%d\n",
cif_dev->csi_host_idx);
}
cif_dev->csi_host_idx_def = cif_dev->csi_host_idx;
cif_dev->media_dev.dev = dev;
v4l2_dev = &cif_dev->v4l2_dev;
v4l2_dev->mdev = &cif_dev->media_dev;
@@ -2160,7 +2171,9 @@ static int rkcif_plat_probe(struct platform_device *pdev)
if (sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp))
return -ENODEV;
rkcif_attach_hw(cif_dev);
ret = rkcif_attach_hw(cif_dev);
if (ret)
return ret;
rkcif_parse_dts(cif_dev);

View File

@@ -845,6 +845,7 @@ struct rkcif_device {
struct rkcif_work_struct reset_work;
int id_use_cnt;
unsigned int csi_host_idx;
unsigned int csi_host_idx_def;
unsigned int dvp_sof_in_oneframe;
unsigned int wait_line;
unsigned int wait_line_bak;
@@ -887,7 +888,7 @@ void rkcif_vb_done_tasklet(struct rkcif_stream *stream, struct rkcif_buffer *buf
int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev);
const struct
cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd,
cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev,
struct v4l2_rect *rect,
u32 pad_id, struct csi_channel_info *csi_info);

View File

@@ -8,6 +8,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_graph.h>
@@ -1252,6 +1253,51 @@ void rkcif_hw_soft_reset(struct rkcif_hw *cif_hw, bool is_rst_iommu)
rkcif_iommu_enable(cif_hw);
}
static int rkcif_get_efuse_value(struct device_node *np, char *porp_name,
u8 *value)
{
struct nvmem_cell *cell;
unsigned char *buf;
size_t len;
cell = of_nvmem_cell_get(np, porp_name);
if (IS_ERR(cell))
return PTR_ERR(cell);
buf = (unsigned char *)nvmem_cell_read(cell, &len);
nvmem_cell_put(cell);
if (IS_ERR(buf))
return PTR_ERR(buf);
*value = buf[0];
kfree(buf);
return 0;
}
static int rkcif_get_speciand_package_number(struct device_node *np)
{
u8 spec = 0, package = 0, low = 0, high = 0;
if (rkcif_get_efuse_value(np, "specification", &spec))
return -EINVAL;
if (rkcif_get_efuse_value(np, "package_low", &low))
return -EINVAL;
if (rkcif_get_efuse_value(np, "package_high", &high))
return -EINVAL;
package = ((high & 0x1) << 3) | low;
/* RK3588S */
if (spec == 0x13)
return package;
return -EINVAL;
}
static int rkcif_plat_hw_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -1265,6 +1311,7 @@ static int rkcif_plat_hw_probe(struct platform_device *pdev)
int i, ret, irq;
bool is_mem_reserved = false;
struct notifier_block *notifier;
int package = 0;
match = of_match_node(rkcif_plat_of_match, node);
if (IS_ERR(match))
@@ -1278,6 +1325,13 @@ static int rkcif_plat_hw_probe(struct platform_device *pdev)
dev_set_drvdata(dev, cif_hw);
cif_hw->dev = dev;
package = rkcif_get_speciand_package_number(node);
if (package == 0x2) {
cif_hw->is_rk3588s2 = true;
dev_info(dev, "attach rk3588s2\n");
} else {
cif_hw->is_rk3588s2 = false;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;

View File

@@ -150,6 +150,7 @@ struct rkcif_hw {
bool is_dma_contig;
bool adapt_to_usbcamerahal;
u64 irq_time;
bool is_rk3588s2;
};
void rkcif_hw_soft_reset(struct rkcif_hw *cif_hw, bool is_rst_iommu);