[PATCH v2 5/8] staging: media: starfive: Add ISP bayer video device

From: Changhuang Liang
Date: Wed Apr 10 2024 - 05:11:33 EST


Add bayer video device to capture bayer format data from ISP.

Signed-off-by: Changhuang Liang <changhuang.liang@xxxxxxxxxxxxxxxx>
---
.../staging/media/starfive/camss/stf-camss.c | 12 ++++++
.../media/starfive/camss/stf-capture.c | 41 +++++++++++++++++++
.../media/starfive/camss/stf-isp-hw-ops.c | 19 +++++++++
.../staging/media/starfive/camss/stf-isp.h | 1 +
.../staging/media/starfive/camss/stf-video.h | 1 +
5 files changed, 74 insertions(+)

diff --git a/drivers/staging/media/starfive/camss/stf-camss.c b/drivers/staging/media/starfive/camss/stf-camss.c
index 62bf46a69a3e..b2f9892b7663 100644
--- a/drivers/staging/media/starfive/camss/stf-camss.c
+++ b/drivers/staging/media/starfive/camss/stf-camss.c
@@ -125,6 +125,7 @@ static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)

static int stfcamss_register_devs(struct stfcamss *stfcamss)
{
+ struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
struct stf_output *output = &stfcamss->output;
@@ -172,8 +173,17 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)
if (ret)
goto err_rm_links1;

+ ret = media_create_pad_link(&isp_dev->subdev.entity, STF_ISP_PAD_SRC_BAYER,
+ &cap_bayer->video.vdev.entity, 0, 0);
+ if (ret)
+ goto err_rm_links2;
+
+ cap_bayer->video.source_subdev = &isp_dev->subdev;
+
return ret;

+err_rm_links2:
+ media_entity_remove_links(&output->video.vdev.entity);
err_rm_links1:
media_entity_remove_links(&cap_scd->video.vdev.entity);
err_rm_links0:
@@ -191,6 +201,7 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)

static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
{
+ struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
struct stf_output *output = &stfcamss->output;
@@ -200,6 +211,7 @@ static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
media_entity_remove_links(&isp_dev->subdev.entity);
media_entity_remove_links(&cap_yuv->video.vdev.entity);
media_entity_remove_links(&cap_scd->video.vdev.entity);
+ media_entity_remove_links(&cap_bayer->video.vdev.entity);

stf_isp_unregister(&stfcamss->isp_dev);
stf_capture_unregister(stfcamss);
diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c
index 328b8c6e351d..21a59259d7a0 100644
--- a/drivers/staging/media/starfive/camss/stf-capture.c
+++ b/drivers/staging/media/starfive/camss/stf-capture.c
@@ -12,6 +12,7 @@
static const char * const stf_cap_names[] = {
"capture_raw",
"capture_yuv",
+ "capture_bayer",
"capture_scd",
};

@@ -56,6 +57,37 @@ static const struct stfcamss_format_info stf_isp_fmts[] = {
},
};

+static const struct stfcamss_format_info stf_isp_bayer_fmts[] = {
+ {
+ .code = MEDIA_BUS_FMT_SRGGB12_1X12,
+ .pixelformat = V4L2_PIX_FMT_SRGGB12,
+ .planes = 1,
+ .vsub = { 1 },
+ .bpp = 12,
+ },
+ {
+ .code = MEDIA_BUS_FMT_SGRBG12_1X12,
+ .pixelformat = V4L2_PIX_FMT_SGRBG12,
+ .planes = 1,
+ .vsub = { 1 },
+ .bpp = 12,
+ },
+ {
+ .code = MEDIA_BUS_FMT_SGBRG12_1X12,
+ .pixelformat = V4L2_PIX_FMT_SGBRG12,
+ .planes = 1,
+ .vsub = { 1 },
+ .bpp = 12,
+ },
+ {
+ .code = MEDIA_BUS_FMT_SBGGR12_1X12,
+ .pixelformat = V4L2_PIX_FMT_SBGGR12,
+ .planes = 1,
+ .vsub = { 1 },
+ .bpp = 12,
+ },
+};
+
/* 3A Statistics Collection Data */
static const struct stfcamss_format_info stf_isp_scd_fmts[] = {
{
@@ -93,6 +125,8 @@ static void stf_init_addrs(struct stfcamss_video *video)
stf_set_raw_addr(video->stfcamss, addr0);
else if (cap->type == STF_CAPTURE_YUV)
stf_set_yuv_addr(video->stfcamss, addr0, addr1);
+ else if (cap->type == STF_CAPTURE_BAYER)
+ stf_set_bayer_addr(video->stfcamss, addr0);
else
stf_set_scd_addr(video->stfcamss, addr0, addr1, TYPE_AWB);
}
@@ -251,6 +285,11 @@ static void stf_capture_init(struct stfcamss *stfcamss, struct stf_capture *cap)
cap->video.formats = stf_isp_fmts;
cap->video.nformats = ARRAY_SIZE(stf_isp_fmts);
cap->video.bpl_alignment = 1;
+ } else if (cap->type == STF_CAPTURE_BAYER) {
+ cap->video.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cap->video.formats = stf_isp_bayer_fmts;
+ cap->video.nformats = ARRAY_SIZE(stf_isp_bayer_fmts);
+ cap->video.bpl_alignment = 16 * 8;
} else {
cap->video.type = V4L2_BUF_TYPE_META_CAPTURE;
cap->video.formats = stf_isp_scd_fmts;
@@ -377,6 +416,7 @@ static void stf_capture_unregister_one(struct stf_capture *cap)

void stf_capture_unregister(struct stfcamss *stfcamss)
{
+ struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
struct stf_capture *cap_raw = &stfcamss->captures[STF_CAPTURE_RAW];
struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
@@ -384,6 +424,7 @@ void stf_capture_unregister(struct stfcamss *stfcamss)
stf_capture_unregister_one(cap_raw);
stf_capture_unregister_one(cap_yuv);
stf_capture_unregister_one(cap_scd);
+ stf_capture_unregister_one(cap_bayer);
}

int stf_capture_register(struct stfcamss *stfcamss,
diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
index 44ac472d9dc3..f170fab2bfb4 100644
--- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
+++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
@@ -515,6 +515,11 @@ void stf_set_scd_addr(struct stfcamss *stfcamss,
stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_4, yhist_addr);
}

+void stf_set_bayer_addr(struct stfcamss *stfcamss, dma_addr_t bayer_addr)
+{
+ stf_isp_reg_write(stfcamss, ISP_REG_DUMP_CFG_0, bayer_addr);
+}
+
static void stf_isp_fill_yhist(struct stfcamss *stfcamss, void *vaddr)
{
struct jh7110_isp_sc_buffer *sc = (struct jh7110_isp_sc_buffer *)vaddr;
@@ -596,6 +601,7 @@ static void stf_isp_set_params(struct stfcamss *stfcamss, void *vaddr)
irqreturn_t stf_line_irq_handler(int irq, void *priv)
{
struct stfcamss *stfcamss = priv;
+ struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
struct stfcamss_buffer *change_buf;
@@ -623,6 +629,12 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv)
change_buf->addr[1], type_scd);
}
}
+
+ if (value & CSI_DUMP_EN) {
+ change_buf = stf_change_buffer(&cap_bayer->buffers);
+ if (change_buf)
+ stf_set_bayer_addr(stfcamss, change_buf->addr[0]);
+ }
}

stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS,
@@ -640,6 +652,7 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv)
irqreturn_t stf_isp_irq_handler(int irq, void *priv)
{
struct stfcamss *stfcamss = priv;
+ struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
struct stf_output *output = &stfcamss->output;
@@ -668,6 +681,12 @@ irqreturn_t stf_isp_irq_handler(int irq, void *priv)
}
}

+ if (status & ISPC_CSI) {
+ ready_buf = stf_buf_done(&cap_bayer->buffers);
+ if (ready_buf)
+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
(status & ~ISPC_INT_ALL_MASK) |
ISPC_ISP | ISPC_CSI | ISPC_SC);
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index f63817b7a235..8505603bdbc5 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -592,6 +592,7 @@ int stf_isp_unregister(struct stf_isp_dev *isp_dev);

void stf_set_yuv_addr(struct stfcamss *stfcamss,
dma_addr_t y_addr, dma_addr_t uv_addr);
+void stf_set_bayer_addr(struct stfcamss *stfcamss, dma_addr_t bayer_addr);
void stf_set_scd_addr(struct stfcamss *stfcamss,
dma_addr_t yhist_addr, dma_addr_t scd_addr,
enum stf_isp_type_scd type_scd);
diff --git a/drivers/staging/media/starfive/camss/stf-video.h b/drivers/staging/media/starfive/camss/stf-video.h
index 53a1cf4e59b7..ea7ec92c3ff5 100644
--- a/drivers/staging/media/starfive/camss/stf-video.h
+++ b/drivers/staging/media/starfive/camss/stf-video.h
@@ -37,6 +37,7 @@ enum stf_v_line_id {
enum stf_capture_type {
STF_CAPTURE_RAW = 0,
STF_CAPTURE_YUV,
+ STF_CAPTURE_BAYER,
STF_CAPTURE_SCD,
STF_CAPTURE_NUM,
};
--
2.25.1