1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/types.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_ctrls.h" 10 #include "iris_instance.h" 11 12 static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id) 13 { 14 return cap_id >= 1 && cap_id < INST_FW_CAP_MAX; 15 } 16 17 static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id) 18 { 19 switch (id) { 20 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 21 return PROFILE_H264; 22 case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: 23 return PROFILE_HEVC; 24 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: 25 return PROFILE_VP9; 26 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 27 return LEVEL_H264; 28 case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: 29 return LEVEL_HEVC; 30 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: 31 return LEVEL_VP9; 32 case V4L2_CID_MPEG_VIDEO_HEVC_TIER: 33 return TIER; 34 case V4L2_CID_MPEG_VIDEO_HEADER_MODE: 35 return HEADER_MODE; 36 case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: 37 return PREPEND_SPSPPS_TO_IDR; 38 case V4L2_CID_MPEG_VIDEO_BITRATE: 39 return BITRATE; 40 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: 41 return BITRATE_PEAK; 42 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: 43 return BITRATE_MODE; 44 case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: 45 return FRAME_SKIP_MODE; 46 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: 47 return FRAME_RC_ENABLE; 48 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 49 return GOP_SIZE; 50 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: 51 return ENTROPY_MODE; 52 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: 53 return MIN_FRAME_QP_H264; 54 case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: 55 return MIN_FRAME_QP_HEVC; 56 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: 57 return MAX_FRAME_QP_H264; 58 case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: 59 return MAX_FRAME_QP_HEVC; 60 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: 61 return I_FRAME_MIN_QP_H264; 62 case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: 63 return I_FRAME_MIN_QP_HEVC; 64 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: 65 return P_FRAME_MIN_QP_H264; 66 case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: 67 return P_FRAME_MIN_QP_HEVC; 68 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: 69 return B_FRAME_MIN_QP_H264; 70 case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: 71 return B_FRAME_MIN_QP_HEVC; 72 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: 73 return I_FRAME_MAX_QP_H264; 74 case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: 75 return I_FRAME_MAX_QP_HEVC; 76 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: 77 return P_FRAME_MAX_QP_H264; 78 case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: 79 return P_FRAME_MAX_QP_HEVC; 80 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: 81 return B_FRAME_MAX_QP_H264; 82 case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: 83 return B_FRAME_MAX_QP_HEVC; 84 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: 85 return I_FRAME_QP_H264; 86 case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: 87 return I_FRAME_QP_HEVC; 88 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: 89 return P_FRAME_QP_H264; 90 case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: 91 return P_FRAME_QP_HEVC; 92 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: 93 return B_FRAME_QP_H264; 94 case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: 95 return B_FRAME_QP_HEVC; 96 default: 97 return INST_FW_CAP_MAX; 98 } 99 } 100 101 static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) 102 { 103 if (!iris_valid_cap_id(cap_id)) 104 return 0; 105 106 switch (cap_id) { 107 case PROFILE_H264: 108 return V4L2_CID_MPEG_VIDEO_H264_PROFILE; 109 case PROFILE_HEVC: 110 return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE; 111 case PROFILE_VP9: 112 return V4L2_CID_MPEG_VIDEO_VP9_PROFILE; 113 case LEVEL_H264: 114 return V4L2_CID_MPEG_VIDEO_H264_LEVEL; 115 case LEVEL_HEVC: 116 return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL; 117 case LEVEL_VP9: 118 return V4L2_CID_MPEG_VIDEO_VP9_LEVEL; 119 case TIER: 120 return V4L2_CID_MPEG_VIDEO_HEVC_TIER; 121 case HEADER_MODE: 122 return V4L2_CID_MPEG_VIDEO_HEADER_MODE; 123 case PREPEND_SPSPPS_TO_IDR: 124 return V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR; 125 case BITRATE: 126 return V4L2_CID_MPEG_VIDEO_BITRATE; 127 case BITRATE_PEAK: 128 return V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; 129 case BITRATE_MODE: 130 return V4L2_CID_MPEG_VIDEO_BITRATE_MODE; 131 case FRAME_SKIP_MODE: 132 return V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE; 133 case FRAME_RC_ENABLE: 134 return V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE; 135 case GOP_SIZE: 136 return V4L2_CID_MPEG_VIDEO_GOP_SIZE; 137 case ENTROPY_MODE: 138 return V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 139 case MIN_FRAME_QP_H264: 140 return V4L2_CID_MPEG_VIDEO_H264_MIN_QP; 141 case MIN_FRAME_QP_HEVC: 142 return V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP; 143 case MAX_FRAME_QP_H264: 144 return V4L2_CID_MPEG_VIDEO_H264_MAX_QP; 145 case MAX_FRAME_QP_HEVC: 146 return V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP; 147 case I_FRAME_MIN_QP_H264: 148 return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP; 149 case I_FRAME_MIN_QP_HEVC: 150 return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP; 151 case P_FRAME_MIN_QP_H264: 152 return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP; 153 case P_FRAME_MIN_QP_HEVC: 154 return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP; 155 case B_FRAME_MIN_QP_H264: 156 return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP; 157 case B_FRAME_MIN_QP_HEVC: 158 return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP; 159 case I_FRAME_MAX_QP_H264: 160 return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP; 161 case I_FRAME_MAX_QP_HEVC: 162 return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP; 163 case P_FRAME_MAX_QP_H264: 164 return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP; 165 case P_FRAME_MAX_QP_HEVC: 166 return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP; 167 case B_FRAME_MAX_QP_H264: 168 return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP; 169 case B_FRAME_MAX_QP_HEVC: 170 return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP; 171 case I_FRAME_QP_H264: 172 return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; 173 case I_FRAME_QP_HEVC: 174 return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP; 175 case P_FRAME_QP_H264: 176 return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; 177 case P_FRAME_QP_HEVC: 178 return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP; 179 case B_FRAME_QP_H264: 180 return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; 181 case B_FRAME_QP_HEVC: 182 return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP; 183 default: 184 return 0; 185 } 186 } 187 188 static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) 189 { 190 struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler); 191 enum platform_inst_fw_cap_type cap_id; 192 struct platform_inst_fw_cap *cap; 193 struct vb2_queue *q; 194 195 cap = &inst->fw_caps[0]; 196 cap_id = iris_get_cap_id(ctrl->id); 197 if (!iris_valid_cap_id(cap_id)) 198 return -EINVAL; 199 200 q = v4l2_m2m_get_src_vq(inst->m2m_ctx); 201 if (vb2_is_streaming(q) && 202 (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED))) 203 return -EINVAL; 204 205 cap[cap_id].flags |= CAP_FLAG_CLIENT_SET; 206 207 inst->fw_caps[cap_id].value = ctrl->val; 208 209 return 0; 210 } 211 212 static const struct v4l2_ctrl_ops iris_ctrl_ops = { 213 .s_ctrl = iris_vdec_op_s_ctrl, 214 }; 215 216 int iris_ctrls_init(struct iris_inst *inst) 217 { 218 struct platform_inst_fw_cap *cap = &inst->fw_caps[0]; 219 u32 num_ctrls = 0, ctrl_idx = 0, idx = 0; 220 u32 v4l2_id; 221 int ret; 222 223 for (idx = 1; idx < INST_FW_CAP_MAX; idx++) { 224 if (iris_get_v4l2_id(cap[idx].cap_id)) 225 num_ctrls++; 226 } 227 228 /* Adding 1 to num_ctrls to include 229 * V4L2_CID_MIN_BUFFERS_FOR_CAPTURE for decoder and 230 * V4L2_CID_MIN_BUFFERS_FOR_OUTPUT for encoder 231 */ 232 233 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1); 234 if (ret) 235 return ret; 236 237 for (idx = 1; idx < INST_FW_CAP_MAX; idx++) { 238 struct v4l2_ctrl *ctrl; 239 240 v4l2_id = iris_get_v4l2_id(cap[idx].cap_id); 241 if (!v4l2_id) 242 continue; 243 244 if (ctrl_idx >= num_ctrls) { 245 ret = -EINVAL; 246 goto error; 247 } 248 249 if (cap[idx].flags & CAP_FLAG_MENU) { 250 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, 251 &iris_ctrl_ops, 252 v4l2_id, 253 cap[idx].max, 254 ~(cap[idx].step_or_mask), 255 cap[idx].value); 256 } else { 257 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, 258 &iris_ctrl_ops, 259 v4l2_id, 260 cap[idx].min, 261 cap[idx].max, 262 cap[idx].step_or_mask, 263 cap[idx].value); 264 } 265 if (!ctrl) { 266 ret = -EINVAL; 267 goto error; 268 } 269 270 ctrl_idx++; 271 } 272 273 if (inst->domain == DECODER) { 274 v4l2_ctrl_new_std(&inst->ctrl_handler, NULL, 275 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4); 276 } else { 277 v4l2_ctrl_new_std(&inst->ctrl_handler, NULL, 278 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 4); 279 } 280 281 ret = inst->ctrl_handler.error; 282 if (ret) 283 goto error; 284 285 return 0; 286 error: 287 v4l2_ctrl_handler_free(&inst->ctrl_handler); 288 289 return ret; 290 } 291 292 void iris_session_init_caps(struct iris_core *core) 293 { 294 struct platform_inst_fw_cap *caps; 295 u32 i, num_cap, cap_id; 296 297 caps = core->iris_platform_data->inst_fw_caps_dec; 298 num_cap = core->iris_platform_data->inst_fw_caps_dec_size; 299 300 for (i = 0; i < num_cap; i++) { 301 cap_id = caps[i].cap_id; 302 if (!iris_valid_cap_id(cap_id)) 303 continue; 304 305 core->inst_fw_caps_dec[cap_id].cap_id = caps[i].cap_id; 306 core->inst_fw_caps_dec[cap_id].min = caps[i].min; 307 core->inst_fw_caps_dec[cap_id].max = caps[i].max; 308 core->inst_fw_caps_dec[cap_id].step_or_mask = caps[i].step_or_mask; 309 core->inst_fw_caps_dec[cap_id].value = caps[i].value; 310 core->inst_fw_caps_dec[cap_id].flags = caps[i].flags; 311 core->inst_fw_caps_dec[cap_id].hfi_id = caps[i].hfi_id; 312 core->inst_fw_caps_dec[cap_id].set = caps[i].set; 313 } 314 315 caps = core->iris_platform_data->inst_fw_caps_enc; 316 num_cap = core->iris_platform_data->inst_fw_caps_enc_size; 317 318 for (i = 0; i < num_cap; i++) { 319 cap_id = caps[i].cap_id; 320 if (!iris_valid_cap_id(cap_id)) 321 continue; 322 323 core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id; 324 core->inst_fw_caps_enc[cap_id].min = caps[i].min; 325 core->inst_fw_caps_enc[cap_id].max = caps[i].max; 326 core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask; 327 core->inst_fw_caps_enc[cap_id].value = caps[i].value; 328 core->inst_fw_caps_enc[cap_id].flags = caps[i].flags; 329 core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id; 330 } 331 } 332 333 static u32 iris_get_port_info(struct iris_inst *inst, 334 enum platform_inst_fw_cap_type cap_id) 335 { 336 if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT) 337 return HFI_PORT_BITSTREAM; 338 else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT) 339 return HFI_PORT_RAW; 340 341 return HFI_PORT_NONE; 342 } 343 344 int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 345 { 346 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 347 u32 hfi_value = inst->fw_caps[cap_id].value; 348 u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 349 350 return hfi_ops->session_set_property(inst, hfi_id, 351 HFI_HOST_FLAGS_NONE, 352 iris_get_port_info(inst, cap_id), 353 HFI_PAYLOAD_U32_ENUM, 354 &hfi_value, sizeof(u32)); 355 } 356 357 int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 358 { 359 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 360 u32 hfi_value = inst->fw_caps[cap_id].value; 361 u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 362 363 return hfi_ops->session_set_property(inst, hfi_id, 364 HFI_HOST_FLAGS_NONE, 365 iris_get_port_info(inst, cap_id), 366 HFI_PAYLOAD_U32, 367 &hfi_value, sizeof(u32)); 368 } 369 370 int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 371 { 372 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 373 struct v4l2_format *inp_f = inst->fmt_src; 374 u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 375 u32 height = inp_f->fmt.pix_mp.height; 376 u32 width = inp_f->fmt.pix_mp.width; 377 u32 work_mode = STAGE_2; 378 379 if (iris_res_is_less_than(width, height, 1280, 720)) 380 work_mode = STAGE_1; 381 382 return hfi_ops->session_set_property(inst, hfi_id, 383 HFI_HOST_FLAGS_NONE, 384 iris_get_port_info(inst, cap_id), 385 HFI_PAYLOAD_U32, 386 &work_mode, sizeof(u32)); 387 } 388 389 int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) 390 { 391 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 392 u32 work_route = inst->fw_caps[PIPE].value; 393 u32 hfi_id = inst->fw_caps[cap_id].hfi_id; 394 395 return hfi_ops->session_set_property(inst, hfi_id, 396 HFI_HOST_FLAGS_NONE, 397 iris_get_port_info(inst, cap_id), 398 HFI_PAYLOAD_U32, 399 &work_route, sizeof(u32)); 400 } 401 402 int iris_set_properties(struct iris_inst *inst, u32 plane) 403 { 404 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 405 struct platform_inst_fw_cap *cap; 406 int ret; 407 u32 i; 408 409 ret = hfi_ops->session_set_config_params(inst, plane); 410 if (ret) 411 return ret; 412 413 for (i = 1; i < INST_FW_CAP_MAX; i++) { 414 cap = &inst->fw_caps[i]; 415 if (!iris_valid_cap_id(cap->cap_id)) 416 continue; 417 418 if (cap->cap_id && cap->set) 419 cap->set(inst, i); 420 } 421 422 return 0; 423 } 424