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