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

media: iris: implement set properties to firmware during streamon

During the stream on operation, set some mandatory properties on the
firmware to start a session. Set all v4l2 properties, which are set by
the client, on to firmware, which is prepared with the dependency graph.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS 13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>

authored by

Vedang Nagar and committed by
Hans Verkuil
3a19d7b9 11712ce7

+1429
+121
drivers/media/platform/qcom/iris/iris_buffer.c
··· 72 72 return ALIGN(y_plane + uv_plane, PIXELS_4K); 73 73 } 74 74 75 + /* 76 + * QC08C: 77 + * Compressed Macro-tile format for NV12. 78 + * Contains 4 planes in the following order - 79 + * (A) Y_Meta_Plane 80 + * (B) Y_UBWC_Plane 81 + * (C) UV_Meta_Plane 82 + * (D) UV_UBWC_Plane 83 + * 84 + * Y_Meta_Plane consists of meta information to decode compressed 85 + * tile data in Y_UBWC_Plane. 86 + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. 87 + * UBWC decoder block will use the Y_Meta_Plane data together with 88 + * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples. 89 + * 90 + * UV_Meta_Plane consists of meta information to decode compressed 91 + * tile data in UV_UBWC_Plane. 92 + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. 93 + * UBWC decoder block will use UV_Meta_Plane data together with 94 + * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2 95 + * subsampled color difference samples. 96 + * 97 + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable 98 + * and randomly accessible. There is no dependency between tiles. 99 + * 100 + * <----- y_meta_stride ----> (aligned to 64) 101 + * <-------- Width ------> 102 + * M M M M M M M M M M M M . . ^ ^ 103 + * M M M M M M M M M M M M . . | | 104 + * M M M M M M M M M M M M . . Height | 105 + * M M M M M M M M M M M M . . | y_meta_scanlines (aligned to 16) 106 + * M M M M M M M M M M M M . . | | 107 + * M M M M M M M M M M M M . . | | 108 + * M M M M M M M M M M M M . . | | 109 + * M M M M M M M M M M M M . . V | 110 + * . . . . . . . . . . . . . . | 111 + * . . . . . . . . . . . . . . | 112 + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 113 + * . . . . . . . . . . . . . . V 114 + * <--Compressed tile y_stride---> (aligned to 128) 115 + * <------- Width -------> 116 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ 117 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 118 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | 119 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile y_scanlines (aligned to 32) 120 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 121 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 122 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 123 + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | 124 + * . . . . . . . . . . . . . . . . | 125 + * . . . . . . . . . . . . . . . . | 126 + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 127 + * . . . . . . . . . . . . . . . . V 128 + * <----- uv_meta_stride ----> (aligned to 64) 129 + * M M M M M M M M M M M M . . ^ 130 + * M M M M M M M M M M M M . . | 131 + * M M M M M M M M M M M M . . | 132 + * M M M M M M M M M M M M . . uv_meta_scanlines (aligned to 16) 133 + * . . . . . . . . . . . . . . | 134 + * . . . . . . . . . . . . . . V 135 + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 136 + * <--Compressed tile uv_stride---> (aligned to 128) 137 + * U* V* U* V* U* V* U* V* . . . . ^ 138 + * U* V* U* V* U* V* U* V* . . . . | 139 + * U* V* U* V* U* V* U* V* . . . . | 140 + * U* V* U* V* U* V* U* V* . . . . uv_scanlines (aligned to 32) 141 + * . . . . . . . . . . . . . . . . | 142 + * . . . . . . . . . . . . . . . . V 143 + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 144 + * 145 + * y_stride: width aligned to 128 146 + * uv_stride: width aligned to 128 147 + * y_scanlines: height aligned to 32 148 + * uv_scanlines: height aligned to 32 149 + * y_plane: buffer size aligned to 4096 150 + * uv_plane: buffer size aligned to 4096 151 + * y_meta_stride: width aligned to 64 152 + * y_meta_scanlines: height aligned to 16 153 + * y_meta_plane: buffer size aligned to 4096 154 + * uv_meta_stride: width aligned to 64 155 + * uv_meta_scanlines: height aligned to 16 156 + * uv_meta_plane: buffer size aligned to 4096 157 + * 158 + * Total size = align( y_plane + uv_plane + 159 + * y_meta_plane + uv_meta_plane, 4096) 160 + * 161 + * Note: All the alignments are hardware requirements. 162 + */ 163 + static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst) 164 + { 165 + u32 y_plane, uv_plane, y_stride, uv_stride; 166 + struct v4l2_format *f = inst->fmt_dst; 167 + u32 uv_meta_stride, uv_meta_plane; 168 + u32 y_meta_stride, y_meta_plane; 169 + 170 + y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1), 171 + META_STRIDE_ALIGNED); 172 + y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height, 173 + META_SCANLINE_ALIGNED >> 1), 174 + META_SCANLINE_ALIGNED); 175 + y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K); 176 + 177 + y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); 178 + y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN), PIXELS_4K); 179 + 180 + uv_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width / 2, META_STRIDE_ALIGNED >> 2), 181 + META_STRIDE_ALIGNED); 182 + uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height / 2, 183 + META_SCANLINE_ALIGNED >> 1), 184 + META_SCANLINE_ALIGNED); 185 + uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K); 186 + 187 + uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); 188 + uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C), 189 + PIXELS_4K); 190 + 191 + return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K); 192 + } 193 + 75 194 static u32 iris_bitstream_buffer_size(struct iris_inst *inst) 76 195 { 77 196 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; ··· 221 102 return iris_bitstream_buffer_size(inst); 222 103 case BUF_OUTPUT: 223 104 return iris_yuv_buffer_size_nv12(inst); 105 + case BUF_DPB: 106 + return iris_yuv_buffer_size_qc08c(inst); 224 107 default: 225 108 return 0; 226 109 }
+94
drivers/media/platform/qcom/iris/iris_ctrls.c
··· 3 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 4 */ 5 5 6 + #include <linux/types.h> 6 7 #include <media/v4l2-mem2mem.h> 8 + 7 9 #include "iris_ctrls.h" 8 10 #include "iris_instance.h" 9 11 ··· 164 162 core->inst_fw_caps[cap_id].flags = caps[i].flags; 165 163 core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id; 166 164 } 165 + } 166 + 167 + static u32 iris_get_port_info(struct iris_inst *inst, 168 + enum platform_inst_fw_cap_type cap_id) 169 + { 170 + if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT) 171 + return HFI_PORT_BITSTREAM; 172 + else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT) 173 + return HFI_PORT_RAW; 174 + 175 + return HFI_PORT_NONE; 176 + } 177 + 178 + int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 179 + { 180 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 181 + u32 hfi_value = inst->fw_caps[cap_id].value; 182 + u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 183 + 184 + return hfi_ops->session_set_property(inst, hfi_id, 185 + HFI_HOST_FLAGS_NONE, 186 + iris_get_port_info(inst, cap_id), 187 + HFI_PAYLOAD_U32_ENUM, 188 + &hfi_value, sizeof(u32)); 189 + } 190 + 191 + int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 192 + { 193 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 194 + u32 hfi_value = inst->fw_caps[cap_id].value; 195 + u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 196 + 197 + return hfi_ops->session_set_property(inst, hfi_id, 198 + HFI_HOST_FLAGS_NONE, 199 + iris_get_port_info(inst, cap_id), 200 + HFI_PAYLOAD_U32, 201 + &hfi_value, sizeof(u32)); 202 + } 203 + 204 + int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 205 + { 206 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 207 + struct v4l2_format *inp_f = inst->fmt_src; 208 + u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 209 + u32 height = inp_f->fmt.pix_mp.height; 210 + u32 width = inp_f->fmt.pix_mp.width; 211 + u32 work_mode = STAGE_2; 212 + 213 + if (iris_res_is_less_than(width, height, 1280, 720)) 214 + work_mode = STAGE_1; 215 + 216 + return hfi_ops->session_set_property(inst, hfi_id, 217 + HFI_HOST_FLAGS_NONE, 218 + iris_get_port_info(inst, cap_id), 219 + HFI_PAYLOAD_U32, 220 + &work_mode, sizeof(u32)); 221 + } 222 + 223 + int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 224 + { 225 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 226 + u32 work_route = inst->fw_caps[PIPE].value; 227 + u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 228 + 229 + return hfi_ops->session_set_property(inst, hfi_id, 230 + HFI_HOST_FLAGS_NONE, 231 + iris_get_port_info(inst, cap_id), 232 + HFI_PAYLOAD_U32, 233 + &work_route, sizeof(u32)); 234 + } 235 + 236 + int iris_set_properties(struct iris_inst *inst, u32 plane) 237 + { 238 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 239 + struct platform_inst_fw_cap *cap; 240 + int ret; 241 + u32 i; 242 + 243 + ret = hfi_ops->session_set_config_params(inst, plane); 244 + if (ret) 245 + return ret; 246 + 247 + for (i = 1; i < INST_FW_CAP_MAX; i++) { 248 + cap = &inst->fw_caps[i]; 249 + if (!iris_valid_cap_id(cap->cap_id)) 250 + continue; 251 + 252 + if (cap->cap_id && cap->set) 253 + cap->set(inst, i); 254 + } 255 + 256 + return 0; 167 257 }
+5
drivers/media/platform/qcom/iris/iris_ctrls.h
··· 13 13 14 14 int iris_ctrls_init(struct iris_inst *inst); 15 15 void iris_session_init_caps(struct iris_core *core); 16 + int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); 17 + int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); 18 + int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); 19 + int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); 20 + int iris_set_properties(struct iris_inst *inst, u32 plane); 16 21 17 22 #endif
+76
drivers/media/platform/qcom/iris/iris_hfi_common.h
··· 43 43 HFI_HOST_FLAGS_GET_PROPERTY = 0x00000008, 44 44 }; 45 45 46 + enum hfi_color_primaries { 47 + HFI_PRIMARIES_RESERVED = 0, 48 + HFI_PRIMARIES_BT709 = 1, 49 + HFI_PRIMARIES_UNSPECIFIED = 2, 50 + HFI_PRIMARIES_BT470_SYSTEM_M = 4, 51 + HFI_PRIMARIES_BT470_SYSTEM_BG = 5, 52 + HFI_PRIMARIES_BT601_525 = 6, 53 + HFI_PRIMARIES_SMPTE_ST240M = 7, 54 + HFI_PRIMARIES_GENERIC_FILM = 8, 55 + HFI_PRIMARIES_BT2020 = 9, 56 + HFI_PRIMARIES_SMPTE_ST428_1 = 10, 57 + HFI_PRIMARIES_SMPTE_RP431_2 = 11, 58 + HFI_PRIMARIES_SMPTE_EG431_1 = 12, 59 + HFI_PRIMARIES_SMPTE_EBU_TECH = 22, 60 + }; 61 + 62 + enum hfi_transfer_characteristics { 63 + HFI_TRANSFER_RESERVED = 0, 64 + HFI_TRANSFER_BT709 = 1, 65 + HFI_TRANSFER_UNSPECIFIED = 2, 66 + HFI_TRANSFER_BT470_SYSTEM_M = 4, 67 + HFI_TRANSFER_BT470_SYSTEM_BG = 5, 68 + HFI_TRANSFER_BT601_525_OR_625 = 6, 69 + HFI_TRANSFER_SMPTE_ST240M = 7, 70 + HFI_TRANSFER_LINEAR = 8, 71 + HFI_TRANSFER_LOG_100_1 = 9, 72 + HFI_TRANSFER_LOG_SQRT = 10, 73 + HFI_TRANSFER_XVYCC = 11, 74 + HFI_TRANSFER_BT1361_0 = 12, 75 + HFI_TRANSFER_SRGB_SYCC = 13, 76 + HFI_TRANSFER_BT2020_14 = 14, 77 + HFI_TRANSFER_BT2020_15 = 15, 78 + HFI_TRANSFER_SMPTE_ST2084_PQ = 16, 79 + HFI_TRANSFER_SMPTE_ST428_1 = 17, 80 + HFI_TRANSFER_BT2100_2_HLG = 18, 81 + }; 82 + 83 + enum hfi_matrix_coefficients { 84 + HFI_MATRIX_COEFF_SRGB_SMPTE_ST428_1 = 0, 85 + HFI_MATRIX_COEFF_BT709 = 1, 86 + HFI_MATRIX_COEFF_UNSPECIFIED = 2, 87 + HFI_MATRIX_COEFF_RESERVED = 3, 88 + HFI_MATRIX_COEFF_FCC_TITLE_47 = 4, 89 + HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625 = 5, 90 + HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625 = 6, 91 + HFI_MATRIX_COEFF_SMPTE_ST240 = 7, 92 + HFI_MATRIX_COEFF_YCGCO = 8, 93 + HFI_MATRIX_COEFF_BT2020_NON_CONSTANT = 9, 94 + HFI_MATRIX_COEFF_BT2020_CONSTANT = 10, 95 + HFI_MATRIX_COEFF_SMPTE_ST2085 = 11, 96 + HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_NON_CONSTANT = 12, 97 + HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_CONSTANT = 13, 98 + HFI_MATRIX_COEFF_BT2100 = 14, 99 + }; 100 + 101 + struct iris_hfi_prop_type_handle { 102 + u32 type; 103 + int (*handle)(struct iris_inst *inst); 104 + }; 105 + 46 106 struct iris_hfi_command_ops { 47 107 int (*sys_init)(struct iris_core *core); 48 108 int (*sys_image_version)(struct iris_core *core); 49 109 int (*sys_interframe_powercollapse)(struct iris_core *core); 50 110 int (*sys_pc_prep)(struct iris_core *core); 111 + int (*session_set_config_params)(struct iris_inst *inst, u32 plane); 112 + int (*session_set_property)(struct iris_inst *inst, 113 + u32 packet_type, u32 flag, u32 plane, u32 payload_type, 114 + void *payload, u32 payload_size); 51 115 int (*session_open)(struct iris_inst *inst); 52 116 int (*session_start)(struct iris_inst *inst, u32 plane); 53 117 int (*session_stop)(struct iris_inst *inst, u32 plane); ··· 120 56 121 57 struct iris_hfi_response_ops { 122 58 void (*hfi_response_handler)(struct iris_core *core); 59 + }; 60 + 61 + struct hfi_subscription_params { 62 + u32 bitstream_resolution; 63 + u32 crop_offsets[2]; 64 + u32 bit_depth; 65 + u32 coded_frames; 66 + u32 fw_min_count; 67 + u32 pic_order_cnt; 68 + u32 color_info; 69 + u32 profile; 70 + u32 level; 123 71 }; 124 72 125 73 int iris_hfi_core_init(struct iris_core *core);
+411
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
··· 6 6 #include "iris_hfi_gen1.h" 7 7 #include "iris_hfi_gen1_defines.h" 8 8 #include "iris_instance.h" 9 + #include "iris_vpu_buffer.h" 9 10 10 11 static int iris_hfi_gen1_sys_init(struct iris_core *core) 11 12 { ··· 183 182 return ret; 184 183 } 185 184 185 + static int 186 + iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, 187 + struct iris_inst *inst, u32 ptype, void *pdata) 188 + { 189 + void *prop_data = &packet->data[1]; 190 + 191 + packet->shdr.hdr.size = sizeof(*packet); 192 + packet->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY; 193 + packet->shdr.session_id = inst->session_id; 194 + packet->num_properties = 1; 195 + packet->data[0] = ptype; 196 + 197 + switch (ptype) { 198 + case HFI_PROPERTY_PARAM_FRAME_SIZE: { 199 + struct hfi_framesize *in = pdata, *fsize = prop_data; 200 + 201 + fsize->buffer_type = in->buffer_type; 202 + fsize->height = in->height; 203 + fsize->width = in->width; 204 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*fsize); 205 + break; 206 + } 207 + case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: { 208 + struct hfi_videocores_usage_type *in = pdata, *cu = prop_data; 209 + 210 + cu->video_core_enable_mask = in->video_core_enable_mask; 211 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*cu); 212 + break; 213 + } 214 + case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: { 215 + struct hfi_uncompressed_format_select *in = pdata; 216 + struct hfi_uncompressed_format_select *hfi = prop_data; 217 + 218 + hfi->buffer_type = in->buffer_type; 219 + hfi->format = in->format; 220 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*hfi); 221 + break; 222 + } 223 + case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: { 224 + struct hfi_uncompressed_plane_actual_constraints_info *info = prop_data; 225 + 226 + info->buffer_type = HFI_BUFFER_OUTPUT2; 227 + info->num_planes = 2; 228 + info->plane_format[0].stride_multiples = 128; 229 + info->plane_format[0].max_stride = 8192; 230 + info->plane_format[0].min_plane_buffer_height_multiple = 32; 231 + info->plane_format[0].buffer_alignment = 256; 232 + if (info->num_planes > 1) { 233 + info->plane_format[1].stride_multiples = 128; 234 + info->plane_format[1].max_stride = 8192; 235 + info->plane_format[1].min_plane_buffer_height_multiple = 16; 236 + info->plane_format[1].buffer_alignment = 256; 237 + } 238 + 239 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*info); 240 + break; 241 + } 242 + case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: { 243 + struct hfi_buffer_count_actual *in = pdata; 244 + struct hfi_buffer_count_actual *count = prop_data; 245 + 246 + count->type = in->type; 247 + count->count_actual = in->count_actual; 248 + count->count_min_host = in->count_min_host; 249 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*count); 250 + break; 251 + } 252 + case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: { 253 + struct hfi_multi_stream *in = pdata; 254 + struct hfi_multi_stream *multi = prop_data; 255 + 256 + multi->buffer_type = in->buffer_type; 257 + multi->enable = in->enable; 258 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*multi); 259 + break; 260 + } 261 + case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: { 262 + struct hfi_buffer_size_actual *in = pdata, *sz = prop_data; 263 + 264 + sz->size = in->size; 265 + sz->type = in->type; 266 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*sz); 267 + break; 268 + } 269 + case HFI_PROPERTY_PARAM_WORK_ROUTE: { 270 + struct hfi_video_work_route *wr = prop_data; 271 + u32 *in = pdata; 272 + 273 + wr->video_work_route = *in; 274 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*wr); 275 + break; 276 + } 277 + case HFI_PROPERTY_PARAM_WORK_MODE: { 278 + struct hfi_video_work_mode *wm = prop_data; 279 + u32 *in = pdata; 280 + 281 + wm->video_work_mode = *in; 282 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm); 283 + break; 284 + } 285 + case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: { 286 + struct hfi_enable *en = prop_data; 287 + u32 *in = pdata; 288 + 289 + en->enable = *in; 290 + packet->shdr.hdr.size += sizeof(u32) + sizeof(*en); 291 + break; 292 + } 293 + default: 294 + return -EINVAL; 295 + } 296 + 297 + return 0; 298 + } 299 + 300 + static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type, 301 + void *payload, u32 payload_size) 302 + { 303 + struct hfi_session_set_property_pkt *pkt; 304 + u32 packet_size; 305 + int ret; 306 + 307 + packet_size = sizeof(*pkt) + sizeof(u32) + payload_size; 308 + pkt = kzalloc(packet_size, GFP_KERNEL); 309 + if (!pkt) 310 + return -ENOMEM; 311 + 312 + ret = iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type, payload); 313 + if (ret == -EOPNOTSUPP) { 314 + ret = 0; 315 + goto exit; 316 + } 317 + if (ret) 318 + goto exit; 319 + 320 + ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); 321 + 322 + exit: 323 + kfree(pkt); 324 + 325 + return ret; 326 + } 327 + 328 + static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet_type, 329 + u32 flag, u32 plane, u32 payload_type, 330 + void *payload, u32 payload_size) 331 + { 332 + return hfi_gen1_set_property(inst, packet_type, payload, payload_size); 333 + } 334 + 335 + static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) 336 + { 337 + u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 338 + struct hfi_framesize fs; 339 + int ret; 340 + 341 + fs.buffer_type = HFI_BUFFER_INPUT; 342 + fs.width = inst->fmt_src->fmt.pix_mp.width; 343 + fs.height = inst->fmt_src->fmt.pix_mp.height; 344 + 345 + ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 346 + if (ret) 347 + return ret; 348 + 349 + fs.buffer_type = HFI_BUFFER_OUTPUT2; 350 + fs.width = inst->fmt_dst->fmt.pix_mp.width; 351 + fs.height = inst->fmt_dst->fmt.pix_mp.height; 352 + 353 + return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 354 + } 355 + 356 + static int iris_hfi_gen1_decide_core(struct iris_inst *inst) 357 + { 358 + const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; 359 + struct hfi_videocores_usage_type cu; 360 + 361 + cu.video_core_enable_mask = HFI_CORE_ID_1; 362 + 363 + return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu)); 364 + } 365 + 366 + static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst) 367 + { 368 + const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 369 + u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 370 + struct hfi_uncompressed_format_select fmt; 371 + int ret; 372 + 373 + if (iris_split_mode_enabled(inst)) { 374 + fmt.buffer_type = HFI_BUFFER_OUTPUT; 375 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0; 376 + 377 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 378 + if (ret) 379 + return ret; 380 + 381 + fmt.buffer_type = HFI_BUFFER_OUTPUT2; 382 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 383 + 384 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 385 + } else { 386 + fmt.buffer_type = HFI_BUFFER_OUTPUT; 387 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 388 + 389 + ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 390 + } 391 + 392 + return ret; 393 + } 394 + 395 + static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst) 396 + { 397 + const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 398 + struct hfi_uncompressed_plane_actual_constraints_info pconstraint; 399 + 400 + pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; 401 + pconstraint.num_planes = 2; 402 + pconstraint.plane_format[0].stride_multiples = 128; 403 + pconstraint.plane_format[0].max_stride = 8192; 404 + pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32; 405 + pconstraint.plane_format[0].buffer_alignment = 256; 406 + 407 + pconstraint.plane_format[1].stride_multiples = 128; 408 + pconstraint.plane_format[1].max_stride = 8192; 409 + pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16; 410 + pconstraint.plane_format[1].buffer_alignment = 256; 411 + 412 + return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint)); 413 + } 414 + 415 + static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst) 416 + { 417 + u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 418 + struct hfi_buffer_count_actual buf_count; 419 + int ret; 420 + 421 + buf_count.type = HFI_BUFFER_INPUT; 422 + buf_count.count_actual = VIDEO_MAX_FRAME; 423 + buf_count.count_min_host = VIDEO_MAX_FRAME; 424 + 425 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 426 + if (ret) 427 + return ret; 428 + 429 + if (iris_split_mode_enabled(inst)) { 430 + buf_count.type = HFI_BUFFER_OUTPUT; 431 + buf_count.count_actual = VIDEO_MAX_FRAME; 432 + buf_count.count_min_host = VIDEO_MAX_FRAME; 433 + 434 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 435 + if (ret) 436 + return ret; 437 + 438 + buf_count.type = HFI_BUFFER_OUTPUT2; 439 + buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); 440 + buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); 441 + 442 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 443 + } else { 444 + buf_count.type = HFI_BUFFER_OUTPUT; 445 + buf_count.count_actual = VIDEO_MAX_FRAME; 446 + buf_count.count_min_host = VIDEO_MAX_FRAME; 447 + 448 + ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 449 + } 450 + 451 + return ret; 452 + } 453 + 454 + static int iris_hfi_gen1_set_multistream(struct iris_inst *inst) 455 + { 456 + u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 457 + struct hfi_multi_stream multi = {0}; 458 + int ret; 459 + 460 + if (iris_split_mode_enabled(inst)) { 461 + multi.buffer_type = HFI_BUFFER_OUTPUT; 462 + multi.enable = 0; 463 + 464 + ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 465 + if (ret) 466 + return ret; 467 + 468 + multi.buffer_type = HFI_BUFFER_OUTPUT2; 469 + multi.enable = 1; 470 + 471 + ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 472 + } else { 473 + multi.buffer_type = HFI_BUFFER_OUTPUT; 474 + multi.enable = 1; 475 + 476 + ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 477 + if (ret) 478 + return ret; 479 + 480 + multi.buffer_type = HFI_BUFFER_OUTPUT2; 481 + multi.enable = 0; 482 + 483 + ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 484 + } 485 + 486 + return ret; 487 + } 488 + 489 + static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst) 490 + { 491 + const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 492 + struct hfi_buffer_size_actual bufsz; 493 + int ret; 494 + 495 + if (iris_split_mode_enabled(inst)) { 496 + bufsz.type = HFI_BUFFER_OUTPUT; 497 + bufsz.size = iris_vpu_dec_dpb_size(inst); 498 + 499 + ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 500 + if (ret) 501 + return ret; 502 + 503 + bufsz.type = HFI_BUFFER_OUTPUT2; 504 + bufsz.size = inst->buffers[BUF_OUTPUT].size; 505 + 506 + ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 507 + } else { 508 + bufsz.type = HFI_BUFFER_OUTPUT; 509 + bufsz.size = inst->buffers[BUF_OUTPUT].size; 510 + 511 + ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 512 + if (ret) 513 + return ret; 514 + 515 + bufsz.type = HFI_BUFFER_OUTPUT2; 516 + bufsz.size = 0; 517 + 518 + ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 519 + } 520 + 521 + return ret; 522 + } 523 + 524 + static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane) 525 + { 526 + struct iris_core *core = inst->core; 527 + u32 config_params_size, i, j; 528 + const u32 *config_params; 529 + int ret; 530 + 531 + static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = { 532 + {HFI_PROPERTY_PARAM_FRAME_SIZE, 533 + iris_hfi_gen1_set_resolution}, 534 + {HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, 535 + iris_hfi_gen1_decide_core}, 536 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 537 + iris_hfi_gen1_set_raw_format}, 538 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 539 + iris_hfi_gen1_set_format_constraints}, 540 + {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 541 + iris_hfi_gen1_set_num_bufs}, 542 + {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 543 + iris_hfi_gen1_set_multistream}, 544 + {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 545 + iris_hfi_gen1_set_bufsize}, 546 + }; 547 + 548 + static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = { 549 + {HFI_PROPERTY_PARAM_FRAME_SIZE, 550 + iris_hfi_gen1_set_resolution}, 551 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 552 + iris_hfi_gen1_set_raw_format}, 553 + {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 554 + iris_hfi_gen1_set_format_constraints}, 555 + {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 556 + iris_hfi_gen1_set_num_bufs}, 557 + {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 558 + iris_hfi_gen1_set_multistream}, 559 + {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 560 + iris_hfi_gen1_set_bufsize}, 561 + }; 562 + 563 + config_params = core->iris_platform_data->input_config_params; 564 + config_params_size = core->iris_platform_data->input_config_params_size; 565 + 566 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 567 + for (i = 0; i < config_params_size; i++) { 568 + for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) { 569 + if (prop_type_handle_inp_arr[j].type == config_params[i]) { 570 + ret = prop_type_handle_inp_arr[j].handle(inst); 571 + if (ret) 572 + return ret; 573 + break; 574 + } 575 + } 576 + } 577 + } else if (V4L2_TYPE_IS_CAPTURE(plane)) { 578 + for (i = 0; i < config_params_size; i++) { 579 + for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) { 580 + if (prop_type_handle_out_arr[j].type == config_params[i]) { 581 + ret = prop_type_handle_out_arr[j].handle(inst); 582 + if (ret) 583 + return ret; 584 + break; 585 + } 586 + } 587 + } 588 + } 589 + 590 + return 0; 591 + } 592 + 186 593 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { 187 594 .sys_init = iris_hfi_gen1_sys_init, 188 595 .sys_image_version = iris_hfi_gen1_sys_image_version, 189 596 .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, 190 597 .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, 191 598 .session_open = iris_hfi_gen1_session_open, 599 + .session_set_config_params = iris_hfi_gen1_session_set_config_params, 600 + .session_set_property = iris_hfi_gen1_session_set_property, 192 601 .session_start = iris_hfi_gen1_session_start, 193 602 .session_stop = iris_hfi_gen1_session_stop, 194 603 .session_close = iris_hfi_gen1_session_close,
+83
drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
··· 23 23 #define HFI_CMD_SYS_SESSION_INIT 0x10007 24 24 #define HFI_CMD_SYS_SESSION_END 0x10008 25 25 26 + #define HFI_CMD_SESSION_SET_PROPERTY 0x11001 27 + 26 28 #define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001 27 29 #define HFI_CMD_SESSION_START 0x211002 28 30 #define HFI_CMD_SESSION_STOP 0x211003 ··· 42 40 #define HFI_FLUSH_OUTPUT 0x1000002 43 41 #define HFI_FLUSH_OUTPUT2 0x1000003 44 42 #define HFI_FLUSH_ALL 0x1000004 43 + 44 + #define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL 0x201001 45 + #define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO 0x201002 46 + #define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE 0x201008 47 + #define HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL 0x20100c 48 + 49 + #define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001 50 + 51 + #define HFI_BUFFER_INPUT 0x1 52 + #define HFI_BUFFER_OUTPUT 0x2 53 + #define HFI_BUFFER_OUTPUT2 0x3 54 + 45 55 #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 46 56 #define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 57 + 58 + #define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001 59 + #define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003 60 + #define HFI_PROPERTY_PARAM_WORK_MODE 0x1015 61 + #define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017 62 + #define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002 63 + 64 + #define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001 65 + #define HFI_CORE_ID_1 1 66 + #define HFI_COLOR_FORMAT_NV12 0x02 67 + #define HFI_COLOR_FORMAT_NV12_UBWC 0x8002 47 68 48 69 #define HFI_MSG_SYS_INIT 0x20001 49 70 #define HFI_MSG_SYS_SESSION_INIT 0x20006 ··· 118 93 u32 data; 119 94 }; 120 95 96 + struct hfi_session_set_property_pkt { 97 + struct hfi_session_hdr_pkt shdr; 98 + u32 num_properties; 99 + u32 data[]; 100 + }; 101 + 121 102 struct hfi_sys_pc_prep_pkt { 122 103 struct hfi_pkt_hdr hdr; 123 104 }; ··· 172 141 }; 173 142 174 143 struct hfi_enable { 144 + u32 enable; 145 + }; 146 + 147 + struct hfi_framesize { 148 + u32 buffer_type; 149 + u32 width; 150 + u32 height; 151 + }; 152 + 153 + struct hfi_videocores_usage_type { 154 + u32 video_core_enable_mask; 155 + }; 156 + 157 + struct hfi_video_work_mode { 158 + u32 video_work_mode; 159 + }; 160 + 161 + struct hfi_video_work_route { 162 + u32 video_work_route; 163 + }; 164 + 165 + struct hfi_uncompressed_format_select { 166 + u32 buffer_type; 167 + u32 format; 168 + }; 169 + 170 + struct hfi_uncompressed_plane_constraints { 171 + u32 stride_multiples; 172 + u32 max_stride; 173 + u32 min_plane_buffer_height_multiple; 174 + u32 buffer_alignment; 175 + }; 176 + 177 + struct hfi_uncompressed_plane_actual_constraints_info { 178 + u32 buffer_type; 179 + u32 num_planes; 180 + struct hfi_uncompressed_plane_constraints plane_format[2]; 181 + }; 182 + 183 + struct hfi_buffer_count_actual { 184 + u32 type; 185 + u32 count_actual; 186 + u32 count_min_host; 187 + }; 188 + 189 + struct hfi_buffer_size_actual { 190 + u32 type; 191 + u32 size; 192 + }; 193 + 194 + struct hfi_multi_stream { 195 + u32 buffer_type; 175 196 u32 enable; 176 197 }; 177 198
+2
drivers/media/platform/qcom/iris/iris_hfi_gen2.h
··· 18 18 * 19 19 * @inst: pointer to iris_instance structure 20 20 * @packet: HFI packet 21 + * @src_subcr_params: subscription params to fw on input port 21 22 */ 22 23 struct iris_inst_hfi_gen2 { 23 24 struct iris_inst inst; 24 25 struct iris_hfi_header *packet; 26 + struct hfi_subscription_params src_subcr_params; 25 27 }; 26 28 27 29 void iris_hfi_gen2_command_ops_init(struct iris_core *core);
+300
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
··· 3 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 4 */ 5 5 6 + #include <linux/bitfield.h> 7 + 6 8 #include "iris_hfi_gen2.h" 7 9 #include "iris_hfi_gen2_packet.h" 8 10 11 + #define UNSPECIFIED_COLOR_FORMAT 5 9 12 #define NUM_SYS_INIT_PACKETS 8 10 13 11 14 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \ ··· 98 95 default: 99 96 return HFI_PORT_NONE; 100 97 } 98 + } 99 + 100 + static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag, 101 + u32 plane, u32 payload_type, void *payload, 102 + u32 payload_size) 103 + { 104 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 105 + 106 + iris_hfi_gen2_packet_session_property(inst, 107 + packet_type, 108 + flag, 109 + plane, 110 + payload_type, 111 + payload, 112 + payload_size); 113 + 114 + return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 115 + inst_hfi_gen2->packet->size); 116 + } 117 + 118 + static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst) 119 + { 120 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 121 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 122 + u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 | 123 + inst->fmt_src->fmt.pix_mp.height; 124 + 125 + inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution; 126 + 127 + return iris_hfi_gen2_session_set_property(inst, 128 + HFI_PROP_BITSTREAM_RESOLUTION, 129 + HFI_HOST_FLAGS_NONE, 130 + port, 131 + HFI_PAYLOAD_U32, 132 + &resolution, 133 + sizeof(u32)); 134 + } 135 + 136 + static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) 137 + { 138 + u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); 139 + u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); 140 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 141 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 142 + u32 left_offset = inst->crop.left; 143 + u32 top_offset = inst->crop.top; 144 + u32 payload[2]; 145 + 146 + payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset; 147 + payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset; 148 + inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0]; 149 + inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1]; 150 + 151 + return iris_hfi_gen2_session_set_property(inst, 152 + HFI_PROP_CROP_OFFSETS, 153 + HFI_HOST_FLAGS_NONE, 154 + port, 155 + HFI_PAYLOAD_64_PACKED, 156 + &payload, 157 + sizeof(u64)); 158 + } 159 + 160 + static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst) 161 + { 162 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 163 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 164 + u32 bitdepth = BIT_DEPTH_8; 165 + 166 + inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth; 167 + 168 + return iris_hfi_gen2_session_set_property(inst, 169 + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, 170 + HFI_HOST_FLAGS_NONE, 171 + port, 172 + HFI_PAYLOAD_U32, 173 + &bitdepth, 174 + sizeof(u32)); 175 + } 176 + 177 + static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst) 178 + { 179 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 180 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 181 + u32 coded_frames = 0; 182 + 183 + if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE) 184 + coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG; 185 + inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames; 186 + 187 + return iris_hfi_gen2_session_set_property(inst, 188 + HFI_PROP_CODED_FRAMES, 189 + HFI_HOST_FLAGS_NONE, 190 + port, 191 + HFI_PAYLOAD_U32, 192 + &coded_frames, 193 + sizeof(u32)); 194 + } 195 + 196 + static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst) 197 + { 198 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 199 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 200 + u32 min_output = inst->buffers[BUF_OUTPUT].min_count; 201 + 202 + inst_hfi_gen2->src_subcr_params.fw_min_count = min_output; 203 + 204 + return iris_hfi_gen2_session_set_property(inst, 205 + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, 206 + HFI_HOST_FLAGS_NONE, 207 + port, 208 + HFI_PAYLOAD_U32, 209 + &min_output, 210 + sizeof(u32)); 211 + } 212 + 213 + static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst) 214 + { 215 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 216 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 217 + u32 poc = 0; 218 + 219 + inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc; 220 + 221 + return iris_hfi_gen2_session_set_property(inst, 222 + HFI_PROP_PIC_ORDER_CNT_TYPE, 223 + HFI_HOST_FLAGS_NONE, 224 + port, 225 + HFI_PAYLOAD_U32, 226 + &poc, 227 + sizeof(u32)); 228 + } 229 + 230 + static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst) 231 + { 232 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 233 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 234 + struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp; 235 + u32 video_signal_type_present_flag = 0, color_info; 236 + u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED; 237 + u32 video_format = UNSPECIFIED_COLOR_FORMAT; 238 + u32 full_range = V4L2_QUANTIZATION_DEFAULT; 239 + u32 transfer_char = HFI_TRANSFER_RESERVED; 240 + u32 colour_description_present_flag = 0; 241 + u32 primaries = HFI_PRIMARIES_RESERVED; 242 + 243 + if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT || 244 + pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT || 245 + pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) { 246 + colour_description_present_flag = 1; 247 + video_signal_type_present_flag = 1; 248 + primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace); 249 + matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc); 250 + transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func); 251 + } 252 + 253 + if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) { 254 + video_signal_type_present_flag = 1; 255 + full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0; 256 + } 257 + 258 + color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries, 259 + colour_description_present_flag, full_range, 260 + video_format, video_signal_type_present_flag); 261 + 262 + inst_hfi_gen2->src_subcr_params.color_info = color_info; 263 + 264 + return iris_hfi_gen2_session_set_property(inst, 265 + HFI_PROP_SIGNAL_COLOR_INFO, 266 + HFI_HOST_FLAGS_NONE, 267 + port, 268 + HFI_PAYLOAD_32_PACKED, 269 + &color_info, 270 + sizeof(u32)); 271 + } 272 + 273 + static int iris_hfi_gen2_set_profile(struct iris_inst *inst) 274 + { 275 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 276 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 277 + u32 profile = inst->fw_caps[PROFILE].value; 278 + 279 + inst_hfi_gen2->src_subcr_params.profile = profile; 280 + 281 + return iris_hfi_gen2_session_set_property(inst, 282 + HFI_PROP_PROFILE, 283 + HFI_HOST_FLAGS_NONE, 284 + port, 285 + HFI_PAYLOAD_U32_ENUM, 286 + &profile, 287 + sizeof(u32)); 288 + } 289 + 290 + static int iris_hfi_gen2_set_level(struct iris_inst *inst) 291 + { 292 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 293 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 294 + u32 level = inst->fw_caps[LEVEL].value; 295 + 296 + inst_hfi_gen2->src_subcr_params.level = level; 297 + 298 + return iris_hfi_gen2_session_set_property(inst, 299 + HFI_PROP_LEVEL, 300 + HFI_HOST_FLAGS_NONE, 301 + port, 302 + HFI_PAYLOAD_U32_ENUM, 303 + &level, 304 + sizeof(u32)); 305 + } 306 + 307 + static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst) 308 + { 309 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 310 + u32 hfi_colorformat, pixelformat; 311 + 312 + pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 313 + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; 314 + 315 + return iris_hfi_gen2_session_set_property(inst, 316 + HFI_PROP_COLOR_FORMAT, 317 + HFI_HOST_FLAGS_NONE, 318 + port, 319 + HFI_PAYLOAD_U32, 320 + &hfi_colorformat, 321 + sizeof(u32)); 322 + } 323 + 324 + static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) 325 + { 326 + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 327 + u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 328 + u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height; 329 + u32 stride_y = inst->fmt_dst->fmt.pix_mp.width; 330 + u32 scanline_uv = scanline_y / 2; 331 + u32 stride_uv = stride_y; 332 + u32 payload[2]; 333 + 334 + if (pixelformat != V4L2_PIX_FMT_NV12) 335 + return 0; 336 + 337 + payload[0] = stride_y << 16 | scanline_y; 338 + payload[1] = stride_uv << 16 | scanline_uv; 339 + 340 + return iris_hfi_gen2_session_set_property(inst, 341 + HFI_PROP_LINEAR_STRIDE_SCANLINE, 342 + HFI_HOST_FLAGS_NONE, 343 + port, 344 + HFI_PAYLOAD_U64, 345 + &payload, 346 + sizeof(u64)); 347 + } 348 + 349 + static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) 350 + { 351 + struct iris_core *core = inst->core; 352 + u32 config_params_size, i, j; 353 + const u32 *config_params; 354 + int ret; 355 + 356 + static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = { 357 + {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, 358 + {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, 359 + {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, 360 + {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_dpeth }, 361 + {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count }, 362 + {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count }, 363 + {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace }, 364 + {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile }, 365 + {HFI_PROP_LEVEL, iris_hfi_gen2_set_level }, 366 + {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, 367 + {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, 368 + }; 369 + 370 + if (V4L2_TYPE_IS_OUTPUT(plane)) { 371 + config_params = core->iris_platform_data->input_config_params; 372 + config_params_size = core->iris_platform_data->input_config_params_size; 373 + } else { 374 + config_params = core->iris_platform_data->output_config_params; 375 + config_params_size = core->iris_platform_data->output_config_params_size; 376 + } 377 + 378 + if (!config_params || !config_params_size) 379 + return -EINVAL; 380 + 381 + for (i = 0; i < config_params_size; i++) { 382 + for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) { 383 + if (prop_type_handle_arr[j].type == config_params[i]) { 384 + ret = prop_type_handle_arr[j].handle(inst); 385 + if (ret) 386 + return ret; 387 + break; 388 + } 389 + } 390 + } 391 + 392 + return 0; 101 393 } 102 394 103 395 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) ··· 551 253 .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, 552 254 .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, 553 255 .session_open = iris_hfi_gen2_session_open, 256 + .session_set_config_params = iris_hfi_gen2_session_set_config_params, 257 + .session_set_property = iris_hfi_gen2_session_set_property, 554 258 .session_start = iris_hfi_gen2_session_start, 555 259 .session_stop = iris_hfi_gen2_session_stop, 556 260 .session_close = iris_hfi_gen2_session_close,
+27
drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
··· 19 19 #define HFI_CMD_STOP 0x01000006 20 20 #define HFI_CMD_END 0x01FFFFFF 21 21 22 + #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG 0x00000001 23 + 22 24 #define HFI_PROP_BEGIN 0x03000000 23 25 #define HFI_PROP_IMAGE_VERSION 0x03000001 24 26 #define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE 0x03000002 ··· 32 30 #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008 33 31 #define HFI_PROP_UBWC_BANK_SPREADING 0x03000009 34 32 #define HFI_PROP_CODEC 0x03000100 33 + #define HFI_PROP_COLOR_FORMAT 0x03000101 34 + #define HFI_PROP_BITSTREAM_RESOLUTION 0x03000103 35 + #define HFI_PROP_LINEAR_STRIDE_SCANLINE 0x03000104 36 + #define HFI_PROP_CROP_OFFSETS 0x03000105 35 37 #define HFI_PROP_PROFILE 0x03000107 36 38 #define HFI_PROP_LEVEL 0x03000108 39 + #define HFI_PROP_STAGE 0x0300010a 40 + #define HFI_PROP_PIPE 0x0300010b 41 + #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f 42 + #define HFI_PROP_CODED_FRAMES 0x03000120 43 + #define HFI_PROP_BUFFER_HOST_MAX_COUNT 0x03000123 44 + #define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT 0x03000124 45 + #define HFI_PROP_PIC_ORDER_CNT_TYPE 0x03000128 46 + #define HFI_PROP_QUALITY_MODE 0x03000148 47 + #define HFI_PROP_SIGNAL_COLOR_INFO 0x03000155 37 48 #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 49 + #define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 38 50 #define HFI_PROP_END 0x03FFFFFF 39 51 40 52 #define HFI_SESSION_ERROR_BEGIN 0x04000000 ··· 64 48 #define HFI_SYSTEM_ERROR_BEGIN 0x05000000 65 49 #define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 66 50 #define HFI_SYSTEM_ERROR_END 0x05FFFFFF 51 + 52 + enum hfi_color_format { 53 + HFI_COLOR_FMT_OPAQUE = 0, 54 + HFI_COLOR_FMT_NV12 = 1, 55 + HFI_COLOR_FMT_NV12_UBWC = 2, 56 + HFI_COLOR_FMT_P010 = 3, 57 + HFI_COLOR_FMT_TP10_UBWC = 4, 58 + HFI_COLOR_FMT_RGBA8888 = 5, 59 + HFI_COLOR_FMT_RGBA8888_UBWC = 6, 60 + HFI_COLOR_FMT_NV21 = 7, 61 + }; 67 62 68 63 enum hfi_codec_type { 69 64 HFI_CODEC_DECODE_AVC = 1,
+79
drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
··· 7 7 #include "iris_hfi_gen2.h" 8 8 #include "iris_hfi_gen2_packet.h" 9 9 10 + u32 iris_hfi_gen2_get_color_primaries(u32 primaries) 11 + { 12 + switch (primaries) { 13 + case V4L2_COLORSPACE_DEFAULT: 14 + return HFI_PRIMARIES_RESERVED; 15 + case V4L2_COLORSPACE_REC709: 16 + return HFI_PRIMARIES_BT709; 17 + case V4L2_COLORSPACE_470_SYSTEM_M: 18 + return HFI_PRIMARIES_BT470_SYSTEM_M; 19 + case V4L2_COLORSPACE_470_SYSTEM_BG: 20 + return HFI_PRIMARIES_BT470_SYSTEM_BG; 21 + case V4L2_COLORSPACE_SMPTE170M: 22 + return HFI_PRIMARIES_BT601_525; 23 + case V4L2_COLORSPACE_SMPTE240M: 24 + return HFI_PRIMARIES_SMPTE_ST240M; 25 + case V4L2_COLORSPACE_BT2020: 26 + return HFI_PRIMARIES_BT2020; 27 + case V4L2_COLORSPACE_DCI_P3: 28 + return HFI_PRIMARIES_SMPTE_RP431_2; 29 + default: 30 + return HFI_PRIMARIES_RESERVED; 31 + } 32 + } 33 + 34 + u32 iris_hfi_gen2_get_transfer_char(u32 characterstics) 35 + { 36 + switch (characterstics) { 37 + case V4L2_XFER_FUNC_DEFAULT: 38 + return HFI_TRANSFER_RESERVED; 39 + case V4L2_XFER_FUNC_709: 40 + return HFI_TRANSFER_BT709; 41 + case V4L2_XFER_FUNC_SMPTE240M: 42 + return HFI_TRANSFER_SMPTE_ST240M; 43 + case V4L2_XFER_FUNC_SRGB: 44 + return HFI_TRANSFER_SRGB_SYCC; 45 + case V4L2_XFER_FUNC_SMPTE2084: 46 + return HFI_TRANSFER_SMPTE_ST2084_PQ; 47 + default: 48 + return HFI_TRANSFER_RESERVED; 49 + } 50 + } 51 + 52 + u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients) 53 + { 54 + switch (coefficients) { 55 + case V4L2_YCBCR_ENC_DEFAULT: 56 + return HFI_MATRIX_COEFF_RESERVED; 57 + case V4L2_YCBCR_ENC_709: 58 + return HFI_MATRIX_COEFF_BT709; 59 + case V4L2_YCBCR_ENC_XV709: 60 + return HFI_MATRIX_COEFF_BT709; 61 + case V4L2_YCBCR_ENC_XV601: 62 + return HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625; 63 + case V4L2_YCBCR_ENC_601: 64 + return HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625; 65 + case V4L2_YCBCR_ENC_SMPTE240M: 66 + return HFI_MATRIX_COEFF_SMPTE_ST240; 67 + case V4L2_YCBCR_ENC_BT2020: 68 + return HFI_MATRIX_COEFF_BT2020_NON_CONSTANT; 69 + case V4L2_YCBCR_ENC_BT2020_CONST_LUM: 70 + return HFI_MATRIX_COEFF_BT2020_CONSTANT; 71 + default: 72 + return HFI_MATRIX_COEFF_RESERVED; 73 + } 74 + } 75 + 76 + u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 primaries, 77 + u32 colour_description_present_flag, u32 full_range, 78 + u32 video_format, u32 video_signal_type_present_flag) 79 + { 80 + return (matrix_coeff & 0xFF) | 81 + ((transfer_char << 8) & 0xFF00) | 82 + ((primaries << 16) & 0xFF0000) | 83 + ((colour_description_present_flag << 24) & 0x1000000) | 84 + ((full_range << 25) & 0x2000000) | 85 + ((video_format << 26) & 0x1C000000) | 86 + ((video_signal_type_present_flag << 29) & 0x20000000); 87 + } 88 + 10 89 static void iris_hfi_gen2_create_header(struct iris_hfi_header *hdr, 11 90 u32 session_id, u32 header_id) 12 91 {
+7
drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
··· 61 61 u32 payload[]; 62 62 }; 63 63 64 + u32 iris_hfi_gen2_get_color_primaries(u32 primaries); 65 + u32 iris_hfi_gen2_get_transfer_char(u32 characterstics); 66 + u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients); 67 + u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 primaries, 68 + u32 colour_description_present_flag, u32 full_range, 69 + u32 video_format, u32 video_signal_type_present_flag); 70 + 64 71 void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr); 65 72 void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr); 66 73 void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_type,
+49
drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
··· 166 166 return 0; 167 167 } 168 168 169 + static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, 170 + struct iris_hfi_packet *pkt) 171 + { 172 + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 173 + 174 + if (pkt->port != HFI_PORT_BITSTREAM) 175 + return 0; 176 + 177 + if (pkt->flags & HFI_FW_FLAGS_INFORMATION) 178 + return 0; 179 + 180 + switch (pkt->type) { 181 + case HFI_PROP_BITSTREAM_RESOLUTION: 182 + inst_hfi_gen2->src_subcr_params.bitstream_resolution = pkt->payload[0]; 183 + break; 184 + case HFI_PROP_CROP_OFFSETS: 185 + inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0]; 186 + inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1]; 187 + break; 188 + case HFI_PROP_CODED_FRAMES: 189 + inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0]; 190 + break; 191 + case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: 192 + inst_hfi_gen2->src_subcr_params.fw_min_count = pkt->payload[0]; 193 + break; 194 + case HFI_PROP_PIC_ORDER_CNT_TYPE: 195 + inst_hfi_gen2->src_subcr_params.pic_order_cnt = pkt->payload[0]; 196 + break; 197 + case HFI_PROP_SIGNAL_COLOR_INFO: 198 + inst_hfi_gen2->src_subcr_params.color_info = pkt->payload[0]; 199 + break; 200 + case HFI_PROP_PROFILE: 201 + inst_hfi_gen2->src_subcr_params.profile = pkt->payload[0]; 202 + break; 203 + case HFI_PROP_LEVEL: 204 + inst_hfi_gen2->src_subcr_params.level = pkt->payload[0]; 205 + break; 206 + case HFI_PROP_QUALITY_MODE: 207 + case HFI_PROP_STAGE: 208 + case HFI_PROP_PIPE: 209 + default: 210 + break; 211 + } 212 + 213 + return 0; 214 + } 215 + 169 216 static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, 170 217 struct iris_hfi_packet *pkt) 171 218 { ··· 297 250 static const struct iris_hfi_gen2_inst_hfi_range range[] = { 298 251 {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, 299 252 iris_hfi_gen2_handle_session_error}, 253 + {HFI_PROP_BEGIN, HFI_PROP_END, 254 + iris_hfi_gen2_handle_session_property}, 300 255 {HFI_CMD_BEGIN, HFI_CMD_END, 301 256 iris_hfi_gen2_handle_session_command }, 302 257 };
+32
drivers/media/platform/qcom/iris/iris_platform_common.h
··· 6 6 #ifndef __IRIS_PLATFORM_COMMON_H__ 7 7 #define __IRIS_PLATFORM_COMMON_H__ 8 8 9 + #include <linux/bits.h> 10 + 9 11 struct iris_core; 12 + struct iris_inst; 10 13 11 14 #define IRIS_PAS_ID 9 12 15 #define HW_RESPONSE_TIMEOUT_VALUE (1000) /* milliseconds */ 13 16 #define AUTOSUSPEND_DELAY_VALUE (HW_RESPONSE_TIMEOUT_VALUE + 500) /* milliseconds */ 17 + 18 + #define REGISTER_BIT_DEPTH(luma, chroma) ((luma) << 16 | (chroma)) 19 + #define BIT_DEPTH_8 REGISTER_BIT_DEPTH(8, 8) 20 + #define CODED_FRAMES_PROGRESSIVE 0x0 21 + #define DEFAULT_MAX_HOST_BUF_COUNT 64 22 + #define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256 23 + enum stage_type { 24 + STAGE_1 = 1, 25 + STAGE_2 = 2, 26 + }; 27 + 28 + enum pipe_type { 29 + PIPE_1 = 1, 30 + PIPE_2 = 2, 31 + PIPE_4 = 4, 32 + }; 14 33 15 34 extern struct iris_platform_data sm8550_data; 16 35 ··· 72 53 enum platform_inst_fw_cap_type { 73 54 PROFILE = 1, 74 55 LEVEL, 56 + INPUT_BUF_HOST_MAX_COUNT, 57 + STAGE, 58 + PIPE, 59 + POC, 60 + CODED_FRAMES, 61 + BIT_DEPTH, 62 + RAP_FRAME, 75 63 DEBLOCK, 76 64 INST_FW_CAP_MAX, 77 65 }; ··· 101 75 s64 value; 102 76 u32 hfi_id; 103 77 enum platform_inst_fw_cap_flags flags; 78 + int (*set)(struct iris_inst *inst, 79 + enum platform_inst_fw_cap_type cap_id); 104 80 }; 105 81 106 82 struct iris_core_power { ··· 143 115 struct ubwc_config_data *ubwc_config; 144 116 u32 num_vpp_pipe; 145 117 u32 max_session_count; 118 + const u32 *input_config_params; 119 + unsigned int input_config_params_size; 120 + const u32 *output_config_params; 121 + unsigned int output_config_params_size; 146 122 }; 147 123 148 124 #endif
+89
drivers/media/platform/qcom/iris/iris_platform_sm8550.c
··· 4 4 */ 5 5 6 6 #include "iris_core.h" 7 + #include "iris_ctrls.h" 7 8 #include "iris_hfi_gen2.h" 8 9 #include "iris_hfi_gen2_defines.h" 9 10 #include "iris_platform_common.h" ··· 25 24 .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 26 25 .hfi_id = HFI_PROP_PROFILE, 27 26 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, 27 + .set = iris_set_u32_enum, 28 28 }, 29 29 { 30 30 .cap_id = LEVEL, ··· 54 52 .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1, 55 53 .hfi_id = HFI_PROP_LEVEL, 56 54 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, 55 + .set = iris_set_u32_enum, 56 + }, 57 + { 58 + .cap_id = INPUT_BUF_HOST_MAX_COUNT, 59 + .min = DEFAULT_MAX_HOST_BUF_COUNT, 60 + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT, 61 + .step_or_mask = 1, 62 + .value = DEFAULT_MAX_HOST_BUF_COUNT, 63 + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT, 64 + .flags = CAP_FLAG_INPUT_PORT, 65 + .set = iris_set_u32, 66 + }, 67 + { 68 + .cap_id = STAGE, 69 + .min = STAGE_1, 70 + .max = STAGE_2, 71 + .step_or_mask = 1, 72 + .value = STAGE_2, 73 + .hfi_id = HFI_PROP_STAGE, 74 + .set = iris_set_stage, 75 + }, 76 + { 77 + .cap_id = PIPE, 78 + .min = PIPE_1, 79 + .max = PIPE_4, 80 + .step_or_mask = 1, 81 + .value = PIPE_4, 82 + .hfi_id = HFI_PROP_PIPE, 83 + .set = iris_set_pipe, 84 + }, 85 + { 86 + .cap_id = POC, 87 + .min = 0, 88 + .max = 2, 89 + .step_or_mask = 1, 90 + .value = 1, 91 + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE, 92 + }, 93 + { 94 + .cap_id = CODED_FRAMES, 95 + .min = CODED_FRAMES_PROGRESSIVE, 96 + .max = CODED_FRAMES_PROGRESSIVE, 97 + .step_or_mask = 0, 98 + .value = CODED_FRAMES_PROGRESSIVE, 99 + .hfi_id = HFI_PROP_CODED_FRAMES, 100 + }, 101 + { 102 + .cap_id = BIT_DEPTH, 103 + .min = BIT_DEPTH_8, 104 + .max = BIT_DEPTH_8, 105 + .step_or_mask = 1, 106 + .value = BIT_DEPTH_8, 107 + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH, 108 + }, 109 + { 110 + .cap_id = RAP_FRAME, 111 + .min = 0, 112 + .max = 1, 113 + .step_or_mask = 1, 114 + .value = 1, 115 + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME, 116 + .flags = CAP_FLAG_INPUT_PORT, 117 + .set = iris_set_u32, 57 118 }, 58 119 }; 59 120 ··· 167 102 .cp_nonpixel_size = 0x24800000, 168 103 }; 169 104 105 + static const u32 sm8550_vdec_input_config_params[] = { 106 + HFI_PROP_BITSTREAM_RESOLUTION, 107 + HFI_PROP_CROP_OFFSETS, 108 + HFI_PROP_CODED_FRAMES, 109 + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, 110 + HFI_PROP_PIC_ORDER_CNT_TYPE, 111 + HFI_PROP_PROFILE, 112 + HFI_PROP_LEVEL, 113 + HFI_PROP_SIGNAL_COLOR_INFO, 114 + }; 115 + 116 + static const u32 sm8550_vdec_output_config_params[] = { 117 + HFI_PROP_COLOR_FORMAT, 118 + HFI_PROP_LINEAR_STRIDE_SCANLINE, 119 + }; 120 + 170 121 struct iris_platform_data sm8550_data = { 171 122 .get_instance = iris_hfi_gen2_get_instance, 172 123 .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, ··· 212 131 .ubwc_config = &ubwc_config_sm8550, 213 132 .num_vpp_pipe = 4, 214 133 .max_session_count = 16, 134 + .input_config_params = 135 + sm8550_vdec_input_config_params, 136 + .input_config_params_size = 137 + ARRAY_SIZE(sm8550_vdec_input_config_params), 138 + .output_config_params = 139 + sm8550_vdec_output_config_params, 140 + .output_config_params_size = 141 + ARRAY_SIZE(sm8550_vdec_output_config_params), 215 142 };
+19
drivers/media/platform/qcom/iris/iris_utils.c
··· 8 8 #include "iris_instance.h" 9 9 #include "iris_utils.h" 10 10 11 + bool iris_res_is_less_than(u32 width, u32 height, 12 + u32 ref_width, u32 ref_height) 13 + { 14 + u32 num_mbs = NUM_MBS_PER_FRAME(height, width); 15 + u32 max_side = max(ref_width, ref_height); 16 + 17 + if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) && 18 + width < max_side && 19 + height < max_side) 20 + return true; 21 + 22 + return false; 23 + } 24 + 11 25 int iris_get_mbpf(struct iris_inst *inst) 12 26 { 13 27 struct v4l2_format *inp_f = inst->fmt_src; ··· 29 15 u32 width = max(inp_f->fmt.pix_mp.width, inst->crop.width); 30 16 31 17 return NUM_MBS_PER_FRAME(height, width); 18 + } 19 + 20 + bool iris_split_mode_enabled(struct iris_inst *inst) 21 + { 22 + return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12; 32 23 } 33 24 34 25 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
+3
drivers/media/platform/qcom/iris/iris_utils.h
··· 27 27 return BUF_OUTPUT; 28 28 } 29 29 30 + bool iris_res_is_less_than(u32 width, u32 height, 31 + u32 ref_width, u32 ref_height); 30 32 int iris_get_mbpf(struct iris_inst *inst); 33 + bool iris_split_mode_enabled(struct iris_inst *inst); 31 34 struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id); 32 35 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush); 33 36
+11
drivers/media/platform/qcom/iris/iris_vdec.c
··· 267 267 268 268 int iris_vdec_streamon_input(struct iris_inst *inst) 269 269 { 270 + int ret; 271 + 272 + ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 273 + if (ret) 274 + return ret; 275 + 270 276 return iris_vdec_process_streamon_input(inst); 271 277 } 272 278 ··· 290 284 291 285 int iris_vdec_streamon_output(struct iris_inst *inst) 292 286 { 287 + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 293 288 int ret; 289 + 290 + ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 291 + if (ret) 292 + return ret; 294 293 295 294 ret = iris_vdec_process_streamon_output(inst); 296 295 if (ret)
+20
drivers/media/platform/qcom/iris/iris_vpu_buffer.c
··· 6 6 #include "iris_instance.h" 7 7 #include "iris_vpu_buffer.h" 8 8 9 + u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) 10 + { 11 + if (iris_split_mode_enabled(inst)) 12 + return iris_get_buffer_size(inst, BUF_DPB); 13 + else 14 + return 0; 15 + } 16 + 17 + static inline int iris_vpu_dpb_count(struct iris_inst *inst) 18 + { 19 + if (iris_split_mode_enabled(inst)) { 20 + return inst->fw_min_count ? 21 + inst->fw_min_count : inst->buffers[BUF_OUTPUT].min_count; 22 + } 23 + 24 + return 0; 25 + } 26 + 9 27 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) 10 28 { 11 29 switch (buffer_type) { ··· 31 13 return MIN_BUFFERS; 32 14 case BUF_OUTPUT: 33 15 return inst->fw_min_count; 16 + case BUF_DPB: 17 + return iris_vpu_dpb_count(inst); 34 18 default: 35 19 return 0; 36 20 }
+1
drivers/media/platform/qcom/iris/iris_vpu_buffer.h
··· 10 10 11 11 #define MIN_BUFFERS 4 12 12 13 + u32 iris_vpu_dec_dpb_size(struct iris_inst *inst); 13 14 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); 14 15 15 16 #endif