]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: iris: add VPU33 specific encoding buffer calculation
authorNeil Armstrong <neil.armstrong@linaro.org>
Tue, 2 Sep 2025 08:43:49 +0000 (10:43 +0200)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Wed, 10 Sep 2025 07:02:48 +0000 (09:02 +0200)
The VPU33 found in the SM8650 Platform requires some slighly different
buffer calculation for encoding to allow working with the latest
firwware uploaded on linux-firmware at [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=ece445af91bbee49bf0d8b23c2b99b596ae6eac7

Suggested-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/qcom/iris/iris_buffer.c
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
drivers/media/platform/qcom/iris/iris_platform_common.h
drivers/media/platform/qcom/iris/iris_platform_gen2.c
drivers/media/platform/qcom/iris/iris_platform_sm8250.c
drivers/media/platform/qcom/iris/iris_vpu_buffer.c
drivers/media/platform/qcom/iris/iris_vpu_buffer.h

index 8891a297d384b018b3cc8313ad6416db6317798b..c0900038e7defccf7de3cb60e17c71e36a0e8ead 100644 (file)
@@ -284,7 +284,7 @@ static void iris_fill_internal_buf_info(struct iris_inst *inst,
 {
        struct iris_buffers *buffers = &inst->buffers[buffer_type];
 
-       buffers->size = iris_vpu_buf_size(inst, buffer_type);
+       buffers->size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, buffer_type);
        buffers->min_count = iris_vpu_buf_count(inst, buffer_type);
 }
 
index 29cf392ca2566da286ea3e928ce4a22c2e970cc8..e1788c266bb1080921f17248fd5ee60156b3143d 100644 (file)
@@ -911,7 +911,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane)
 
        if (iris_split_mode_enabled(inst)) {
                bufsz.type = HFI_BUFFER_OUTPUT;
-               bufsz.size = iris_vpu_buf_size(inst, BUF_DPB);
+               bufsz.size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, BUF_DPB);
 
                ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
                if (ret)
index 7fbbea38c78a1ba18e8f1c689b2eacb568bead8f..58d05e0a112eed25faea027a34c719c89d6c3897 100644 (file)
@@ -7,6 +7,7 @@
 #define __IRIS_PLATFORM_COMMON_H__
 
 #include <linux/bits.h>
+#include "iris_buffer.h"
 
 struct iris_core;
 struct iris_inst;
@@ -193,6 +194,7 @@ struct iris_platform_data {
        void (*init_hfi_command_ops)(struct iris_core *core);
        void (*init_hfi_response_ops)(struct iris_core *core);
        struct iris_inst *(*get_instance)(void);
+       u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type);
        const struct vpu_ops *vpu_ops;
        void (*set_preset_registers)(struct iris_core *core);
        const struct icc_info *icc_tbl;
index d8c167c6f62c4b97fa7f5da9ac3c79b6c484a9f1..36d69cc73986b74534a2912524c8553970fd862e 100644 (file)
@@ -9,6 +9,7 @@
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_defines.h"
 #include "iris_platform_common.h"
+#include "iris_vpu_buffer.h"
 #include "iris_vpu_common.h"
 
 #include "iris_platform_qcs8300.h"
@@ -740,6 +741,7 @@ struct iris_platform_data sm8550_data = {
        .get_instance = iris_hfi_gen2_get_instance,
        .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
        .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+       .get_vpu_buffer_size = iris_vpu_buf_size,
        .vpu_ops = &iris_vpu3_ops,
        .set_preset_registers = iris_set_sm8550_preset_registers,
        .icc_tbl = sm8550_icc_table,
@@ -829,6 +831,7 @@ struct iris_platform_data sm8650_data = {
        .get_instance = iris_hfi_gen2_get_instance,
        .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
        .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+       .get_vpu_buffer_size = iris_vpu33_buf_size,
        .vpu_ops = &iris_vpu33_ops,
        .set_preset_registers = iris_set_sm8550_preset_registers,
        .icc_tbl = sm8550_icc_table,
@@ -999,6 +1002,7 @@ struct iris_platform_data qcs8300_data = {
        .get_instance = iris_hfi_gen2_get_instance,
        .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
        .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+       .get_vpu_buffer_size = iris_vpu_buf_size,
        .vpu_ops = &iris_vpu3_ops,
        .set_preset_registers = iris_set_sm8550_preset_registers,
        .icc_tbl = sm8550_icc_table,
index 978d0130d43b5f6febb65430a9bbe3932e8f24df..16486284f8acccf6a95a27f6003e885226e28f4d 100644 (file)
@@ -9,6 +9,7 @@
 #include "iris_resources.h"
 #include "iris_hfi_gen1.h"
 #include "iris_hfi_gen1_defines.h"
+#include "iris_vpu_buffer.h"
 #include "iris_vpu_common.h"
 
 #define BITRATE_MIN            32000
@@ -317,6 +318,7 @@ struct iris_platform_data sm8250_data = {
        .get_instance = iris_hfi_gen1_get_instance,
        .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init,
        .init_hfi_response_ops = iris_hfi_gen1_response_ops_init,
+       .get_vpu_buffer_size = iris_vpu_buf_size,
        .vpu_ops = &iris_vpu2_ops,
        .set_preset_registers = iris_set_sm8250_preset_registers,
        .icc_tbl = sm8250_icc_table,
index 570b6415dff99fddf8fb35a1d01598a7db79a2ae..4463be05ce165adef6b152eb0c155d2e6a7b3c36 100644 (file)
@@ -844,6 +844,27 @@ u32 size_vpss_line_buf(u32 num_vpp_pipes_enc, u32 frame_height_coded,
                      (((((max_t(u32, (frame_width_coded),
                                 (frame_height_coded)) + 3) >> 2) << 5) + 256) * 16)), 256);
 }
+static inline
+u32 size_vpss_line_buf_vpu33(u32 num_vpp_pipes_enc, u32 frame_height_coded,
+                            u32 frame_width_coded)
+{
+       u32 vpss_4tap_top, vpss_4tap_left, vpss_div2_top;
+       u32 vpss_div2_left, vpss_top_lb, vpss_left_lb;
+       u32 size_left, size_top;
+       u32 max_width_height;
+
+       max_width_height = max_t(u32, frame_width_coded, frame_height_coded);
+       vpss_4tap_top = ((((max_width_height * 2) + 3) >> 2) << 4) + 256;
+       vpss_4tap_left = (((8192 + 3) >> 2) << 5) + 64;
+       vpss_div2_top = (((max_width_height + 3) >> 2) << 4) + 256;
+       vpss_div2_left = ((((max_width_height * 2) + 3) >> 2) << 5) + 64;
+       vpss_top_lb = (frame_width_coded + 1) << 3;
+       vpss_left_lb = (frame_height_coded << 3) * num_vpp_pipes_enc;
+       size_left = (vpss_4tap_left + vpss_div2_left) * 2 * num_vpp_pipes_enc;
+       size_top = (vpss_4tap_top + vpss_div2_top) * 2;
+
+       return ALIGN(size_left + size_top + vpss_top_lb + vpss_left_lb, DMA_ALIGNMENT);
+}
 
 static inline
 u32 size_top_line_buf_first_stg_sao(u32 frame_width_coded)
@@ -954,8 +975,8 @@ static u32 iris_vpu_enc_non_comv_size(struct iris_inst *inst)
 }
 
 static inline
-u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
-                       u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+u32 hfi_buffer_line_enc_base(u32 frame_width, u32 frame_height, bool is_ten_bit,
+                            u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
 {
        u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
        u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
@@ -995,10 +1016,38 @@ u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
                line_buff_recon_pix_size +
                size_left_linebuff_ctrl_fe(frame_height_coded, num_vpp_pipes_enc) +
                size_line_buf_sde(frame_width_coded) +
-               size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded, frame_width_coded) +
                size_top_line_buf_first_stg_sao(frame_width_coded);
 }
 
+static inline
+u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
+                       u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+       u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+       u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+       u32 frame_height_coded = height_in_lcus * (lcu_size);
+       u32 frame_width_coded = width_in_lcus * (lcu_size);
+
+       return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit,
+                                       num_vpp_pipes_enc, lcu_size, standard) +
+               size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded, frame_width_coded);
+}
+
+static inline
+u32 hfi_buffer_line_enc_vpu33(u32 frame_width, u32 frame_height, bool is_ten_bit,
+                             u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+       u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+       u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+       u32 frame_height_coded = height_in_lcus * (lcu_size);
+       u32 frame_width_coded = width_in_lcus * (lcu_size);
+
+       return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit,
+                                       num_vpp_pipes_enc, lcu_size, standard) +
+               size_vpss_line_buf_vpu33(num_vpp_pipes_enc, frame_height_coded,
+                                        frame_width_coded);
+}
+
 static u32 iris_vpu_enc_line_size(struct iris_inst *inst)
 {
        u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
@@ -1017,6 +1066,24 @@ static u32 iris_vpu_enc_line_size(struct iris_inst *inst)
                                   lcu_size, HFI_CODEC_ENCODE_AVC);
 }
 
+static u32 iris_vpu33_enc_line_size(struct iris_inst *inst)
+{
+       u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+       struct v4l2_format *f = inst->fmt_dst;
+       u32 height = f->fmt.pix_mp.height;
+       u32 width = f->fmt.pix_mp.width;
+       u32 lcu_size = 16;
+
+       if (inst->codec == V4L2_PIX_FMT_HEVC) {
+               lcu_size = 32;
+               return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes,
+                                                lcu_size, HFI_CODEC_ENCODE_HEVC);
+       }
+
+       return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes,
+                                        lcu_size, HFI_CODEC_ENCODE_AVC);
+}
+
 static inline
 u32 hfi_buffer_dpb_enc(u32 frame_width, u32 frame_height, bool is_ten_bit)
 {
@@ -1364,7 +1431,7 @@ struct iris_vpu_buf_type_handle {
        u32 (*handle)(struct iris_inst *inst);
 };
 
-int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
 {
        const struct iris_vpu_buf_type_handle *buf_type_handle_arr = NULL;
        u32 size = 0, buf_type_handle_size = 0, i;
@@ -1408,6 +1475,34 @@ int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
        return size;
 }
 
+u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+{
+       u32 size = 0, i;
+
+       static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = {
+               {BUF_BIN,         iris_vpu_enc_bin_size         },
+               {BUF_COMV,        iris_vpu_enc_comv_size        },
+               {BUF_NON_COMV,    iris_vpu_enc_non_comv_size    },
+               {BUF_LINE,        iris_vpu33_enc_line_size      },
+               {BUF_ARP,         iris_vpu_enc_arp_size         },
+               {BUF_VPSS,        iris_vpu_enc_vpss_size        },
+               {BUF_SCRATCH_1,   iris_vpu_enc_scratch1_size    },
+               {BUF_SCRATCH_2,   iris_vpu_enc_scratch2_size    },
+       };
+
+       if (inst->domain == DECODER)
+               return iris_vpu_buf_size(inst, buffer_type);
+
+       for (i = 0; i < ARRAY_SIZE(enc_internal_buf_type_handle); i++) {
+               if (enc_internal_buf_type_handle[i].type == buffer_type) {
+                       size = enc_internal_buf_type_handle[i].handle(inst);
+                       break;
+               }
+       }
+
+       return size;
+}
+
 static u32 internal_buffer_count(struct iris_inst *inst,
                                 enum iris_buffer_type buffer_type)
 {
index 94668c5b3d15fb6e10d0b5ed6ed704cadb5a6534..04f0b7400a1e4e1d274d690a2761b9e57778e8b7 100644 (file)
@@ -146,7 +146,8 @@ static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
        return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128;
 }
 
-int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
+u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
+u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type);
 
 #endif