| 1 | |
| 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_hfi_gen1_defines.h"
|
| 11 | #include "iris_hfi_gen2_defines.h"
|
| 12 | #include "iris_instance.h"
|
| 13 |
|
| 14 | #define CABAC_MAX_BITRATE 160000000
|
| 15 | #define CAVLC_MAX_BITRATE 220000000
|
| 16 |
|
| 17 | static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
|
| 18 | {
|
| 19 | return cap_id >= 1 && cap_id < INST_FW_CAP_MAX;
|
| 20 | }
|
| 21 |
|
| 22 | static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
|
| 23 | {
|
| 24 | switch (id) {
|
| 25 | case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
| 26 | return PROFILE_H264;
|
| 27 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
|
| 28 | return PROFILE_HEVC;
|
| 29 | case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
|
| 30 | return PROFILE_VP9;
|
| 31 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
|
| 32 | return LEVEL_H264;
|
| 33 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
|
| 34 | return LEVEL_HEVC;
|
| 35 | case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
|
| 36 | return LEVEL_VP9;
|
| 37 | case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
|
| 38 | return TIER;
|
| 39 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
|
| 40 | return HEADER_MODE;
|
| 41 | case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
|
| 42 | return PREPEND_SPSPPS_TO_IDR;
|
| 43 | case V4L2_CID_MPEG_VIDEO_BITRATE:
|
| 44 | return BITRATE;
|
| 45 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
|
| 46 | return BITRATE_PEAK;
|
| 47 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
|
| 48 | return BITRATE_MODE;
|
| 49 | case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE:
|
| 50 | return FRAME_SKIP_MODE;
|
| 51 | case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
|
| 52 | return FRAME_RC_ENABLE;
|
| 53 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
| 54 | return GOP_SIZE;
|
| 55 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
|
| 56 | return ENTROPY_MODE;
|
| 57 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
|
| 58 | return MIN_FRAME_QP_H264;
|
| 59 | case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
|
| 60 | return MIN_FRAME_QP_HEVC;
|
| 61 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
|
| 62 | return MAX_FRAME_QP_H264;
|
| 63 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
|
| 64 | return MAX_FRAME_QP_HEVC;
|
| 65 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP:
|
| 66 | return I_FRAME_MIN_QP_H264;
|
| 67 | case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP:
|
| 68 | return I_FRAME_MIN_QP_HEVC;
|
| 69 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP:
|
| 70 | return P_FRAME_MIN_QP_H264;
|
| 71 | case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP:
|
| 72 | return P_FRAME_MIN_QP_HEVC;
|
| 73 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP:
|
| 74 | return B_FRAME_MIN_QP_H264;
|
| 75 | case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP:
|
| 76 | return B_FRAME_MIN_QP_HEVC;
|
| 77 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP:
|
| 78 | return I_FRAME_MAX_QP_H264;
|
| 79 | case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP:
|
| 80 | return I_FRAME_MAX_QP_HEVC;
|
| 81 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP:
|
| 82 | return P_FRAME_MAX_QP_H264;
|
| 83 | case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP:
|
| 84 | return P_FRAME_MAX_QP_HEVC;
|
| 85 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP:
|
| 86 | return B_FRAME_MAX_QP_H264;
|
| 87 | case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP:
|
| 88 | return B_FRAME_MAX_QP_HEVC;
|
| 89 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
|
| 90 | return I_FRAME_QP_H264;
|
| 91 | case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
|
| 92 | return I_FRAME_QP_HEVC;
|
| 93 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
|
| 94 | return P_FRAME_QP_H264;
|
| 95 | case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
|
| 96 | return P_FRAME_QP_HEVC;
|
| 97 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
|
| 98 | return B_FRAME_QP_H264;
|
| 99 | case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
|
| 100 | return B_FRAME_QP_HEVC;
|
| 101 | case V4L2_CID_MPEG_VIDEO_AV1_PROFILE:
|
| 102 | return PROFILE_AV1;
|
| 103 | case V4L2_CID_MPEG_VIDEO_AV1_LEVEL:
|
| 104 | return LEVEL_AV1;
|
| 105 | case V4L2_CID_ROTATE:
|
| 106 | return ROTATION;
|
| 107 | case V4L2_CID_HFLIP:
|
| 108 | return HFLIP;
|
| 109 | case V4L2_CID_VFLIP:
|
| 110 | return VFLIP;
|
| 111 | case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE:
|
| 112 | return IR_TYPE;
|
| 113 | case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
|
| 114 | return IR_PERIOD;
|
| 115 | case V4L2_CID_MPEG_VIDEO_LTR_COUNT:
|
| 116 | return LTR_COUNT;
|
| 117 | case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES:
|
| 118 | return USE_LTR;
|
| 119 | case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
|
| 120 | return MARK_LTR;
|
| 121 | case V4L2_CID_MPEG_VIDEO_B_FRAMES:
|
| 122 | return B_FRAME;
|
| 123 | case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
|
| 124 | return LAYER_ENABLE;
|
| 125 | case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
|
| 126 | return LAYER_TYPE_H264;
|
| 127 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
|
| 128 | return LAYER_TYPE_HEVC;
|
| 129 | case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
|
| 130 | return LAYER_COUNT_H264;
|
| 131 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
|
| 132 | return LAYER_COUNT_HEVC;
|
| 133 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR:
|
| 134 | return LAYER0_BITRATE_H264;
|
| 135 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR:
|
| 136 | return LAYER1_BITRATE_H264;
|
| 137 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR:
|
| 138 | return LAYER2_BITRATE_H264;
|
| 139 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR:
|
| 140 | return LAYER3_BITRATE_H264;
|
| 141 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR:
|
| 142 | return LAYER4_BITRATE_H264;
|
| 143 | case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR:
|
| 144 | return LAYER5_BITRATE_H264;
|
| 145 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR:
|
| 146 | return LAYER0_BITRATE_HEVC;
|
| 147 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR:
|
| 148 | return LAYER1_BITRATE_HEVC;
|
| 149 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR:
|
| 150 | return LAYER2_BITRATE_HEVC;
|
| 151 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR:
|
| 152 | return LAYER3_BITRATE_HEVC;
|
| 153 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR:
|
| 154 | return LAYER4_BITRATE_HEVC;
|
| 155 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
|
| 156 | return LAYER5_BITRATE_HEVC;
|
| 157 | case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
|
| 158 | return REQUEST_SYNC_FRAME;
|
| 159 | default:
|
| 160 | return INST_FW_CAP_MAX;
|
| 161 | }
|
| 162 | }
|
| 163 |
|
| 164 | static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
|
| 165 | {
|
| 166 | if (!iris_valid_cap_id(cap_id))
|
| 167 | return 0;
|
| 168 |
|
| 169 | switch (cap_id) {
|
| 170 | case PROFILE_H264:
|
| 171 | return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
| 172 | case PROFILE_HEVC:
|
| 173 | return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
|
| 174 | case PROFILE_VP9:
|
| 175 | return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
|
| 176 | case LEVEL_H264:
|
| 177 | return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
|
| 178 | case LEVEL_HEVC:
|
| 179 | return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
|
| 180 | case LEVEL_VP9:
|
| 181 | return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
|
| 182 | case TIER:
|
| 183 | return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
|
| 184 | case HEADER_MODE:
|
| 185 | return V4L2_CID_MPEG_VIDEO_HEADER_MODE;
|
| 186 | case PREPEND_SPSPPS_TO_IDR:
|
| 187 | return V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR;
|
| 188 | case BITRATE:
|
| 189 | return V4L2_CID_MPEG_VIDEO_BITRATE;
|
| 190 | case BITRATE_PEAK:
|
| 191 | return V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
|
| 192 | case BITRATE_MODE:
|
| 193 | return V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
|
| 194 | case FRAME_SKIP_MODE:
|
| 195 | return V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE;
|
| 196 | case FRAME_RC_ENABLE:
|
| 197 | return V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
|
| 198 | case GOP_SIZE:
|
| 199 | return V4L2_CID_MPEG_VIDEO_GOP_SIZE;
|
| 200 | case ENTROPY_MODE:
|
| 201 | return V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
|
| 202 | case MIN_FRAME_QP_H264:
|
| 203 | return V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
|
| 204 | case MIN_FRAME_QP_HEVC:
|
| 205 | return V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
|
| 206 | case MAX_FRAME_QP_H264:
|
| 207 | return V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
|
| 208 | case MAX_FRAME_QP_HEVC:
|
| 209 | return V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
|
| 210 | case I_FRAME_MIN_QP_H264:
|
| 211 | return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP;
|
| 212 | case I_FRAME_MIN_QP_HEVC:
|
| 213 | return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP;
|
| 214 | case P_FRAME_MIN_QP_H264:
|
| 215 | return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP;
|
| 216 | case P_FRAME_MIN_QP_HEVC:
|
| 217 | return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP;
|
| 218 | case B_FRAME_MIN_QP_H264:
|
| 219 | return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP;
|
| 220 | case B_FRAME_MIN_QP_HEVC:
|
| 221 | return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP;
|
| 222 | case I_FRAME_MAX_QP_H264:
|
| 223 | return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP;
|
| 224 | case I_FRAME_MAX_QP_HEVC:
|
| 225 | return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP;
|
| 226 | case P_FRAME_MAX_QP_H264:
|
| 227 | return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP;
|
| 228 | case P_FRAME_MAX_QP_HEVC:
|
| 229 | return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP;
|
| 230 | case B_FRAME_MAX_QP_H264:
|
| 231 | return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP;
|
| 232 | case B_FRAME_MAX_QP_HEVC:
|
| 233 | return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP;
|
| 234 | case I_FRAME_QP_H264:
|
| 235 | return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
|
| 236 | case I_FRAME_QP_HEVC:
|
| 237 | return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP;
|
| 238 | case P_FRAME_QP_H264:
|
| 239 | return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
|
| 240 | case P_FRAME_QP_HEVC:
|
| 241 | return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP;
|
| 242 | case B_FRAME_QP_H264:
|
| 243 | return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
|
| 244 | case B_FRAME_QP_HEVC:
|
| 245 | return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP;
|
| 246 | case PROFILE_AV1:
|
| 247 | return V4L2_CID_MPEG_VIDEO_AV1_PROFILE;
|
| 248 | case LEVEL_AV1:
|
| 249 | return V4L2_CID_MPEG_VIDEO_AV1_LEVEL;
|
| 250 | case ROTATION:
|
| 251 | return V4L2_CID_ROTATE;
|
| 252 | case HFLIP:
|
| 253 | return V4L2_CID_HFLIP;
|
| 254 | case VFLIP:
|
| 255 | return V4L2_CID_VFLIP;
|
| 256 | case IR_TYPE:
|
| 257 | return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE;
|
| 258 | case IR_PERIOD:
|
| 259 | return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD;
|
| 260 | case LTR_COUNT:
|
| 261 | return V4L2_CID_MPEG_VIDEO_LTR_COUNT;
|
| 262 | case USE_LTR:
|
| 263 | return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
|
| 264 | case MARK_LTR:
|
| 265 | return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
|
| 266 | case B_FRAME:
|
| 267 | return V4L2_CID_MPEG_VIDEO_B_FRAMES;
|
| 268 | case LAYER_ENABLE:
|
| 269 | return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
|
| 270 | case LAYER_TYPE_H264:
|
| 271 | return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
|
| 272 | case LAYER_TYPE_HEVC:
|
| 273 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE;
|
| 274 | case LAYER_COUNT_H264:
|
| 275 | return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
|
| 276 | case LAYER_COUNT_HEVC:
|
| 277 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER;
|
| 278 | case LAYER0_BITRATE_H264:
|
| 279 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR;
|
| 280 | case LAYER1_BITRATE_H264:
|
| 281 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR;
|
| 282 | case LAYER2_BITRATE_H264:
|
| 283 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR;
|
| 284 | case LAYER3_BITRATE_H264:
|
| 285 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR;
|
| 286 | case LAYER4_BITRATE_H264:
|
| 287 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR;
|
| 288 | case LAYER5_BITRATE_H264:
|
| 289 | return V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR;
|
| 290 | case LAYER0_BITRATE_HEVC:
|
| 291 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR;
|
| 292 | case LAYER1_BITRATE_HEVC:
|
| 293 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR;
|
| 294 | case LAYER2_BITRATE_HEVC:
|
| 295 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR;
|
| 296 | case LAYER3_BITRATE_HEVC:
|
| 297 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR;
|
| 298 | case LAYER4_BITRATE_HEVC:
|
| 299 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR;
|
| 300 | case LAYER5_BITRATE_HEVC:
|
| 301 | return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR;
|
| 302 | case REQUEST_SYNC_FRAME:
|
| 303 | return V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME;
|
| 304 | default:
|
| 305 | return 0;
|
| 306 | }
|
| 307 | }
|
| 308 |
|
| 309 | static int iris_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
| 310 | {
|
| 311 | struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
|
| 312 | enum platform_inst_fw_cap_type cap_id;
|
| 313 | struct platform_inst_fw_cap *cap;
|
| 314 | struct vb2_queue *q;
|
| 315 |
|
| 316 | cap = &inst->fw_caps[0];
|
| 317 | cap_id = iris_get_cap_id(ctrl->id);
|
| 318 | if (!iris_valid_cap_id(cap_id))
|
| 319 | return -EINVAL;
|
| 320 |
|
| 321 | q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 322 | if (vb2_is_streaming(q) &&
|
| 323 | (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)))
|
| 324 | return -EINVAL;
|
| 325 |
|
| 326 | cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
|
| 327 |
|
| 328 | inst->fw_caps[cap_id].value = ctrl->val;
|
| 329 |
|
| 330 | if (vb2_is_streaming(q)) {
|
| 331 | if (cap[cap_id].set)
|
| 332 | cap[cap_id].set(inst, cap_id);
|
| 333 | }
|
| 334 |
|
| 335 | return 0;
|
| 336 | }
|
| 337 |
|
| 338 | static const struct v4l2_ctrl_ops iris_ctrl_ops = {
|
| 339 | .s_ctrl = iris_op_s_ctrl,
|
| 340 | };
|
| 341 |
|
| 342 | int iris_ctrls_init(struct iris_inst *inst)
|
| 343 | {
|
| 344 | struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
|
| 345 | u32 num_ctrls = 0, ctrl_idx = 0, idx = 0;
|
| 346 | u32 v4l2_id;
|
| 347 | int ret;
|
| 348 |
|
| 349 | for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
|
| 350 | if (iris_get_v4l2_id(cap[idx].cap_id))
|
| 351 | num_ctrls++;
|
| 352 | }
|
| 353 |
|
| 354 | |
| 355 | * V4L2_CID_MIN_BUFFERS_FOR_CAPTURE for decoder and
|
| 356 | * V4L2_CID_MIN_BUFFERS_FOR_OUTPUT for encoder
|
| 357 |
|
| 358 |
|
| 359 | ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
|
| 360 | if (ret)
|
| 361 | return ret;
|
| 362 |
|
| 363 | for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
|
| 364 | struct v4l2_ctrl *ctrl;
|
| 365 |
|
| 366 | v4l2_id = iris_get_v4l2_id(cap[idx].cap_id);
|
| 367 | if (!v4l2_id)
|
| 368 | continue;
|
| 369 |
|
| 370 | if (ctrl_idx >= num_ctrls) {
|
| 371 | ret = -EINVAL;
|
| 372 | goto error;
|
| 373 | }
|
| 374 |
|
| 375 | if (cap[idx].flags & CAP_FLAG_MENU) {
|
| 376 | ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
|
| 377 | &iris_ctrl_ops,
|
| 378 | v4l2_id,
|
| 379 | cap[idx].max,
|
| 380 | ~(cap[idx].step_or_mask),
|
| 381 | cap[idx].value);
|
| 382 | } else {
|
| 383 | ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
|
| 384 | &iris_ctrl_ops,
|
| 385 | v4l2_id,
|
| 386 | cap[idx].min,
|
| 387 | cap[idx].max,
|
| 388 | cap[idx].step_or_mask,
|
| 389 | cap[idx].value);
|
| 390 | }
|
| 391 | if (!ctrl) {
|
| 392 | ret = -EINVAL;
|
| 393 | goto error;
|
| 394 | }
|
| 395 |
|
| 396 | ctrl_idx++;
|
| 397 | }
|
| 398 |
|
| 399 | if (inst->domain == DECODER) {
|
| 400 | v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
|
| 401 | V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
|
| 402 | } else {
|
| 403 | v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
|
| 404 | V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 4);
|
| 405 | }
|
| 406 |
|
| 407 | ret = inst->ctrl_handler.error;
|
| 408 | if (ret)
|
| 409 | goto error;
|
| 410 |
|
| 411 | return 0;
|
| 412 | error:
|
| 413 | v4l2_ctrl_handler_free(&inst->ctrl_handler);
|
| 414 |
|
| 415 | return ret;
|
| 416 | }
|
| 417 |
|
| 418 | void iris_session_init_caps(struct iris_core *core)
|
| 419 | {
|
| 420 | const struct platform_inst_fw_cap *caps;
|
| 421 | u32 i, num_cap, cap_id;
|
| 422 |
|
| 423 | caps = core->iris_firmware_data->inst_fw_caps_dec;
|
| 424 | num_cap = core->iris_firmware_data->inst_fw_caps_dec_size;
|
| 425 |
|
| 426 | for (i = 0; i < num_cap; i++) {
|
| 427 | cap_id = caps[i].cap_id;
|
| 428 | if (!iris_valid_cap_id(cap_id))
|
| 429 | continue;
|
| 430 |
|
| 431 | core->inst_fw_caps_dec[cap_id].cap_id = caps[i].cap_id;
|
| 432 | core->inst_fw_caps_dec[cap_id].step_or_mask = caps[i].step_or_mask;
|
| 433 | core->inst_fw_caps_dec[cap_id].flags = caps[i].flags;
|
| 434 | core->inst_fw_caps_dec[cap_id].hfi_id = caps[i].hfi_id;
|
| 435 | core->inst_fw_caps_dec[cap_id].set = caps[i].set;
|
| 436 |
|
| 437 | if (cap_id == PIPE) {
|
| 438 | core->inst_fw_caps_dec[cap_id].value =
|
| 439 | core->iris_platform_data->num_vpp_pipe;
|
| 440 | core->inst_fw_caps_dec[cap_id].min =
|
| 441 | core->iris_platform_data->num_vpp_pipe;
|
| 442 | core->inst_fw_caps_dec[cap_id].max =
|
| 443 | core->iris_platform_data->num_vpp_pipe;
|
| 444 | } else {
|
| 445 | core->inst_fw_caps_dec[cap_id].min = caps[i].min;
|
| 446 | core->inst_fw_caps_dec[cap_id].max = caps[i].max;
|
| 447 | core->inst_fw_caps_dec[cap_id].value = caps[i].value;
|
| 448 | }
|
| 449 | }
|
| 450 |
|
| 451 | caps = core->iris_firmware_data->inst_fw_caps_enc;
|
| 452 | num_cap = core->iris_firmware_data->inst_fw_caps_enc_size;
|
| 453 |
|
| 454 | for (i = 0; i < num_cap; i++) {
|
| 455 | cap_id = caps[i].cap_id;
|
| 456 | if (!iris_valid_cap_id(cap_id))
|
| 457 | continue;
|
| 458 |
|
| 459 | core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
|
| 460 | core->inst_fw_caps_enc[cap_id].min = caps[i].min;
|
| 461 | core->inst_fw_caps_enc[cap_id].max = caps[i].max;
|
| 462 | core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
|
| 463 | core->inst_fw_caps_enc[cap_id].value = caps[i].value;
|
| 464 | core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
|
| 465 | core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
|
| 466 | core->inst_fw_caps_enc[cap_id].set = caps[i].set;
|
| 467 | }
|
| 468 | }
|
| 469 |
|
| 470 | static u32 iris_get_port_info(struct iris_inst *inst,
|
| 471 | enum platform_inst_fw_cap_type cap_id)
|
| 472 | {
|
| 473 | if (inst->domain == DECODER) {
|
| 474 | if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
|
| 475 | return HFI_PORT_BITSTREAM;
|
| 476 | else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
|
| 477 | return HFI_PORT_RAW;
|
| 478 | } else {
|
| 479 | if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
|
| 480 | return HFI_PORT_RAW;
|
| 481 | else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
|
| 482 | return HFI_PORT_BITSTREAM;
|
| 483 | }
|
| 484 |
|
| 485 | return HFI_PORT_NONE;
|
| 486 | }
|
| 487 |
|
| 488 | int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 489 | {
|
| 490 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 491 | u32 hfi_value = inst->fw_caps[cap_id].value;
|
| 492 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 493 |
|
| 494 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 495 | HFI_HOST_FLAGS_NONE,
|
| 496 | iris_get_port_info(inst, cap_id),
|
| 497 | HFI_PAYLOAD_U32_ENUM,
|
| 498 | &hfi_value, sizeof(u32));
|
| 499 | }
|
| 500 |
|
| 501 | int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 502 | {
|
| 503 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 504 | u32 hfi_value = inst->fw_caps[cap_id].value;
|
| 505 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 506 |
|
| 507 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 508 | HFI_HOST_FLAGS_NONE,
|
| 509 | iris_get_port_info(inst, cap_id),
|
| 510 | HFI_PAYLOAD_U32,
|
| 511 | &hfi_value, sizeof(u32));
|
| 512 | }
|
| 513 |
|
| 514 | int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 515 | {
|
| 516 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 517 | struct v4l2_format *inp_f = inst->fmt_src;
|
| 518 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 519 | u32 height = inp_f->fmt.pix_mp.height;
|
| 520 | u32 width = inp_f->fmt.pix_mp.width;
|
| 521 | u32 work_mode = STAGE_2;
|
| 522 |
|
| 523 | if (inst->domain == DECODER) {
|
| 524 | if (iris_res_is_less_than(width, height, 1280, 720))
|
| 525 | work_mode = STAGE_1;
|
| 526 | }
|
| 527 |
|
| 528 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 529 | HFI_HOST_FLAGS_NONE,
|
| 530 | iris_get_port_info(inst, cap_id),
|
| 531 | HFI_PAYLOAD_U32,
|
| 532 | &work_mode, sizeof(u32));
|
| 533 | }
|
| 534 |
|
| 535 | int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 536 | {
|
| 537 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 538 | u32 work_route = inst->fw_caps[PIPE].value;
|
| 539 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 540 |
|
| 541 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 542 | HFI_HOST_FLAGS_NONE,
|
| 543 | iris_get_port_info(inst, cap_id),
|
| 544 | HFI_PAYLOAD_U32,
|
| 545 | &work_route, sizeof(u32));
|
| 546 | }
|
| 547 |
|
| 548 | int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 549 | {
|
| 550 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 551 | u32 hfi_id, hfi_value;
|
| 552 |
|
| 553 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 554 | hfi_id = inst->fw_caps[PROFILE_H264].hfi_id;
|
| 555 | hfi_value = inst->fw_caps[PROFILE_H264].value;
|
| 556 | } else {
|
| 557 | hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
|
| 558 | hfi_value = inst->fw_caps[PROFILE_HEVC].value;
|
| 559 | }
|
| 560 |
|
| 561 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 562 | HFI_HOST_FLAGS_NONE,
|
| 563 | iris_get_port_info(inst, cap_id),
|
| 564 | HFI_PAYLOAD_U32_ENUM,
|
| 565 | &hfi_value, sizeof(u32));
|
| 566 | }
|
| 567 |
|
| 568 | int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 569 | {
|
| 570 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 571 | u32 hfi_id, hfi_value;
|
| 572 |
|
| 573 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 574 | hfi_id = inst->fw_caps[LEVEL_H264].hfi_id;
|
| 575 | hfi_value = inst->fw_caps[LEVEL_H264].value;
|
| 576 | } else {
|
| 577 | hfi_id = inst->fw_caps[LEVEL_HEVC].hfi_id;
|
| 578 | hfi_value = inst->fw_caps[LEVEL_HEVC].value;
|
| 579 | }
|
| 580 |
|
| 581 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 582 | HFI_HOST_FLAGS_NONE,
|
| 583 | iris_get_port_info(inst, cap_id),
|
| 584 | HFI_PAYLOAD_U32_ENUM,
|
| 585 | &hfi_value, sizeof(u32));
|
| 586 | }
|
| 587 |
|
| 588 | int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 589 | {
|
| 590 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 591 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 592 | struct hfi_profile_level pl;
|
| 593 |
|
| 594 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 595 | pl.profile = inst->fw_caps[PROFILE_H264].value;
|
| 596 | pl.level = inst->fw_caps[LEVEL_H264].value;
|
| 597 | } else {
|
| 598 | pl.profile = inst->fw_caps[PROFILE_HEVC].value;
|
| 599 | pl.level = inst->fw_caps[LEVEL_HEVC].value;
|
| 600 | }
|
| 601 |
|
| 602 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 603 | HFI_HOST_FLAGS_NONE,
|
| 604 | iris_get_port_info(inst, cap_id),
|
| 605 | HFI_PAYLOAD_U32_ENUM,
|
| 606 | &pl, sizeof(u32));
|
| 607 | }
|
| 608 |
|
| 609 | int iris_set_header_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 610 | {
|
| 611 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 612 | u32 header_mode = inst->fw_caps[cap_id].value;
|
| 613 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 614 | u32 hfi_val;
|
| 615 |
|
| 616 | if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)
|
| 617 | hfi_val = 0;
|
| 618 | else
|
| 619 | hfi_val = 1;
|
| 620 |
|
| 621 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 622 | HFI_HOST_FLAGS_NONE,
|
| 623 | iris_get_port_info(inst, cap_id),
|
| 624 | HFI_PAYLOAD_U32,
|
| 625 | &hfi_val, sizeof(u32));
|
| 626 | }
|
| 627 |
|
| 628 | int iris_set_header_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 629 | {
|
| 630 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 631 | u32 prepend_sps_pps = inst->fw_caps[PREPEND_SPSPPS_TO_IDR].value;
|
| 632 | u32 header_mode = inst->fw_caps[cap_id].value;
|
| 633 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 634 | u32 hfi_val;
|
| 635 |
|
| 636 | if (prepend_sps_pps)
|
| 637 | hfi_val = HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME;
|
| 638 | else if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)
|
| 639 | hfi_val = HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME;
|
| 640 | else
|
| 641 | hfi_val = HFI_SEQ_HEADER_SEPERATE_FRAME;
|
| 642 |
|
| 643 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 644 | HFI_HOST_FLAGS_NONE,
|
| 645 | iris_get_port_info(inst, cap_id),
|
| 646 | HFI_PAYLOAD_U32_ENUM,
|
| 647 | &hfi_val, sizeof(u32));
|
| 648 | }
|
| 649 |
|
| 650 | int iris_set_bitrate_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 651 | {
|
| 652 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 653 | u32 entropy_mode = inst->fw_caps[ENTROPY_MODE].value;
|
| 654 | u32 bitrate = inst->fw_caps[cap_id].value;
|
| 655 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 656 | struct hfi_bitrate hfi_val;
|
| 657 | u32 max_bitrate;
|
| 658 |
|
| 659 | if (!(inst->fw_caps[cap_id].flags & CAP_FLAG_CLIENT_SET) && cap_id != BITRATE)
|
| 660 | return -EINVAL;
|
| 661 |
|
| 662 | if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
| 663 | max_bitrate = CABAC_MAX_BITRATE;
|
| 664 | } else {
|
| 665 | if (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
|
| 666 | max_bitrate = CABAC_MAX_BITRATE;
|
| 667 | else
|
| 668 | max_bitrate = CAVLC_MAX_BITRATE;
|
| 669 | }
|
| 670 |
|
| 671 | hfi_val.bitrate = min(bitrate, max_bitrate);
|
| 672 |
|
| 673 | switch (cap_id) {
|
| 674 | case BITRATE:
|
| 675 | case LAYER0_BITRATE_H264:
|
| 676 | hfi_val.layer_id = 0;
|
| 677 | break;
|
| 678 | case LAYER1_BITRATE_H264:
|
| 679 | hfi_val.layer_id = 1;
|
| 680 | break;
|
| 681 | case LAYER2_BITRATE_H264:
|
| 682 | hfi_val.layer_id = 2;
|
| 683 | break;
|
| 684 | case LAYER3_BITRATE_H264:
|
| 685 | hfi_val.layer_id = 3;
|
| 686 | break;
|
| 687 | case LAYER4_BITRATE_H264:
|
| 688 | hfi_val.layer_id = 4;
|
| 689 | break;
|
| 690 | case LAYER5_BITRATE_H264:
|
| 691 | hfi_val.layer_id = 5;
|
| 692 | break;
|
| 693 | default:
|
| 694 | return -EINVAL;
|
| 695 | }
|
| 696 |
|
| 697 | if (hfi_val.layer_id > 0 && !inst->fw_caps[LAYER_ENABLE].value)
|
| 698 | return -EINVAL;
|
| 699 |
|
| 700 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 701 | HFI_HOST_FLAGS_NONE,
|
| 702 | iris_get_port_info(inst, cap_id),
|
| 703 | HFI_PAYLOAD_STRUCTURE,
|
| 704 | &hfi_val, sizeof(hfi_val));
|
| 705 | }
|
| 706 |
|
| 707 | int iris_set_bitrate_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 708 | {
|
| 709 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 710 | u32 entropy_mode = inst->fw_caps[ENTROPY_MODE].value;
|
| 711 | u32 bitrate = inst->fw_caps[cap_id].value;
|
| 712 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 713 | u32 max_bitrate;
|
| 714 |
|
| 715 | if (inst->codec == V4L2_PIX_FMT_HEVC)
|
| 716 | max_bitrate = CABAC_MAX_BITRATE;
|
| 717 |
|
| 718 | if (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
|
| 719 | max_bitrate = CABAC_MAX_BITRATE;
|
| 720 | else
|
| 721 | max_bitrate = CAVLC_MAX_BITRATE;
|
| 722 |
|
| 723 | bitrate = min(bitrate, max_bitrate);
|
| 724 |
|
| 725 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 726 | HFI_HOST_FLAGS_NONE,
|
| 727 | iris_get_port_info(inst, cap_id),
|
| 728 | HFI_PAYLOAD_U32,
|
| 729 | &bitrate, sizeof(u32));
|
| 730 | }
|
| 731 |
|
| 732 | int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 733 | {
|
| 734 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 735 | u32 rc_mode = inst->fw_caps[BITRATE_MODE].value;
|
| 736 | u32 peak_bitrate = inst->fw_caps[cap_id].value;
|
| 737 | u32 bitrate = inst->fw_caps[BITRATE].value;
|
| 738 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 739 |
|
| 740 | if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
|
| 741 | return 0;
|
| 742 |
|
| 743 | if (inst->fw_caps[cap_id].flags & CAP_FLAG_CLIENT_SET) {
|
| 744 | if (peak_bitrate < bitrate)
|
| 745 | peak_bitrate = bitrate;
|
| 746 | } else {
|
| 747 | peak_bitrate = bitrate;
|
| 748 | }
|
| 749 |
|
| 750 | inst->fw_caps[cap_id].value = peak_bitrate;
|
| 751 |
|
| 752 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 753 | HFI_HOST_FLAGS_NONE,
|
| 754 | iris_get_port_info(inst, cap_id),
|
| 755 | HFI_PAYLOAD_U32,
|
| 756 | &peak_bitrate, sizeof(u32));
|
| 757 | }
|
| 758 |
|
| 759 | int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 760 | {
|
| 761 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 762 | u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
|
| 763 | u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
|
| 764 | u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value;
|
| 765 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 766 | u32 rc_mode = 0;
|
| 767 |
|
| 768 | if (!frame_rc)
|
| 769 | rc_mode = HFI_RATE_CONTROL_OFF;
|
| 770 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
|
| 771 | rc_mode = frame_skip ? HFI_RATE_CONTROL_VBR_VFR : HFI_RATE_CONTROL_VBR_CFR;
|
| 772 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
|
| 773 | rc_mode = frame_skip ? HFI_RATE_CONTROL_CBR_VFR : HFI_RATE_CONTROL_CBR_CFR;
|
| 774 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
|
| 775 | rc_mode = HFI_RATE_CONTROL_CQ;
|
| 776 |
|
| 777 | inst->hfi_rc_type = rc_mode;
|
| 778 |
|
| 779 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 780 | HFI_HOST_FLAGS_NONE,
|
| 781 | iris_get_port_info(inst, cap_id),
|
| 782 | HFI_PAYLOAD_U32_ENUM,
|
| 783 | &rc_mode, sizeof(u32));
|
| 784 | }
|
| 785 |
|
| 786 | int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 787 | {
|
| 788 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 789 | u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
|
| 790 | u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
|
| 791 | u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value;
|
| 792 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 793 | u32 rc_mode = 0;
|
| 794 |
|
| 795 | if (!frame_rc)
|
| 796 | rc_mode = HFI_RC_OFF;
|
| 797 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
|
| 798 | rc_mode = HFI_RC_VBR_CFR;
|
| 799 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
|
| 800 | rc_mode = frame_skip ? HFI_RC_CBR_VFR : HFI_RC_CBR_CFR;
|
| 801 | else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
|
| 802 | rc_mode = HFI_RC_CQ;
|
| 803 |
|
| 804 | inst->hfi_rc_type = rc_mode;
|
| 805 |
|
| 806 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 807 | HFI_HOST_FLAGS_NONE,
|
| 808 | iris_get_port_info(inst, cap_id),
|
| 809 | HFI_PAYLOAD_U32_ENUM,
|
| 810 | &rc_mode, sizeof(u32));
|
| 811 | }
|
| 812 |
|
| 813 | int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 814 | {
|
| 815 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 816 | u32 entropy_mode = inst->fw_caps[cap_id].value;
|
| 817 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 818 | u32 hfi_val;
|
| 819 |
|
| 820 | if (inst->codec != V4L2_PIX_FMT_H264)
|
| 821 | return 0;
|
| 822 |
|
| 823 | hfi_val = (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) ?
|
| 824 | HFI_H264_ENTROPY_CAVLC : HFI_H264_ENTROPY_CABAC;
|
| 825 |
|
| 826 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 827 | HFI_HOST_FLAGS_NONE,
|
| 828 | iris_get_port_info(inst, cap_id),
|
| 829 | HFI_PAYLOAD_U32,
|
| 830 | &hfi_val, sizeof(u32));
|
| 831 | }
|
| 832 |
|
| 833 | int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 834 | {
|
| 835 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 836 | u32 entropy_mode = inst->fw_caps[cap_id].value;
|
| 837 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 838 | u32 profile;
|
| 839 |
|
| 840 | if (inst->codec != V4L2_PIX_FMT_H264)
|
| 841 | return 0;
|
| 842 |
|
| 843 | profile = inst->fw_caps[PROFILE_H264].value;
|
| 844 |
|
| 845 | if (profile == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE ||
|
| 846 | profile == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
|
| 847 | entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
|
| 848 |
|
| 849 | inst->fw_caps[cap_id].value = entropy_mode;
|
| 850 |
|
| 851 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 852 | HFI_HOST_FLAGS_NONE,
|
| 853 | iris_get_port_info(inst, cap_id),
|
| 854 | HFI_PAYLOAD_U32,
|
| 855 | &entropy_mode, sizeof(u32));
|
| 856 | }
|
| 857 |
|
| 858 | int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 859 | {
|
| 860 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 861 | u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
|
| 862 | u32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0;
|
| 863 | u32 min_qp_enable = 0, client_qp_enable = 0;
|
| 864 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 865 | u32 hfi_val;
|
| 866 |
|
| 867 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 868 | if (inst->fw_caps[MIN_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
|
| 869 | min_qp_enable = 1;
|
| 870 | if (min_qp_enable ||
|
| 871 | (inst->fw_caps[I_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 872 | i_qp_enable = 1;
|
| 873 | if (min_qp_enable ||
|
| 874 | (inst->fw_caps[P_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 875 | p_qp_enable = 1;
|
| 876 | if (min_qp_enable ||
|
| 877 | (inst->fw_caps[B_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 878 | b_qp_enable = 1;
|
| 879 | } else {
|
| 880 | if (inst->fw_caps[MIN_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
|
| 881 | min_qp_enable = 1;
|
| 882 | if (min_qp_enable ||
|
| 883 | (inst->fw_caps[I_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 884 | i_qp_enable = 1;
|
| 885 | if (min_qp_enable ||
|
| 886 | (inst->fw_caps[P_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 887 | p_qp_enable = 1;
|
| 888 | if (min_qp_enable ||
|
| 889 | (inst->fw_caps[B_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 890 | b_qp_enable = 1;
|
| 891 | }
|
| 892 |
|
| 893 | client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
|
| 894 | if (!client_qp_enable)
|
| 895 | return 0;
|
| 896 |
|
| 897 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 898 | i_frame_qp = max(inst->fw_caps[I_FRAME_MIN_QP_H264].value,
|
| 899 | inst->fw_caps[MIN_FRAME_QP_H264].value);
|
| 900 | p_frame_qp = max(inst->fw_caps[P_FRAME_MIN_QP_H264].value,
|
| 901 | inst->fw_caps[MIN_FRAME_QP_H264].value);
|
| 902 | b_frame_qp = max(inst->fw_caps[B_FRAME_MIN_QP_H264].value,
|
| 903 | inst->fw_caps[MIN_FRAME_QP_H264].value);
|
| 904 | } else {
|
| 905 | i_frame_qp = max(inst->fw_caps[I_FRAME_MIN_QP_HEVC].value,
|
| 906 | inst->fw_caps[MIN_FRAME_QP_HEVC].value);
|
| 907 | p_frame_qp = max(inst->fw_caps[P_FRAME_MIN_QP_HEVC].value,
|
| 908 | inst->fw_caps[MIN_FRAME_QP_HEVC].value);
|
| 909 | b_frame_qp = max(inst->fw_caps[B_FRAME_MIN_QP_HEVC].value,
|
| 910 | inst->fw_caps[MIN_FRAME_QP_HEVC].value);
|
| 911 | }
|
| 912 |
|
| 913 | hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 | client_qp_enable << 24;
|
| 914 |
|
| 915 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 916 | HFI_HOST_FLAGS_NONE,
|
| 917 | iris_get_port_info(inst, cap_id),
|
| 918 | HFI_PAYLOAD_32_PACKED,
|
| 919 | &hfi_val, sizeof(u32));
|
| 920 | }
|
| 921 |
|
| 922 | int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 923 | {
|
| 924 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 925 | u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
|
| 926 | u32 max_qp_enable = 0, client_qp_enable;
|
| 927 | u32 i_frame_qp, p_frame_qp, b_frame_qp;
|
| 928 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 929 | u32 hfi_val;
|
| 930 |
|
| 931 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 932 | if (inst->fw_caps[MAX_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
|
| 933 | max_qp_enable = 1;
|
| 934 | if (max_qp_enable ||
|
| 935 | (inst->fw_caps[I_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 936 | i_qp_enable = 1;
|
| 937 | if (max_qp_enable ||
|
| 938 | (inst->fw_caps[P_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 939 | p_qp_enable = 1;
|
| 940 | if (max_qp_enable ||
|
| 941 | (inst->fw_caps[B_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
|
| 942 | b_qp_enable = 1;
|
| 943 | } else {
|
| 944 | if (inst->fw_caps[MAX_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
|
| 945 | max_qp_enable = 1;
|
| 946 | if (max_qp_enable ||
|
| 947 | (inst->fw_caps[I_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 948 | i_qp_enable = 1;
|
| 949 | if (max_qp_enable ||
|
| 950 | (inst->fw_caps[P_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 951 | p_qp_enable = 1;
|
| 952 | if (max_qp_enable ||
|
| 953 | (inst->fw_caps[B_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
|
| 954 | b_qp_enable = 1;
|
| 955 | }
|
| 956 |
|
| 957 | client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
|
| 958 | if (!client_qp_enable)
|
| 959 | return 0;
|
| 960 |
|
| 961 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 962 | i_frame_qp = min(inst->fw_caps[I_FRAME_MAX_QP_H264].value,
|
| 963 | inst->fw_caps[MAX_FRAME_QP_H264].value);
|
| 964 | p_frame_qp = min(inst->fw_caps[P_FRAME_MAX_QP_H264].value,
|
| 965 | inst->fw_caps[MAX_FRAME_QP_H264].value);
|
| 966 | b_frame_qp = min(inst->fw_caps[B_FRAME_MAX_QP_H264].value,
|
| 967 | inst->fw_caps[MAX_FRAME_QP_H264].value);
|
| 968 | } else {
|
| 969 | i_frame_qp = min(inst->fw_caps[I_FRAME_MAX_QP_HEVC].value,
|
| 970 | inst->fw_caps[MAX_FRAME_QP_HEVC].value);
|
| 971 | p_frame_qp = min(inst->fw_caps[P_FRAME_MAX_QP_HEVC].value,
|
| 972 | inst->fw_caps[MAX_FRAME_QP_HEVC].value);
|
| 973 | b_frame_qp = min(inst->fw_caps[B_FRAME_MAX_QP_HEVC].value,
|
| 974 | inst->fw_caps[MAX_FRAME_QP_HEVC].value);
|
| 975 | }
|
| 976 |
|
| 977 | hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
|
| 978 | client_qp_enable << 24;
|
| 979 |
|
| 980 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 981 | HFI_HOST_FLAGS_NONE,
|
| 982 | iris_get_port_info(inst, cap_id),
|
| 983 | HFI_PAYLOAD_32_PACKED,
|
| 984 | &hfi_val, sizeof(u32));
|
| 985 | }
|
| 986 |
|
| 987 | int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 988 | {
|
| 989 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 990 | u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0, client_qp_enable;
|
| 991 | u32 i_frame_qp, p_frame_qp, b_frame_qp;
|
| 992 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 993 | struct vb2_queue *q;
|
| 994 | u32 hfi_val;
|
| 995 |
|
| 996 | q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 997 | if (vb2_is_streaming(q)) {
|
| 998 | if (inst->hfi_rc_type != HFI_RC_OFF)
|
| 999 | return 0;
|
| 1000 | }
|
| 1001 |
|
| 1002 | if (inst->hfi_rc_type == HFI_RC_OFF) {
|
| 1003 | i_qp_enable = 1;
|
| 1004 | p_qp_enable = 1;
|
| 1005 | b_qp_enable = 1;
|
| 1006 | } else {
|
| 1007 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 1008 | if (inst->fw_caps[I_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
|
| 1009 | i_qp_enable = 1;
|
| 1010 | if (inst->fw_caps[P_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
|
| 1011 | p_qp_enable = 1;
|
| 1012 | if (inst->fw_caps[B_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
|
| 1013 | b_qp_enable = 1;
|
| 1014 | } else {
|
| 1015 | if (inst->fw_caps[I_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
|
| 1016 | i_qp_enable = 1;
|
| 1017 | if (inst->fw_caps[P_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
|
| 1018 | p_qp_enable = 1;
|
| 1019 | if (inst->fw_caps[B_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
|
| 1020 | b_qp_enable = 1;
|
| 1021 | }
|
| 1022 | }
|
| 1023 |
|
| 1024 | client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
|
| 1025 | if (!client_qp_enable)
|
| 1026 | return 0;
|
| 1027 |
|
| 1028 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 1029 | i_frame_qp = inst->fw_caps[I_FRAME_QP_H264].value;
|
| 1030 | p_frame_qp = inst->fw_caps[P_FRAME_QP_H264].value;
|
| 1031 | b_frame_qp = inst->fw_caps[B_FRAME_QP_H264].value;
|
| 1032 | } else {
|
| 1033 | i_frame_qp = inst->fw_caps[I_FRAME_QP_HEVC].value;
|
| 1034 | p_frame_qp = inst->fw_caps[P_FRAME_QP_HEVC].value;
|
| 1035 | b_frame_qp = inst->fw_caps[B_FRAME_QP_HEVC].value;
|
| 1036 | }
|
| 1037 |
|
| 1038 | hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
|
| 1039 | client_qp_enable << 24;
|
| 1040 |
|
| 1041 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1042 | HFI_HOST_FLAGS_NONE,
|
| 1043 | iris_get_port_info(inst, cap_id),
|
| 1044 | HFI_PAYLOAD_32_PACKED,
|
| 1045 | &hfi_val, sizeof(u32));
|
| 1046 | }
|
| 1047 |
|
| 1048 | int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1049 | {
|
| 1050 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1051 | struct hfi_quantization_range_v2 range;
|
| 1052 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1053 |
|
| 1054 | if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
| 1055 | range.min_qp.qp_packed = inst->fw_caps[MIN_FRAME_QP_HEVC].value;
|
| 1056 | range.max_qp.qp_packed = inst->fw_caps[MAX_FRAME_QP_HEVC].value;
|
| 1057 | } else {
|
| 1058 | range.min_qp.qp_packed = inst->fw_caps[MIN_FRAME_QP_H264].value;
|
| 1059 | range.max_qp.qp_packed = inst->fw_caps[MAX_FRAME_QP_H264].value;
|
| 1060 | }
|
| 1061 |
|
| 1062 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1063 | HFI_HOST_FLAGS_NONE,
|
| 1064 | iris_get_port_info(inst, cap_id),
|
| 1065 | HFI_PAYLOAD_32_PACKED,
|
| 1066 | &range, sizeof(range));
|
| 1067 | }
|
| 1068 |
|
| 1069 | int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1070 | {
|
| 1071 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1072 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1073 | u32 hfi_val;
|
| 1074 |
|
| 1075 | switch (inst->fw_caps[cap_id].value) {
|
| 1076 | case 0:
|
| 1077 | hfi_val = HFI_ROTATION_NONE;
|
| 1078 | return 0;
|
| 1079 | case 90:
|
| 1080 | hfi_val = HFI_ROTATION_90;
|
| 1081 | break;
|
| 1082 | case 180:
|
| 1083 | hfi_val = HFI_ROTATION_180;
|
| 1084 | break;
|
| 1085 | case 270:
|
| 1086 | hfi_val = HFI_ROTATION_270;
|
| 1087 | break;
|
| 1088 | default:
|
| 1089 | return -EINVAL;
|
| 1090 | }
|
| 1091 |
|
| 1092 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1093 | HFI_HOST_FLAGS_NONE,
|
| 1094 | iris_get_port_info(inst, cap_id),
|
| 1095 | HFI_PAYLOAD_U32,
|
| 1096 | &hfi_val, sizeof(u32));
|
| 1097 | }
|
| 1098 |
|
| 1099 | int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1100 | {
|
| 1101 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1102 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1103 | u32 hfi_val = HFI_DISABLE_FLIP;
|
| 1104 |
|
| 1105 | if (inst->fw_caps[HFLIP].value)
|
| 1106 | hfi_val |= HFI_HORIZONTAL_FLIP;
|
| 1107 |
|
| 1108 | if (inst->fw_caps[VFLIP].value)
|
| 1109 | hfi_val |= HFI_VERTICAL_FLIP;
|
| 1110 |
|
| 1111 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1112 | HFI_HOST_FLAGS_NONE,
|
| 1113 | iris_get_port_info(inst, cap_id),
|
| 1114 | HFI_PAYLOAD_U32_ENUM,
|
| 1115 | &hfi_val, sizeof(u32));
|
| 1116 | }
|
| 1117 |
|
| 1118 | int iris_set_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1119 | {
|
| 1120 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1121 | struct v4l2_pix_format_mplane *fmt = &inst->fmt_dst->fmt.pix_mp;
|
| 1122 | u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
|
| 1123 | u32 ir_period = inst->fw_caps[cap_id].value;
|
| 1124 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1125 | struct hfi_intra_refresh hfi_val;
|
| 1126 |
|
| 1127 | if (!ir_period)
|
| 1128 | return -EINVAL;
|
| 1129 |
|
| 1130 | if (inst->fw_caps[IR_TYPE].value ==
|
| 1131 | V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
|
| 1132 | hfi_val.mode = HFI_INTRA_REFRESH_RANDOM;
|
| 1133 | } else if (inst->fw_caps[IR_TYPE].value ==
|
| 1134 | V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
|
| 1135 | hfi_val.mode = HFI_INTRA_REFRESH_CYCLIC;
|
| 1136 | } else {
|
| 1137 | return -EINVAL;
|
| 1138 | }
|
| 1139 |
|
| 1140 | |
| 1141 | * Calculate the number of macroblocks in a frame,
|
| 1142 | * then determine how many macroblocks need to be
|
| 1143 | * refreshed within one ir_period.
|
| 1144 |
|
| 1145 | hfi_val.mbs = (fmt->width / codec_align) * (fmt->height / codec_align);
|
| 1146 | hfi_val.mbs /= ir_period;
|
| 1147 |
|
| 1148 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1149 | HFI_HOST_FLAGS_NONE,
|
| 1150 | iris_get_port_info(inst, cap_id),
|
| 1151 | HFI_PAYLOAD_STRUCTURE,
|
| 1152 | &hfi_val, sizeof(hfi_val));
|
| 1153 | }
|
| 1154 |
|
| 1155 | int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1156 | {
|
| 1157 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1158 | struct vb2_queue *q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1159 | u32 ir_period = inst->fw_caps[cap_id].value;
|
| 1160 | u32 ir_type = 0;
|
| 1161 |
|
| 1162 | if (inst->fw_caps[IR_TYPE].value ==
|
| 1163 | V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
|
| 1164 | if (vb2_is_streaming(q))
|
| 1165 | return 0;
|
| 1166 | ir_type = HFI_PROP_IR_RANDOM_PERIOD;
|
| 1167 | } else if (inst->fw_caps[IR_TYPE].value ==
|
| 1168 | V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
|
| 1169 | ir_type = HFI_PROP_IR_CYCLIC_PERIOD;
|
| 1170 | } else {
|
| 1171 | return -EINVAL;
|
| 1172 | }
|
| 1173 |
|
| 1174 | return hfi_ops->session_set_property(inst, ir_type,
|
| 1175 | HFI_HOST_FLAGS_NONE,
|
| 1176 | iris_get_port_info(inst, cap_id),
|
| 1177 | HFI_PAYLOAD_U32,
|
| 1178 | &ir_period, sizeof(u32));
|
| 1179 | }
|
| 1180 |
|
| 1181 | int iris_set_ltr_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1182 | {
|
| 1183 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1184 | u32 ltr_count = inst->fw_caps[cap_id].value;
|
| 1185 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1186 | struct hfi_ltr_mode ltr_mode;
|
| 1187 |
|
| 1188 | if (!ltr_count)
|
| 1189 | return -EINVAL;
|
| 1190 |
|
| 1191 | ltr_mode.count = ltr_count;
|
| 1192 | ltr_mode.mode = HFI_LTR_MODE_MANUAL;
|
| 1193 | ltr_mode.trust_mode = 1;
|
| 1194 |
|
| 1195 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1196 | HFI_HOST_FLAGS_NONE,
|
| 1197 | iris_get_port_info(inst, cap_id),
|
| 1198 | HFI_PAYLOAD_STRUCTURE,
|
| 1199 | <r_mode, sizeof(ltr_mode));
|
| 1200 | }
|
| 1201 |
|
| 1202 | int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1203 | {
|
| 1204 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1205 | struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 1206 | struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1207 | u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
|
| 1208 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1209 | struct hfi_ltr_use ltr_use;
|
| 1210 |
|
| 1211 | if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
|
| 1212 | return -EINVAL;
|
| 1213 |
|
| 1214 | if (!ltr_count)
|
| 1215 | return -EINVAL;
|
| 1216 |
|
| 1217 | ltr_use.ref_ltr = inst->fw_caps[cap_id].value;
|
| 1218 | ltr_use.use_constrnt = true;
|
| 1219 | ltr_use.frames = 0;
|
| 1220 |
|
| 1221 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1222 | HFI_HOST_FLAGS_NONE,
|
| 1223 | iris_get_port_info(inst, cap_id),
|
| 1224 | HFI_PAYLOAD_STRUCTURE,
|
| 1225 | <r_use, sizeof(ltr_use));
|
| 1226 | }
|
| 1227 |
|
| 1228 | int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1229 | {
|
| 1230 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1231 | struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 1232 | struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1233 | u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
|
| 1234 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1235 | struct hfi_ltr_mark ltr_mark;
|
| 1236 |
|
| 1237 | if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
|
| 1238 | return -EINVAL;
|
| 1239 |
|
| 1240 | if (!ltr_count)
|
| 1241 | return -EINVAL;
|
| 1242 |
|
| 1243 | ltr_mark.mark_frame = inst->fw_caps[cap_id].value;
|
| 1244 |
|
| 1245 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1246 | HFI_HOST_FLAGS_NONE,
|
| 1247 | iris_get_port_info(inst, cap_id),
|
| 1248 | HFI_PAYLOAD_STRUCTURE,
|
| 1249 | <r_mark, sizeof(ltr_mark));
|
| 1250 | }
|
| 1251 |
|
| 1252 | int iris_set_ltr_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1253 | {
|
| 1254 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1255 | u32 ltr_count = inst->fw_caps[cap_id].value;
|
| 1256 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1257 |
|
| 1258 | if (!ltr_count)
|
| 1259 | return -EINVAL;
|
| 1260 |
|
| 1261 | if (inst->hfi_rc_type == HFI_RC_CBR_VFR ||
|
| 1262 | inst->hfi_rc_type == HFI_RC_CBR_CFR ||
|
| 1263 | inst->hfi_rc_type == HFI_RC_OFF) {
|
| 1264 | inst->fw_caps[LTR_COUNT].value = 0;
|
| 1265 | return -EINVAL;
|
| 1266 | }
|
| 1267 |
|
| 1268 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1269 | HFI_HOST_FLAGS_NONE,
|
| 1270 | iris_get_port_info(inst, cap_id),
|
| 1271 | HFI_PAYLOAD_U32,
|
| 1272 | <r_count, sizeof(u32));
|
| 1273 | }
|
| 1274 |
|
| 1275 | int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1276 | {
|
| 1277 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1278 | struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 1279 | struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1280 | u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
|
| 1281 | u32 hfi_val = inst->fw_caps[cap_id].value;
|
| 1282 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1283 |
|
| 1284 | if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
|
| 1285 | return -EINVAL;
|
| 1286 |
|
| 1287 | if (!ltr_count || hfi_val == INVALID_DEFAULT_MARK_OR_USE_LTR)
|
| 1288 | return -EINVAL;
|
| 1289 |
|
| 1290 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1291 | HFI_HOST_FLAGS_NONE,
|
| 1292 | iris_get_port_info(inst, cap_id),
|
| 1293 | HFI_PAYLOAD_U32,
|
| 1294 | &hfi_val, sizeof(u32));
|
| 1295 | }
|
| 1296 |
|
| 1297 | int iris_set_intra_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1298 | {
|
| 1299 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1300 | u32 gop_size = inst->fw_caps[cap_id].value;
|
| 1301 | u32 b_frame = inst->fw_caps[B_FRAME].value;
|
| 1302 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1303 | struct hfi_intra_period intra_period;
|
| 1304 |
|
| 1305 | if (!gop_size || b_frame >= gop_size)
|
| 1306 | return -EINVAL;
|
| 1307 |
|
| 1308 | |
| 1309 | * intra_period represents the length of a GOP, which includes both P-frames
|
| 1310 | * and B-frames. The counts of P-frames and B-frames within a GOP must be
|
| 1311 | * communicated to the firmware.
|
| 1312 |
|
| 1313 | intra_period.pframes = (gop_size - 1) / (b_frame + 1);
|
| 1314 | intra_period.bframes = b_frame;
|
| 1315 |
|
| 1316 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1317 | HFI_HOST_FLAGS_NONE,
|
| 1318 | iris_get_port_info(inst, cap_id),
|
| 1319 | HFI_PAYLOAD_STRUCTURE,
|
| 1320 | &intra_period, sizeof(intra_period));
|
| 1321 | }
|
| 1322 |
|
| 1323 | int iris_set_layer_type(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1324 | {
|
| 1325 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1326 | u32 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
|
| 1327 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1328 | u32 layer_type;
|
| 1329 |
|
| 1330 | if (inst->hfi_rc_type == HFI_RATE_CONTROL_CQ ||
|
| 1331 | inst->hfi_rc_type == HFI_RATE_CONTROL_OFF)
|
| 1332 | return -EINVAL;
|
| 1333 |
|
| 1334 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 1335 | if (!layer_enable || !inst->fw_caps[LAYER_COUNT_H264].value)
|
| 1336 | return -EINVAL;
|
| 1337 |
|
| 1338 | if (inst->fw_caps[LAYER_TYPE_H264].value ==
|
| 1339 | V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P) {
|
| 1340 | if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
|
| 1341 | layer_type = HFI_HIER_P_HYBRID_LTR;
|
| 1342 | else
|
| 1343 | layer_type = HFI_HIER_P_SLIDING_WINDOW;
|
| 1344 | } else if (inst->fw_caps[LAYER_TYPE_H264].value ==
|
| 1345 | V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) {
|
| 1346 | if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
|
| 1347 | layer_type = HFI_HIER_B;
|
| 1348 | else
|
| 1349 | return -EINVAL;
|
| 1350 | } else {
|
| 1351 | return -EINVAL;
|
| 1352 | }
|
| 1353 | } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
|
| 1354 | if (!inst->fw_caps[LAYER_COUNT_HEVC].value)
|
| 1355 | return -EINVAL;
|
| 1356 |
|
| 1357 | if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
|
| 1358 | V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) {
|
| 1359 | layer_type = HFI_HIER_P_SLIDING_WINDOW;
|
| 1360 | } else if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
|
| 1361 | V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) {
|
| 1362 | if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
|
| 1363 | layer_type = HFI_HIER_B;
|
| 1364 | else
|
| 1365 | return -EINVAL;
|
| 1366 | } else {
|
| 1367 | return -EINVAL;
|
| 1368 | }
|
| 1369 | } else {
|
| 1370 | return -EINVAL;
|
| 1371 | }
|
| 1372 |
|
| 1373 | inst->hfi_layer_type = layer_type;
|
| 1374 |
|
| 1375 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1376 | HFI_HOST_FLAGS_NONE,
|
| 1377 | iris_get_port_info(inst, cap_id),
|
| 1378 | HFI_PAYLOAD_U32_ENUM,
|
| 1379 | &layer_type, sizeof(u32));
|
| 1380 | }
|
| 1381 |
|
| 1382 | int iris_set_layer_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1383 | {
|
| 1384 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1385 | struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 1386 | struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1387 | u32 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
|
| 1388 | u32 layer_count = inst->fw_caps[cap_id].value;
|
| 1389 | u32 hfi_id, ret;
|
| 1390 |
|
| 1391 | if (!layer_enable || !layer_count)
|
| 1392 | return -EINVAL;
|
| 1393 |
|
| 1394 | inst->hfi_layer_count = layer_count;
|
| 1395 |
|
| 1396 | if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq)) {
|
| 1397 | hfi_id = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER;
|
| 1398 | ret = hfi_ops->session_set_property(inst, hfi_id,
|
| 1399 | HFI_HOST_FLAGS_NONE,
|
| 1400 | iris_get_port_info(inst, cap_id),
|
| 1401 | HFI_PAYLOAD_U32,
|
| 1402 | &layer_count, sizeof(u32));
|
| 1403 | if (ret)
|
| 1404 | return ret;
|
| 1405 | }
|
| 1406 |
|
| 1407 | hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1408 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1409 | HFI_HOST_FLAGS_NONE,
|
| 1410 | iris_get_port_info(inst, cap_id),
|
| 1411 | HFI_PAYLOAD_U32,
|
| 1412 | &layer_count, sizeof(u32));
|
| 1413 | }
|
| 1414 |
|
| 1415 | int iris_set_layer_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1416 | {
|
| 1417 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1418 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1419 | u32 layer_type = inst->hfi_layer_type;
|
| 1420 | u32 layer_count, layer_count_max;
|
| 1421 |
|
| 1422 | layer_count = (inst->codec == V4L2_PIX_FMT_H264) ?
|
| 1423 | inst->fw_caps[LAYER_COUNT_H264].value :
|
| 1424 | inst->fw_caps[LAYER_COUNT_HEVC].value;
|
| 1425 |
|
| 1426 | if (!layer_count)
|
| 1427 | return -EINVAL;
|
| 1428 |
|
| 1429 | if (layer_type == HFI_HIER_B) {
|
| 1430 | layer_count_max = MAX_LAYER_HB;
|
| 1431 | } else if (layer_type == HFI_HIER_P_HYBRID_LTR) {
|
| 1432 | layer_count_max = MAX_AVC_LAYER_HP_HYBRID_LTR;
|
| 1433 | } else if (layer_type == HFI_HIER_P_SLIDING_WINDOW) {
|
| 1434 | if (inst->codec == V4L2_PIX_FMT_H264) {
|
| 1435 | layer_count_max = MAX_AVC_LAYER_HP_SLIDING_WINDOW;
|
| 1436 | } else {
|
| 1437 | if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
|
| 1438 | layer_count_max = MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW;
|
| 1439 | else
|
| 1440 | layer_count_max = MAX_HEVC_LAYER_HP_SLIDING_WINDOW;
|
| 1441 | }
|
| 1442 | } else {
|
| 1443 | return -EINVAL;
|
| 1444 | }
|
| 1445 |
|
| 1446 | if (layer_count > layer_count_max)
|
| 1447 | layer_count = layer_count_max;
|
| 1448 |
|
| 1449 | layer_count += 1;
|
| 1450 | inst->hfi_layer_count = layer_count;
|
| 1451 |
|
| 1452 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1453 | HFI_HOST_FLAGS_NONE,
|
| 1454 | iris_get_port_info(inst, cap_id),
|
| 1455 | HFI_PAYLOAD_U32,
|
| 1456 | &layer_count, sizeof(u32));
|
| 1457 | }
|
| 1458 |
|
| 1459 | int iris_set_layer_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1460 | {
|
| 1461 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1462 | struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
|
| 1463 | struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
|
| 1464 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1465 | u32 bitrate = inst->fw_caps[cap_id].value;
|
| 1466 |
|
| 1467 |
|
| 1468 | if (inst->fw_caps[BITRATE].flags & CAP_FLAG_CLIENT_SET)
|
| 1469 | return 0;
|
| 1470 |
|
| 1471 | if (!(inst->fw_caps[cap_id].flags & CAP_FLAG_CLIENT_SET))
|
| 1472 | return -EINVAL;
|
| 1473 |
|
| 1474 | if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
|
| 1475 | return -EINVAL;
|
| 1476 |
|
| 1477 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1478 | HFI_HOST_FLAGS_NONE,
|
| 1479 | iris_get_port_info(inst, cap_id),
|
| 1480 | HFI_PAYLOAD_U32,
|
| 1481 | &bitrate, sizeof(u32));
|
| 1482 | }
|
| 1483 |
|
| 1484 | int iris_set_req_sync_frame(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1485 | {
|
| 1486 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1487 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1488 | u32 hfi_val = 0;
|
| 1489 |
|
| 1490 | if (inst->fw_caps[PREPEND_SPSPPS_TO_IDR].value)
|
| 1491 | hfi_val = HFI_SYNC_FRAME_REQUEST_WITH_PREFIX_SEQ_HDR;
|
| 1492 | else
|
| 1493 | hfi_val = HFI_SYNC_FRAME_REQUEST_WITHOUT_SEQ_HDR;
|
| 1494 |
|
| 1495 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1496 | HFI_HOST_FLAGS_NONE,
|
| 1497 | iris_get_port_info(inst, cap_id),
|
| 1498 | HFI_PAYLOAD_U32_ENUM,
|
| 1499 | &hfi_val, sizeof(u32));
|
| 1500 | }
|
| 1501 |
|
| 1502 | int iris_set_time_delta_based_rc(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
|
| 1503 | {
|
| 1504 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1505 | u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
|
| 1506 | u32 value = inst->fw_caps[cap_id].value;
|
| 1507 |
|
| 1508 | |
| 1509 | * Disable time-delta-based rate control (value = 0).
|
| 1510 | * This overrides the firmware's default (enabled), ensuring the
|
| 1511 | * firmware uses the configured bitrate target rather than calculating
|
| 1512 | * bitrate from frame timing.
|
| 1513 |
|
| 1514 | return hfi_ops->session_set_property(inst, hfi_id,
|
| 1515 | HFI_HOST_FLAGS_NONE,
|
| 1516 | iris_get_port_info(inst, cap_id),
|
| 1517 | HFI_PAYLOAD_U32,
|
| 1518 | &value, sizeof(u32));
|
| 1519 | }
|
| 1520 |
|
| 1521 | int iris_set_properties(struct iris_inst *inst, u32 plane)
|
| 1522 | {
|
| 1523 | const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops;
|
| 1524 | struct platform_inst_fw_cap *cap;
|
| 1525 | int ret;
|
| 1526 | u32 i;
|
| 1527 |
|
| 1528 | ret = hfi_ops->session_set_config_params(inst, plane);
|
| 1529 | if (ret)
|
| 1530 | return ret;
|
| 1531 |
|
| 1532 | for (i = 1; i < INST_FW_CAP_MAX; i++) {
|
| 1533 | cap = &inst->fw_caps[i];
|
| 1534 | if (!iris_valid_cap_id(cap->cap_id))
|
| 1535 | continue;
|
| 1536 |
|
| 1537 | if (cap->cap_id && cap->set)
|
| 1538 | cap->set(inst, i);
|
| 1539 | }
|
| 1540 |
|
| 1541 | return 0;
|
| 1542 | }
|