author: andy.hu <andy.hu@starfivetech.com> 2023-06-20 09:25:27 +0000
committer: andy.hu <andy.hu@starfivetech.com> 2023-06-20 09:25:27 +0000
commit: 11ecf33c599661c28e8a4bd8966e06ff5951b805
parent: b39db4c6d0b91b1a4e347912a5f6508207882109
Commit Summary:
Diffstat:
6 files changed, 107 insertions, 68 deletions
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi.c b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
index 4f5d615ad14b..9f905d0ed0d8 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
@@ -12,15 +12,23 @@
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
-static const struct csi_format csi_formats_st7110[] = {
- { MEDIA_BUS_FMT_YUYV8_2X8, 16},
- { MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
+static const struct csi_format csi_formats_sink[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
{ MEDIA_BUS_FMT_SRGGB10_1X10, 10},
{ MEDIA_BUS_FMT_SGRBG10_1X10, 10},
{ MEDIA_BUS_FMT_SGBRG10_1X10, 10},
{ MEDIA_BUS_FMT_SBGGR10_1X10, 10},
};
+/* this bpp need see csi controllor */
+static const struct csi_format csi_formats_src[] = {
+ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
+ { MEDIA_BUS_FMT_SRGGB10_1X10, 16},
+ { MEDIA_BUS_FMT_SGRBG10_1X10, 16},
+ { MEDIA_BUS_FMT_SGBRG10_1X10, 16},
+ { MEDIA_BUS_FMT_SBGGR10_1X10, 16},
+};
+
static int csi_find_format(u32 code,
const struct csi_format *formats,
unsigned int nformats)
@@ -40,8 +48,10 @@ int stf_csi_subdev_init(struct stfcamss *stfcamss)
csi_dev->s_type = SENSOR_VIN;
csi_dev->hw_ops = &csi_ops;
csi_dev->stfcamss = stfcamss;
- csi_dev->formats = csi_formats_st7110;
- csi_dev->nformats = ARRAY_SIZE(csi_formats_st7110);
+ csi_dev->formats_sink = csi_formats_sink;
+ csi_dev->nformats_sink = ARRAY_SIZE(csi_formats_sink);
+ csi_dev->formats_src = csi_formats_src;
+ csi_dev->nformats_src = ARRAY_SIZE(csi_formats_src);
mutex_init(&csi_dev->stream_lock);
return 0;
}
@@ -74,10 +84,8 @@ static u32 code_to_data_type(int code)
case MEDIA_BUS_FMT_SGBRG10_1X10:
case MEDIA_BUS_FMT_SBGGR10_1X10:
return 0x2b;
- case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_UYVY8_2X8:
return 0x1E;
- case MEDIA_BUS_FMT_RGB565_2X8_LE:
- return 0x22;
default:
return 0x2b;
}
@@ -89,8 +97,9 @@ static int csi_set_stream(struct v4l2_subdev *sd, int enable)
struct v4l2_mbus_framefmt *format;
int ret = 0;
u32 code, width, dt;
+ u8 bpp;
- format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SRC,
+ format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SINK,
V4L2_SUBDEV_FORMAT_ACTIVE);
if (format == NULL)
return -EINVAL;
@@ -98,26 +107,27 @@ static int csi_set_stream(struct v4l2_subdev *sd, int enable)
width = format->width;
ret = csi_find_format(format->code,
- csi_dev->formats,
- csi_dev->nformats);
+ csi_dev->formats_sink,
+ csi_dev->nformats_sink);
if (ret < 0)
return ret;
- code = csi_dev->formats[ret].code;
+ code = csi_dev->formats_sink[ret].code;
+ bpp = csi_dev->formats_src[ret].bpp;
dt = code_to_data_type(code);
mutex_lock(&csi_dev->stream_lock);
if (enable) {
if (csi_dev->stream_count == 0) {
csi_dev->hw_ops->csi_clk_enable(csi_dev);
- csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width);
+ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
}
csi_dev->stream_count++;
} else {
if (csi_dev->stream_count == 0)
goto exit;
if (csi_dev->stream_count == 1) {
- csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width);
+ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
csi_dev->hw_ops->csi_clk_disable(csi_dev);
}
csi_dev->stream_count--;
@@ -139,12 +149,12 @@ static void csi_try_format(struct stf_csi_dev *csi_dev,
case STF_CSI_PAD_SINK:
/* Set format on sink pad */
- for (i = 0; i < csi_dev->nformats; i++)
- if (fmt->code == csi_dev->formats[i].code)
+ for (i = 0; i < csi_dev->nformats_sink; i++)
+ if (fmt->code == csi_dev->formats_sink[i].code)
break;
- if (i >= csi_dev->nformats)
- fmt->code = csi_dev->formats[0].code;
+ if (i >= csi_dev->nformats_sink)
+ fmt->code = csi_dev->formats_sink[0].code;
fmt->width = clamp_t(u32,
fmt->width,
@@ -163,8 +173,27 @@ static void csi_try_format(struct stf_csi_dev *csi_dev,
break;
case STF_CSI_PAD_SRC:
+ /* Set format on src pad */
+
+ for (i = 0; i < csi_dev->nformats_src; i++)
+ if (fmt->code == csi_dev->formats_src[i].code)
+ break;
+
+ if (i >= csi_dev->nformats_src)
+ fmt->code = csi_dev->formats_src[0].code;
+
+ fmt->width = clamp_t(u32,
+ fmt->width,
+ STFCAMSS_FRAME_MIN_WIDTH,
+ STFCAMSS_FRAME_MAX_WIDTH);
+ fmt->height = clamp_t(u32,
+ fmt->height,
+ STFCAMSS_FRAME_MIN_HEIGHT,
+ STFCAMSS_FRAME_MAX_HEIGHT);
- *fmt = *__csi_get_format(csi_dev, state, STF_CSI_PAD_SINK, which);
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
+ fmt->flags = 0;
break;
}
@@ -176,10 +205,10 @@ static int csi_enum_mbus_code(struct v4l2_subdev *sd,
{
struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
- if (code->index >= csi_dev->nformats)
+ if (code->index >= csi_dev->nformats_sink)
return -EINVAL;
if (code->pad == STF_CSI_PAD_SINK) {
- code->code = csi_dev->formats[code->index].code;
+ code->code = csi_dev->formats_sink[code->index].code;
} else {
struct v4l2_mbus_framefmt *sink_fmt;
@@ -247,6 +276,8 @@ static int csi_set_format(struct v4l2_subdev *sd,
{
struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
struct v4l2_mbus_framefmt *format;
+ struct v4l2_mbus_framefmt *format_src;
+ int ret;
format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
if (format == NULL)
@@ -263,13 +294,17 @@ static int csi_set_format(struct v4l2_subdev *sd,
}
mutex_unlock(&csi_dev->stream_lock);
- /* Propagate the format from sink to source */
if (fmt->pad == STF_CSI_PAD_SINK) {
- format = __csi_get_format(csi_dev, state, STF_CSI_PAD_SRC,
+ format_src = __csi_get_format(csi_dev, state, STF_DVP_PAD_SRC,
fmt->which);
- *format = fmt->format;
- csi_try_format(csi_dev, state, STF_CSI_PAD_SRC, format,
+ ret = csi_find_format(format->code, csi_dev->formats_sink,
+ csi_dev->nformats_sink);
+ if (ret < 0)
+ return ret;
+
+ format_src->code = csi_dev->formats_src[ret].code;
+ csi_try_format(csi_dev, state, STF_DVP_PAD_SRC, format_src,
fmt->which);
}
out:
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi.h b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
index 6d5dc73f82a1..f55b67b7ddba 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
@@ -30,9 +30,8 @@ struct csi_hw_ops {
int (*csi_power_on)(struct stf_csi_dev *csi_dev, u8 on);
int (*csi_clk_enable)(struct stf_csi_dev *csi_dev);
int (*csi_clk_disable)(struct stf_csi_dev *csi_dev);
- int (*csi_set_format)(struct stf_csi_dev *csi_dev,
- u32 vsize, u8 bpp, int is_raw10);
- int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on, u32 dt, u32 width);
+ int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on,
+ u32 dt, u32 width, u8 bpp);
};
struct stf_csi_dev {
@@ -41,8 +40,10 @@ struct stf_csi_dev {
struct v4l2_subdev subdev;
struct media_pad pads[STF_CSI_PADS_NUM];
struct v4l2_mbus_framefmt fmt[STF_CSI_PADS_NUM];
- const struct csi_format *formats;
- unsigned int nformats;
+ const struct csi_format *formats_sink;
+ unsigned int nformats_sink;
+ const struct csi_format *formats_src;
+ unsigned int nformats_src;
struct csi_hw_ops *hw_ops;
struct mutex stream_lock;
int stream_count;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
index 4af0ca8119e0..ff8c2f33ad7a 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
@@ -226,8 +226,28 @@ static void csi2rx_stop(struct stf_csi_dev *csi_dev, void *reg_base)
writel(0, reg_base + CSI2RX_STREAM_CTRL_REG(i));
}
+static void csi_set_vin_axiwr_pix(struct stf_csi_dev *csi_dev, u32 width, u8 bpp)
+{
+ struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
+ u32 value = 0;
+ int cnfg_axiwr_pix_ct = 64 / bpp;
+
+ if (cnfg_axiwr_pix_ct == 2)
+ value = 0;
+ else if (cnfg_axiwr_pix_ct == 4)
+ value = 1;
+ else if (cnfg_axiwr_pix_ct == 8)
+ value = 2;
+
+ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
+ BIT(14)|BIT(13), value << 13); //u0_vin_cnfg_axiwr0_pix_ct
+ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
+ BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
+ (width / cnfg_axiwr_pix_ct - 1)<<2); //u0_vin_cnfg_axiwr0_pix_cnt_end
+}
+
static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
- int on, u32 dt, u32 width)
+ int on, u32 dt, u32 width, u8 bpp)
{
struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
void __iomem *reg_base = vin->csi2rx_base;
@@ -237,15 +257,10 @@ static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20,
BIT(3)|BIT(2)|BIT(1)|BIT(0),
0<<0); //u0_vin_cnfg_axiwr0_channel_sel
- reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
- BIT(14)|BIT(13),
- 1<<13); //u0_vin_cnfg_axiwr0_pix_ct
reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
BIT(16)|BIT(15),
0<<15); //u0_vin_cnfg_axiwr0_pixel_high_bit_sel
- reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
- BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
- (width / 4 - 1)<<2); //u0_vin_cnfg_axiwr0_pix_cnt_end
+ csi_set_vin_axiwr_pix(csi_dev, width, bpp);
break;
case SENSOR_ISP:
reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
index 2e57ee2df513..4ef8e021009e 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
@@ -13,8 +13,7 @@
#include <media/v4l2-subdev.h>
static const struct csiphy_format csiphy_formats_st7110[] = {
- { MEDIA_BUS_FMT_YUYV8_2X8, 16},
- { MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
+ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
{ MEDIA_BUS_FMT_SRGGB10_1X10, 10},
{ MEDIA_BUS_FMT_SGRBG10_1X10, 10},
{ MEDIA_BUS_FMT_SGBRG10_1X10, 10},
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_video.c b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
index ea38dafe8857..83ff347615f9 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
@@ -14,6 +14,8 @@
#include <media/videobuf2-dma-contig.h>
static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
+ { MEDIA_BUS_FMT_AYUV8_1X32, V4L2_PIX_FMT_AYUV32, 1,
+ { { 1, 1 } }, { { 1, 1 } }, { 32 } },
{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
{ { 1, 1 } }, { { 1, 1 } }, { 16 } },
{ MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_PIX_FMT_RGB565, 1,
@@ -867,11 +869,12 @@ static int video_g_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
static int video_entity_s_fmt(struct stfcamss_video *video,
struct media_entity *entity,
struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *fmt, u32 dst_code)
+ struct v4l2_subdev_format *fmt)
{
struct v4l2_subdev *subdev;
struct media_pad *pad;
struct v4l2_mbus_framefmt *mf = &fmt->format;
+ struct v4l2_subdev_format fmt_src;
u32 width, height, code;
int ret, index = 0;
@@ -886,13 +889,7 @@ static int video_entity_s_fmt(struct stfcamss_video *video,
pad = media_entity_remote_pad(pad);
if (pad && is_media_entity_v4l2_subdev(pad->entity)) {
fmt->pad = index;
- if (index)
- mf->code = dst_code;
ret = v4l2_subdev_call(subdev, pad, set_fmt, state, fmt);
- st_warn(ST_VIDEO,
- "\"%s\":%d pad fmt set to 0x%x %ux%u, dst_code = 0x%x, ret=%d\n",
- subdev->name, fmt->pad, mf->code,
- mf->width, mf->height, dst_code, ret);
if (mf->code != code ||
mf->width != width || mf->height != height) {
st_warn(ST_VIDEO,
@@ -901,8 +898,16 @@ static int video_entity_s_fmt(struct stfcamss_video *video,
subdev->name, fmt->pad, mf->code,
mf->width, mf->height);
}
- if (index)
- ret = video_entity_s_fmt(video, pad->entity, state, fmt, dst_code);
+ if (index) {
+ fmt_src.pad = index;
+ fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt_src);
+ if (ret)
+ return ret;
+
+ fmt->format.code = fmt_src.format.code;
+ ret = video_entity_s_fmt(video, pad->entity, state, fmt);
+ }
}
if (ret < 0 && ret != -ENOIOCTLCMD)
@@ -921,6 +926,7 @@ static int video_pipeline_s_fmt(struct stfcamss_video *video,
struct v4l2_subdev *subdev;
int ret, index;
struct v4l2_subdev_format fmt = {
+ .pad = 0,
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.reserved = {getcrop_pad_id(video->id)}
};
@@ -948,37 +954,27 @@ static int video_pipeline_s_fmt(struct stfcamss_video *video,
return index;
v4l2_fill_mbus_format(mf, pix, video->formats[index].code);
}
- code = mf->code;
+
width = mf->width;
height = mf->height;
+
sensor = stfcamss_find_sensor(entity);
- if (sensor) {
- subdev = media_entity_to_v4l2_subdev(sensor);
- ret = v4l2_subdev_call(subdev, pad, set_fmt, state, &fmt);
- st_warn(ST_VIDEO,
- "\"%s\":%d pad fmt set to 0x%x %ux%u\n",
- subdev->name, fmt.pad, mf->code,
- mf->width, mf->height);
- if (mf->code != code ||
- mf->width != width || mf->height != height) {
- st_warn(ST_VIDEO,
- "\"%s\":%d pad fmt has been"
- " changed to 0x%x %ux%u\n",
- subdev->name, fmt.pad, mf->code,
- mf->width, mf->height);
- }
- } else {
+ if (!sensor) {
st_err(ST_VIDEO, "Can't find sensor\n");
return -ENOTTY;
}
+
+ subdev = media_entity_to_v4l2_subdev(sensor);
+ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt);
+ if (ret)
+ return ret;
+
/*
* Starting from sensor subdevice, walk within
* pipeline and set format on each subdevice
*/
- sensor = stfcamss_find_sensor(entity);
pad = media_entity_remote_pad(&sensor->pads[0]);
- ret = video_entity_s_fmt(video, pad->entity, state, &fmt, code);
-
+ ret = video_entity_s_fmt(video, pad->entity, state, &fmt);
if (ret < 0 && ret != -ENOIOCTLCMD)
return ret;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
index a716be49a0eb..5758ab77d7ea 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
@@ -45,6 +45,7 @@ static const struct vin2_format vin2_formats_st7110[] = {
{ MEDIA_BUS_FMT_SBGGR12_1X12, 12},
{ MEDIA_BUS_FMT_Y12_1X12, 8},
{ MEDIA_BUS_FMT_YUV8_1X24, 8},
+ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
};
static const struct vin2_format isp_formats_st7110_raw[] = {