Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: iris: add VPU33 specific encoding buffer calculation

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>

authored by

Neil Armstrong and committed by
Hans Verkuil
a5925a2c 75db90ae

+111 -7
+1 -1
drivers/media/platform/qcom/iris/iris_buffer.c
··· 284 284 { 285 285 struct iris_buffers *buffers = &inst->buffers[buffer_type]; 286 286 287 - buffers->size = iris_vpu_buf_size(inst, buffer_type); 287 + buffers->size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, buffer_type); 288 288 buffers->min_count = iris_vpu_buf_count(inst, buffer_type); 289 289 } 290 290
+1 -1
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
··· 911 911 912 912 if (iris_split_mode_enabled(inst)) { 913 913 bufsz.type = HFI_BUFFER_OUTPUT; 914 - bufsz.size = iris_vpu_buf_size(inst, BUF_DPB); 914 + bufsz.size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, BUF_DPB); 915 915 916 916 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 917 917 if (ret)
+2
drivers/media/platform/qcom/iris/iris_platform_common.h
··· 7 7 #define __IRIS_PLATFORM_COMMON_H__ 8 8 9 9 #include <linux/bits.h> 10 + #include "iris_buffer.h" 10 11 11 12 struct iris_core; 12 13 struct iris_inst; ··· 194 193 void (*init_hfi_command_ops)(struct iris_core *core); 195 194 void (*init_hfi_response_ops)(struct iris_core *core); 196 195 struct iris_inst *(*get_instance)(void); 196 + u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); 197 197 const struct vpu_ops *vpu_ops; 198 198 void (*set_preset_registers)(struct iris_core *core); 199 199 const struct icc_info *icc_tbl;
+4
drivers/media/platform/qcom/iris/iris_platform_gen2.c
··· 9 9 #include "iris_hfi_gen2.h" 10 10 #include "iris_hfi_gen2_defines.h" 11 11 #include "iris_platform_common.h" 12 + #include "iris_vpu_buffer.h" 12 13 #include "iris_vpu_common.h" 13 14 14 15 #include "iris_platform_qcs8300.h" ··· 741 740 .get_instance = iris_hfi_gen2_get_instance, 742 741 .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, 743 742 .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, 743 + .get_vpu_buffer_size = iris_vpu_buf_size, 744 744 .vpu_ops = &iris_vpu3_ops, 745 745 .set_preset_registers = iris_set_sm8550_preset_registers, 746 746 .icc_tbl = sm8550_icc_table, ··· 831 829 .get_instance = iris_hfi_gen2_get_instance, 832 830 .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, 833 831 .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, 832 + .get_vpu_buffer_size = iris_vpu33_buf_size, 834 833 .vpu_ops = &iris_vpu33_ops, 835 834 .set_preset_registers = iris_set_sm8550_preset_registers, 836 835 .icc_tbl = sm8550_icc_table, ··· 1002 999 .get_instance = iris_hfi_gen2_get_instance, 1003 1000 .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, 1004 1001 .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, 1002 + .get_vpu_buffer_size = iris_vpu_buf_size, 1005 1003 .vpu_ops = &iris_vpu3_ops, 1006 1004 .set_preset_registers = iris_set_sm8550_preset_registers, 1007 1005 .icc_tbl = sm8550_icc_table,
+2
drivers/media/platform/qcom/iris/iris_platform_sm8250.c
··· 9 9 #include "iris_resources.h" 10 10 #include "iris_hfi_gen1.h" 11 11 #include "iris_hfi_gen1_defines.h" 12 + #include "iris_vpu_buffer.h" 12 13 #include "iris_vpu_common.h" 13 14 14 15 #define BITRATE_MIN 32000 ··· 318 317 .get_instance = iris_hfi_gen1_get_instance, 319 318 .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, 320 319 .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, 320 + .get_vpu_buffer_size = iris_vpu_buf_size, 321 321 .vpu_ops = &iris_vpu2_ops, 322 322 .set_preset_registers = iris_set_sm8250_preset_registers, 323 323 .icc_tbl = sm8250_icc_table,
+99 -4
drivers/media/platform/qcom/iris/iris_vpu_buffer.c
··· 844 844 (((((max_t(u32, (frame_width_coded), 845 845 (frame_height_coded)) + 3) >> 2) << 5) + 256) * 16)), 256); 846 846 } 847 + static inline 848 + u32 size_vpss_line_buf_vpu33(u32 num_vpp_pipes_enc, u32 frame_height_coded, 849 + u32 frame_width_coded) 850 + { 851 + u32 vpss_4tap_top, vpss_4tap_left, vpss_div2_top; 852 + u32 vpss_div2_left, vpss_top_lb, vpss_left_lb; 853 + u32 size_left, size_top; 854 + u32 max_width_height; 855 + 856 + max_width_height = max_t(u32, frame_width_coded, frame_height_coded); 857 + vpss_4tap_top = ((((max_width_height * 2) + 3) >> 2) << 4) + 256; 858 + vpss_4tap_left = (((8192 + 3) >> 2) << 5) + 64; 859 + vpss_div2_top = (((max_width_height + 3) >> 2) << 4) + 256; 860 + vpss_div2_left = ((((max_width_height * 2) + 3) >> 2) << 5) + 64; 861 + vpss_top_lb = (frame_width_coded + 1) << 3; 862 + vpss_left_lb = (frame_height_coded << 3) * num_vpp_pipes_enc; 863 + size_left = (vpss_4tap_left + vpss_div2_left) * 2 * num_vpp_pipes_enc; 864 + size_top = (vpss_4tap_top + vpss_div2_top) * 2; 865 + 866 + return ALIGN(size_left + size_top + vpss_top_lb + vpss_left_lb, DMA_ALIGNMENT); 867 + } 847 868 848 869 static inline 849 870 u32 size_top_line_buf_first_stg_sao(u32 frame_width_coded) ··· 975 954 } 976 955 977 956 static inline 978 - u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit, 979 - u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard) 957 + u32 hfi_buffer_line_enc_base(u32 frame_width, u32 frame_height, bool is_ten_bit, 958 + u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard) 980 959 { 981 960 u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size); 982 961 u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size); ··· 1016 995 line_buff_recon_pix_size + 1017 996 size_left_linebuff_ctrl_fe(frame_height_coded, num_vpp_pipes_enc) + 1018 997 size_line_buf_sde(frame_width_coded) + 1019 - size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded, frame_width_coded) + 1020 998 size_top_line_buf_first_stg_sao(frame_width_coded); 999 + } 1000 + 1001 + static inline 1002 + u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit, 1003 + u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard) 1004 + { 1005 + u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size); 1006 + u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size); 1007 + u32 frame_height_coded = height_in_lcus * (lcu_size); 1008 + u32 frame_width_coded = width_in_lcus * (lcu_size); 1009 + 1010 + return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit, 1011 + num_vpp_pipes_enc, lcu_size, standard) + 1012 + size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded, frame_width_coded); 1013 + } 1014 + 1015 + static inline 1016 + u32 hfi_buffer_line_enc_vpu33(u32 frame_width, u32 frame_height, bool is_ten_bit, 1017 + u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard) 1018 + { 1019 + u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size); 1020 + u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size); 1021 + u32 frame_height_coded = height_in_lcus * (lcu_size); 1022 + u32 frame_width_coded = width_in_lcus * (lcu_size); 1023 + 1024 + return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit, 1025 + num_vpp_pipes_enc, lcu_size, standard) + 1026 + size_vpss_line_buf_vpu33(num_vpp_pipes_enc, frame_height_coded, 1027 + frame_width_coded); 1021 1028 } 1022 1029 1023 1030 static u32 iris_vpu_enc_line_size(struct iris_inst *inst) ··· 1064 1015 1065 1016 return hfi_buffer_line_enc(width, height, 0, num_vpp_pipes, 1066 1017 lcu_size, HFI_CODEC_ENCODE_AVC); 1018 + } 1019 + 1020 + static u32 iris_vpu33_enc_line_size(struct iris_inst *inst) 1021 + { 1022 + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; 1023 + struct v4l2_format *f = inst->fmt_dst; 1024 + u32 height = f->fmt.pix_mp.height; 1025 + u32 width = f->fmt.pix_mp.width; 1026 + u32 lcu_size = 16; 1027 + 1028 + if (inst->codec == V4L2_PIX_FMT_HEVC) { 1029 + lcu_size = 32; 1030 + return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes, 1031 + lcu_size, HFI_CODEC_ENCODE_HEVC); 1032 + } 1033 + 1034 + return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes, 1035 + lcu_size, HFI_CODEC_ENCODE_AVC); 1067 1036 } 1068 1037 1069 1038 static inline ··· 1431 1364 u32 (*handle)(struct iris_inst *inst); 1432 1365 }; 1433 1366 1434 - int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) 1367 + u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) 1435 1368 { 1436 1369 const struct iris_vpu_buf_type_handle *buf_type_handle_arr = NULL; 1437 1370 u32 size = 0, buf_type_handle_size = 0, i; ··· 1468 1401 for (i = 0; i < buf_type_handle_size; i++) { 1469 1402 if (buf_type_handle_arr[i].type == buffer_type) { 1470 1403 size = buf_type_handle_arr[i].handle(inst); 1404 + break; 1405 + } 1406 + } 1407 + 1408 + return size; 1409 + } 1410 + 1411 + u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) 1412 + { 1413 + u32 size = 0, i; 1414 + 1415 + static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = { 1416 + {BUF_BIN, iris_vpu_enc_bin_size }, 1417 + {BUF_COMV, iris_vpu_enc_comv_size }, 1418 + {BUF_NON_COMV, iris_vpu_enc_non_comv_size }, 1419 + {BUF_LINE, iris_vpu33_enc_line_size }, 1420 + {BUF_ARP, iris_vpu_enc_arp_size }, 1421 + {BUF_VPSS, iris_vpu_enc_vpss_size }, 1422 + {BUF_SCRATCH_1, iris_vpu_enc_scratch1_size }, 1423 + {BUF_SCRATCH_2, iris_vpu_enc_scratch2_size }, 1424 + }; 1425 + 1426 + if (inst->domain == DECODER) 1427 + return iris_vpu_buf_size(inst, buffer_type); 1428 + 1429 + for (i = 0; i < ARRAY_SIZE(enc_internal_buf_type_handle); i++) { 1430 + if (enc_internal_buf_type_handle[i].type == buffer_type) { 1431 + size = enc_internal_buf_type_handle[i].handle(inst); 1471 1432 break; 1472 1433 } 1473 1434 }
+2 -1
drivers/media/platform/qcom/iris/iris_vpu_buffer.h
··· 146 146 return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128; 147 147 } 148 148 149 - int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); 149 + u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); 150 + u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); 150 151 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); 151 152 152 153 #endif