On Wed Oct 8 15:22:26 2025 +0530, Dikshita Agarwal wrote:
> Introduce handling for the QC08C format in the decoder. QC08C format is
> NV12 with UBWC compression. Update format checks and configuration to
> enable decoding of QC08C streams.
> 
> Signed-off-by: Dikshita Agarwal <[email protected]>
> Reviewed-by: Vikash Garodia <[email protected]>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/qcom/iris/iris_buffer.c     |  5 +-
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 12 +++--
 .../platform/qcom/iris/iris_hfi_gen2_command.c     |  3 +-
 drivers/media/platform/qcom/iris/iris_instance.h   |  7 ++-
 drivers/media/platform/qcom/iris/iris_utils.c      |  3 +-
 drivers/media/platform/qcom/iris/iris_vdec.c       | 61 ++++++++++++++++++----
 6 files changed, 72 insertions(+), 19 deletions(-)

---

diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c 
b/drivers/media/platform/qcom/iris/iris_buffer.c
index c0900038e7de..83dcf49e57ec 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -261,7 +261,10 @@ int iris_get_buffer_size(struct iris_inst *inst,
                case BUF_INPUT:
                        return iris_dec_bitstream_buffer_size(inst);
                case BUF_OUTPUT:
-                       return iris_yuv_buffer_size_nv12(inst);
+                       if (inst->fmt_dst->fmt.pix_mp.pixelformat == 
V4L2_PIX_FMT_QC08C)
+                               return iris_yuv_buffer_size_qc08c(inst);
+                       else
+                               return iris_yuv_buffer_size_nv12(inst);
                case BUF_DPB:
                        return iris_yuv_buffer_size_qc08c(inst);
                default:
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c 
b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index e1788c266bb1..e458d3349ce0 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -774,20 +774,21 @@ static int iris_hfi_gen1_set_raw_format(struct iris_inst 
*inst, u32 plane)
                pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
                if (iris_split_mode_enabled(inst)) {
                        fmt.buffer_type = HFI_BUFFER_OUTPUT;
-                       fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
-                               HFI_COLOR_FORMAT_NV12_UBWC : 0;
+                       fmt.format = HFI_COLOR_FORMAT_NV12_UBWC;
 
                        ret = hfi_gen1_set_property(inst, ptype, &fmt, 
sizeof(fmt));
                        if (ret)
                                return ret;
 
                        fmt.buffer_type = HFI_BUFFER_OUTPUT2;
-                       fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 
HFI_COLOR_FORMAT_NV12 : 0;
+                       fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
+                               HFI_COLOR_FORMAT_NV12 : 
HFI_COLOR_FORMAT_NV12_UBWC;
 
                        ret = hfi_gen1_set_property(inst, ptype, &fmt, 
sizeof(fmt));
                } else {
                        fmt.buffer_type = HFI_BUFFER_OUTPUT;
-                       fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 
HFI_COLOR_FORMAT_NV12 : 0;
+                       fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
+                               HFI_COLOR_FORMAT_NV12 : 
HFI_COLOR_FORMAT_NV12_UBWC;
 
                        ret = hfi_gen1_set_property(inst, ptype, &fmt, 
sizeof(fmt));
                }
@@ -806,6 +807,9 @@ static int iris_hfi_gen1_set_format_constraints(struct 
iris_inst *inst, u32 plan
        const u32 ptype = 
HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
        struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
 
+       if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C)
+               return 0;
+
        pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
        pconstraint.num_planes = 2;
        pconstraint.plane_format[0].stride_multiples = 128;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c 
b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 56ced61de924..5ad202d3fcdc 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -443,7 +443,8 @@ static int iris_hfi_gen2_set_colorformat(struct iris_inst 
*inst, u32 plane)
 
        if (inst->domain == DECODER) {
                pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
-               hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? 
HFI_COLOR_FMT_NV12 : 0;
+               hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
+                       HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
        } else {
                pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
                hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? 
HFI_COLOR_FMT_NV12 : 0;
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h 
b/drivers/media/platform/qcom/iris/iris_instance.h
index 5982d7adefea..62fbb30691ff 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -15,12 +15,17 @@
 #define DEFAULT_WIDTH 320
 #define DEFAULT_HEIGHT 240
 
-enum iris_fmt_type {
+enum iris_fmt_type_out {
        IRIS_FMT_H264,
        IRIS_FMT_HEVC,
        IRIS_FMT_VP9,
 };
 
+enum iris_fmt_type_cap {
+       IRIS_FMT_NV12,
+       IRIS_FMT_QC08C,
+};
+
 struct iris_fmt {
        u32 pixfmt;
        u32 type;
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c 
b/drivers/media/platform/qcom/iris/iris_utils.c
index 85c70a62b1fd..e2f1131de431 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -34,7 +34,8 @@ int iris_get_mbpf(struct iris_inst *inst)
 
 bool iris_split_mode_enabled(struct iris_inst *inst)
 {
-       return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12;
+       return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12 ||
+               inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C;
 }
 
 void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c 
b/drivers/media/platform/qcom/iris/iris_vdec.c
index 3926ed513f08..69ffe52590d3 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -67,7 +67,7 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
        kfree(inst->fmt_src);
 }
 
-static const struct iris_fmt iris_vdec_formats[] = {
+static const struct iris_fmt iris_vdec_formats_out[] = {
        [IRIS_FMT_H264] = {
                .pixfmt = V4L2_PIX_FMT_H264,
                .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
@@ -82,12 +82,35 @@ static const struct iris_fmt iris_vdec_formats[] = {
        },
 };
 
+static const struct iris_fmt iris_vdec_formats_cap[] = {
+       [IRIS_FMT_NV12] = {
+               .pixfmt = V4L2_PIX_FMT_NV12,
+               .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+       },
+       [IRIS_FMT_QC08C] = {
+               .pixfmt = V4L2_PIX_FMT_QC08C,
+               .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+       },
+};
+
 static const struct iris_fmt *
 find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
 {
-       unsigned int size = ARRAY_SIZE(iris_vdec_formats);
-       const struct iris_fmt *fmt = iris_vdec_formats;
+       const struct iris_fmt *fmt = NULL;
+       unsigned int size = 0;
        unsigned int i;
+       switch (type) {
+       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+               fmt = iris_vdec_formats_out;
+               size = ARRAY_SIZE(iris_vdec_formats_out);
+               break;
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               fmt = iris_vdec_formats_cap;
+               size = ARRAY_SIZE(iris_vdec_formats_cap);
+               break;
+       default:
+               return NULL;
+       }
 
        for (i = 0; i < size; i++) {
                if (fmt[i].pixfmt == pixfmt)
@@ -103,8 +126,21 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
 static const struct iris_fmt *
 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
 {
-       const struct iris_fmt *fmt = iris_vdec_formats;
-       unsigned int size = ARRAY_SIZE(iris_vdec_formats);
+       const struct iris_fmt *fmt = NULL;
+       unsigned int size = 0;
+
+       switch (type) {
+       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+               fmt = iris_vdec_formats_out;
+               size = ARRAY_SIZE(iris_vdec_formats_out);
+               break;
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               fmt = iris_vdec_formats_cap;
+               size = ARRAY_SIZE(iris_vdec_formats_cap);
+               break;
+       default:
+               return NULL;
+       }
 
        if (index >= size || fmt[index].type != type)
                return NULL;
@@ -126,9 +162,10 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct 
v4l2_fmtdesc *f)
                f->flags = V4L2_FMT_FLAG_COMPRESSED | 
V4L2_FMT_FLAG_DYN_RESOLUTION;
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-               if (f->index)
+               fmt = find_format_by_index(inst, f->index, f->type);
+               if (!fmt)
                        return -EINVAL;
-               f->pixelformat = V4L2_PIX_FMT_NV12;
+               f->pixelformat = fmt->pixfmt;
                break;
        default:
                return -EINVAL;
@@ -157,7 +194,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct 
v4l2_format *f)
                }
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-               if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
+               if (!fmt) {
                        f_inst = inst->fmt_dst;
                        f->fmt.pix_mp.pixelformat = 
f_inst->fmt.pix_mp.pixelformat;
                        f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
@@ -236,10 +273,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct 
v4l2_format *f)
                inst->crop.height = f->fmt.pix_mp.height;
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
+                       return -EINVAL;
+
                fmt = inst->fmt_dst;
                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-               if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12)
-                       return -EINVAL;
                fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
                fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
                fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
@@ -266,7 +304,8 @@ int iris_vdec_validate_format(struct iris_inst *inst, u32 
pixelformat)
 {
        const struct iris_fmt *fmt = NULL;
 
-       if (pixelformat != V4L2_PIX_FMT_NV12) {
+       fmt = find_format(inst, pixelformat, 
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+       if (!fmt) {
                fmt = find_format(inst, pixelformat, 
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
                if (!fmt)
                        return -EINVAL;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to