diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:35:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:31 +0000 |
commit | 85c675d0d09a45a135bddd15d7b385f8758c32fb (patch) | |
tree | 76267dbc9b9a130337be3640948fe397b04ac629 /drivers/media/platform/qcom/camss/camss-vfe.c | |
parent | Adding upstream version 6.6.15. (diff) | |
download | linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.tar.xz linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.zip |
Adding upstream version 6.7.7.upstream/6.7.7
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/media/platform/qcom/camss/camss-vfe.c')
-rw-r--r-- | drivers/media/platform/qcom/camss/camss-vfe.c | 227 |
1 files changed, 136 insertions, 91 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 965500b83d..4839e2cedf 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -37,10 +37,10 @@ struct vfe_format { }; static const struct vfe_format formats_rdi_8x16[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, - { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, - { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, - { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_UYVY8_1X16, 8 }, + { MEDIA_BUS_FMT_VYUY8_1X16, 8 }, + { MEDIA_BUS_FMT_YUYV8_1X16, 8 }, + { MEDIA_BUS_FMT_YVYU8_1X16, 8 }, { MEDIA_BUS_FMT_SBGGR8_1X8, 8 }, { MEDIA_BUS_FMT_SGBRG8_1X8, 8 }, { MEDIA_BUS_FMT_SGRBG8_1X8, 8 }, @@ -57,17 +57,17 @@ static const struct vfe_format formats_rdi_8x16[] = { }; static const struct vfe_format formats_pix_8x16[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, - { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, - { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, - { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_UYVY8_1X16, 8 }, + { MEDIA_BUS_FMT_VYUY8_1X16, 8 }, + { MEDIA_BUS_FMT_YUYV8_1X16, 8 }, + { MEDIA_BUS_FMT_YVYU8_1X16, 8 }, }; static const struct vfe_format formats_rdi_8x96[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, - { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, - { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, - { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_UYVY8_1X16, 8 }, + { MEDIA_BUS_FMT_VYUY8_1X16, 8 }, + { MEDIA_BUS_FMT_YUYV8_1X16, 8 }, + { MEDIA_BUS_FMT_YVYU8_1X16, 8 }, { MEDIA_BUS_FMT_SBGGR8_1X8, 8 }, { MEDIA_BUS_FMT_SGBRG8_1X8, 8 }, { MEDIA_BUS_FMT_SGRBG8_1X8, 8 }, @@ -90,17 +90,17 @@ static const struct vfe_format formats_rdi_8x96[] = { }; static const struct vfe_format formats_pix_8x96[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, - { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, - { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, - { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_UYVY8_1X16, 8 }, + { MEDIA_BUS_FMT_VYUY8_1X16, 8 }, + { MEDIA_BUS_FMT_YUYV8_1X16, 8 }, + { MEDIA_BUS_FMT_YVYU8_1X16, 8 }, }; static const struct vfe_format formats_rdi_845[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, - { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, - { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, - { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_UYVY8_1X16, 8 }, + { MEDIA_BUS_FMT_VYUY8_1X16, 8 }, + { MEDIA_BUS_FMT_YUYV8_1X16, 8 }, + { MEDIA_BUS_FMT_YVYU8_1X16, 8 }, { MEDIA_BUS_FMT_SBGGR8_1X8, 8 }, { MEDIA_BUS_FMT_SGBRG8_1X8, 8 }, { MEDIA_BUS_FMT_SGRBG8_1X8, 8 }, @@ -170,42 +170,43 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, { struct vfe_device *vfe = to_vfe(line); - if (vfe->camss->version == CAMSS_8x16) + switch (vfe->camss->res->version) { + case CAMSS_8x16: switch (sink_code) { - case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_YVYU8_1X16, MEDIA_BUS_FMT_YVYU8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_VYUY8_1X16, MEDIA_BUS_FMT_VYUY8_1_5X8, }; @@ -218,57 +219,58 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, return sink_code; } - else if (vfe->camss->version == CAMSS_8x96 || - vfe->camss->version == CAMSS_660 || - vfe->camss->version == CAMSS_845 || - vfe->camss->version == CAMSS_8250) + break; + case CAMSS_8x96: + case CAMSS_660: + case CAMSS_845: + case CAMSS_8250: switch (sink_code) { - case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YVYU8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_VYUY8_1X16, MEDIA_BUS_FMT_YUYV8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YVYU8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_VYUY8_1X16, MEDIA_BUS_FMT_YVYU8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YVYU8_1X16, + MEDIA_BUS_FMT_VYUY8_1X16, MEDIA_BUS_FMT_UYVY8_1_5X8, }; return vfe_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } - case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_1X16: { u32 src_code[] = { - MEDIA_BUS_FMT_VYUY8_2X8, - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YVYU8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_VYUY8_1_5X8, }; @@ -281,8 +283,9 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, return sink_code; } - else - return 0; + break; + } + return 0; } int vfe_reset(struct vfe_device *vfe) @@ -407,6 +410,49 @@ int vfe_put_output(struct vfe_line *line) return 0; } +static int vfe_disable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&vfe->output_lock, flags); + for (i = 0; i < output->wm_num; i++) + vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]); + output->gen2.active_num = 0; + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return vfe_reset(vfe); +} + +/* + * vfe_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +int vfe_disable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + int ret; + + ret = vfe_disable_output(line); + if (ret) + goto error; + + vfe_put_output(line); + + mutex_lock(&vfe->stream_lock); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + +error: + return ret; +} + /** * vfe_isr_comp_done() - Process composite image done interrupt * @vfe: VFE Device @@ -428,6 +474,20 @@ void vfe_isr_reset_ack(struct vfe_device *vfe) complete(&vfe->reset_complete); } +static int vfe_match_clock_names(struct vfe_device *vfe, + struct camss_clock *clock) +{ + char vfe_name[7]; /* vfeXXX\0 */ + char vfe_lite_name[12]; /* vfe_liteXXX\0 */ + + snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id); + snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id); + + return (!strcmp(clock->name, vfe_name) || + !strcmp(clock->name, vfe_lite_name) || + !strcmp(clock->name, "vfe_lite")); +} + /* * vfe_set_clock_rates - Calculate and set clock rates on VFE module * @vfe: VFE device @@ -451,9 +511,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe) for (i = 0; i < vfe->nclocks; i++) { struct camss_clock *clock = &vfe->clock[i]; - if (!strcmp(clock->name, "vfe0") || - !strcmp(clock->name, "vfe1") || - !strcmp(clock->name, "vfe_lite")) { + if (vfe_match_clock_names(vfe, clock)) { u64 min_rate = 0; long rate; @@ -534,9 +592,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe) for (i = 0; i < vfe->nclocks; i++) { struct camss_clock *clock = &vfe->clock[i]; - if (!strcmp(clock->name, "vfe0") || - !strcmp(clock->name, "vfe1") || - !strcmp(clock->name, "vfe_lite")) { + if (vfe_match_clock_names(vfe, clock)) { u64 min_rate = 0; unsigned long rate; @@ -845,7 +901,7 @@ static void vfe_try_format(struct vfe_line *line, /* If not found, use UYVY as default */ if (i >= line->nformats) - fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; fmt->width = clamp_t(u32, fmt->width, 1, 8191); fmt->height = clamp_t(u32, fmt->height, 1, 8191); @@ -1262,7 +1318,7 @@ static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) .which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE, .format = { - .code = MEDIA_BUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .width = 1920, .height = 1080 } @@ -1279,32 +1335,19 @@ static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) * Return 0 on success or a negative error code otherwise */ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, - const struct resources *res, u8 id) + const struct camss_subdev_resources *res, u8 id) { struct device *dev = camss->dev; struct platform_device *pdev = to_platform_device(dev); int i, j; int ret; - switch (camss->version) { - case CAMSS_8x16: - vfe->ops = &vfe_ops_4_1; - break; - case CAMSS_8x96: - vfe->ops = &vfe_ops_4_7; - break; - case CAMSS_660: - vfe->ops = &vfe_ops_4_8; - break; - case CAMSS_845: - vfe->ops = &vfe_ops_170; - break; - case CAMSS_8250: - vfe->ops = &vfe_ops_480; - break; - default: + vfe->ops = res->ops; + + if (!res->line_num) return -EINVAL; - } + + vfe->line_num = res->line_num; vfe->ops->subdev_init(dev, vfe); /* Memory */ @@ -1392,7 +1435,8 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, init_completion(&l->output.sof); init_completion(&l->output.reg_update); - if (camss->version == CAMSS_8x16) { + switch (camss->res->version) { + case CAMSS_8x16: if (i == VFE_LINE_PIX) { l->formats = formats_pix_8x16; l->nformats = ARRAY_SIZE(formats_pix_8x16); @@ -1400,8 +1444,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, l->formats = formats_rdi_8x16; l->nformats = ARRAY_SIZE(formats_rdi_8x16); } - } else if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) { + break; + case CAMSS_8x96: + case CAMSS_660: if (i == VFE_LINE_PIX) { l->formats = formats_pix_8x96; l->nformats = ARRAY_SIZE(formats_pix_8x96); @@ -1409,12 +1454,12 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, l->formats = formats_rdi_8x96; l->nformats = ARRAY_SIZE(formats_rdi_8x96); } - } else if (camss->version == CAMSS_845 || - camss->version == CAMSS_8250) { + break; + case CAMSS_845: + case CAMSS_8250: l->formats = formats_rdi_845; l->nformats = ARRAY_SIZE(formats_rdi_845); - } else { - return -EINVAL; + break; } } @@ -1542,8 +1587,8 @@ int msm_vfe_register_entities(struct vfe_device *vfe, } video_out->ops = &vfe->video_ops; - if (vfe->camss->version == CAMSS_845 || - vfe->camss->version == CAMSS_8250) + if (vfe->camss->res->version == CAMSS_845 || + vfe->camss->res->version == CAMSS_8250) video_out->bpl_alignment = 16; else video_out->bpl_alignment = 8; |