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 <media/v4l2-event.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_buffer.h" 10 #include "iris_instance.h" 11 #include "iris_power.h" 12 #include "iris_vpu_buffer.h" 13 14 #define PIXELS_4K 4096 15 #define MAX_WIDTH 4096 16 #define MAX_HEIGHT 2304 17 #define Y_STRIDE_ALIGN 128 18 #define Y_STRIDE_ALIGN_P010 256 19 #define UV_STRIDE_ALIGN 128 20 #define UV_STRIDE_ALIGN_P010 256 21 #define Y_SCANLINE_ALIGN 32 22 #define Y_SCANLINE_ALIGN_QC10C 16 23 #define UV_SCANLINE_ALIGN 16 24 #define UV_SCANLINE_ALIGN_QC08C 32 25 #define META_STRIDE_ALIGNED 64 26 #define META_SCANLINE_ALIGNED 16 27 #define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16)) 28 29 /* 30 * NV12: 31 * YUV 4:2:0 image with a plane of 8 bit Y samples followed 32 * by an interleaved U/V plane containing 8 bit 2x2 subsampled 33 * colour difference samples. 34 * 35 * <-Y/UV_Stride (aligned to 128)-> 36 * <------- Width -------> 37 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ 38 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 39 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | 40 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | y_scanlines (aligned to 32) 41 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 42 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 43 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 44 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | 45 * . . . . . . . . . . . . . . . . | 46 * . . . . . . . . . . . . . . . . | 47 * . . . . . . . . . . . . . . . . | 48 * . . . . . . . . . . . . . . . . V 49 * U V U V U V U V U V U V . . . . ^ 50 * U V U V U V U V U V U V . . . . | 51 * U V U V U V U V U V U V . . . . | 52 * U V U V U V U V U V U V . . . . uv_scanlines (aligned to 16) 53 * . . . . . . . . . . . . . . . . | 54 * . . . . . . . . . . . . . . . . V 55 * . . . . . . . . . . . . . . . . --> Buffer size aligned to 4K 56 * 57 * y_stride : Width aligned to 128 58 * uv_stride : Width aligned to 128 59 * y_scanlines: Height aligned to 32 60 * uv_scanlines: Height/2 aligned to 16 61 * Total size = align((y_stride * y_scanlines 62 * + uv_stride * uv_scanlines , 4096) 63 * 64 * Note: All the alignments are hardware requirements. 65 */ 66 static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst) 67 { 68 u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines; 69 struct v4l2_format *f; 70 71 if (inst->domain == DECODER) 72 f = inst->fmt_dst; 73 else 74 f = inst->fmt_src; 75 76 y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); 77 uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); 78 y_scanlines = ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN); 79 uv_scanlines = ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN); 80 y_plane = y_stride * y_scanlines; 81 uv_plane = uv_stride * uv_scanlines; 82 83 return ALIGN(y_plane + uv_plane, PIXELS_4K); 84 } 85 86 /* 87 * P010: 88 * YUV 4:2:0 image with a plane of 10 bit Y samples followed 89 * by an interleaved U/V plane containing 10 bit 2x2 subsampled 90 * colour difference samples. 91 * 92 * <-Y/UV_Stride (aligned to 256)-> 93 * <----- Width*2 -------> 94 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ 95 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 96 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | 97 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | y_scanlines (aligned to 32) 98 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 99 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 100 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 101 * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | 102 * . . . . . . . . . . . . . . . . | 103 * . . . . . . . . . . . . . . . . | 104 * . . . . . . . . . . . . . . . . | 105 * . . . . . . . . . . . . . . . . V 106 * U V U V U V U V U V U V . . . . ^ 107 * U V U V U V U V U V U V . . . . | 108 * U V U V U V U V U V U V . . . . | 109 * U V U V U V U V U V U V . . . . uv_scanlines (aligned to 16) 110 * . . . . . . . . . . . . . . . . | 111 * . . . . . . . . . . . . . . . . V 112 * . . . . . . . . . . . . . . . . --> Buffer size aligned to 4K 113 * 114 * y_stride : Width*2 aligned to 256 115 * uv_stride : Width*2 aligned to 256 116 * y_scanlines: Height aligned to 32 117 * uv_scanlines: Height/2 aligned to 16 118 * Total size = align((y_stride * y_scanlines 119 * + uv_stride * uv_scanlines , 4096) 120 * 121 * Note: All the alignments are hardware requirements. 122 */ 123 static u32 iris_yuv_buffer_size_p010(struct iris_inst *inst) 124 { 125 u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines; 126 struct v4l2_format *f; 127 128 if (inst->domain == DECODER) 129 f = inst->fmt_dst; 130 else 131 f = inst->fmt_src; 132 133 y_stride = ALIGN(f->fmt.pix_mp.width * 2, Y_STRIDE_ALIGN_P010); 134 uv_stride = ALIGN(f->fmt.pix_mp.width * 2, UV_STRIDE_ALIGN_P010); 135 y_scanlines = ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN); 136 uv_scanlines = ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN); 137 y_plane = y_stride * y_scanlines; 138 uv_plane = uv_stride * uv_scanlines; 139 140 return ALIGN(y_plane + uv_plane, PIXELS_4K); 141 } 142 143 /* 144 * QC08C: 145 * Compressed Macro-tile format for NV12. 146 * Contains 4 planes in the following order - 147 * (A) Y_Meta_Plane 148 * (B) Y_UBWC_Plane 149 * (C) UV_Meta_Plane 150 * (D) UV_UBWC_Plane 151 * 152 * Y_Meta_Plane consists of meta information to decode compressed 153 * tile data in Y_UBWC_Plane. 154 * Y_UBWC_Plane consists of Y data in compressed macro-tile format. 155 * UBWC decoder block will use the Y_Meta_Plane data together with 156 * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples. 157 * 158 * UV_Meta_Plane consists of meta information to decode compressed 159 * tile data in UV_UBWC_Plane. 160 * UV_UBWC_Plane consists of UV data in compressed macro-tile format. 161 * UBWC decoder block will use UV_Meta_Plane data together with 162 * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2 163 * subsampled color difference samples. 164 * 165 * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable 166 * and randomly accessible. There is no dependency between tiles. 167 * 168 * <----- y_meta_stride ----> (aligned to 64) 169 * <-------- Width ------> 170 * M M M M M M M M M M M M . . ^ ^ 171 * M M M M M M M M M M M M . . | | 172 * M M M M M M M M M M M M . . Height | 173 * M M M M M M M M M M M M . . | y_meta_scanlines (aligned to 16) 174 * M M M M M M M M M M M M . . | | 175 * M M M M M M M M M M M M . . | | 176 * M M M M M M M M M M M M . . | | 177 * M M M M M M M M M M M M . . V | 178 * . . . . . . . . . . . . . . | 179 * . . . . . . . . . . . . . . | 180 * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 181 * . . . . . . . . . . . . . . V 182 * <--Compressed tile y_stride---> (aligned to 128) 183 * <------- Width -------> 184 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ 185 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 186 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | 187 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile y_scanlines (aligned to 32) 188 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 189 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 190 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 191 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | 192 * . . . . . . . . . . . . . . . . | 193 * . . . . . . . . . . . . . . . . | 194 * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 195 * . . . . . . . . . . . . . . . . V 196 * <----- uv_meta_stride ----> (aligned to 64) 197 * M M M M M M M M M M M M . . ^ 198 * M M M M M M M M M M M M . . | 199 * M M M M M M M M M M M M . . | 200 * M M M M M M M M M M M M . . uv_meta_scanlines (aligned to 16) 201 * . . . . . . . . . . . . . . | 202 * . . . . . . . . . . . . . . V 203 * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 204 * <--Compressed tile uv_stride---> (aligned to 128) 205 * U* V* U* V* U* V* U* V* . . . . ^ 206 * U* V* U* V* U* V* U* V* . . . . | 207 * U* V* U* V* U* V* U* V* . . . . | 208 * U* V* U* V* U* V* U* V* . . . . uv_scanlines (aligned to 32) 209 * . . . . . . . . . . . . . . . . | 210 * . . . . . . . . . . . . . . . . V 211 * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 212 * 213 * y_stride: width aligned to 128 214 * uv_stride: width aligned to 128 215 * y_scanlines: height aligned to 32 216 * uv_scanlines: height aligned to 32 217 * y_plane: buffer size aligned to 4096 218 * uv_plane: buffer size aligned to 4096 219 * y_meta_stride: width aligned to 64 220 * y_meta_scanlines: height aligned to 16 221 * y_meta_plane: buffer size aligned to 4096 222 * uv_meta_stride: width aligned to 64 223 * uv_meta_scanlines: height aligned to 16 224 * uv_meta_plane: buffer size aligned to 4096 225 * 226 * Total size = align( y_plane + uv_plane + 227 * y_meta_plane + uv_meta_plane, 4096) 228 * 229 * Note: All the alignments are hardware requirements. 230 */ 231 static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst) 232 { 233 u32 y_plane, uv_plane, y_stride, uv_stride; 234 u32 uv_meta_stride, uv_meta_plane; 235 u32 y_meta_stride, y_meta_plane; 236 struct v4l2_format *f = NULL; 237 238 if (inst->domain == DECODER) 239 f = inst->fmt_dst; 240 else 241 f = inst->fmt_src; 242 243 y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1), 244 META_STRIDE_ALIGNED); 245 y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height, 246 META_SCANLINE_ALIGNED >> 1), 247 META_SCANLINE_ALIGNED); 248 y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K); 249 250 y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); 251 y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN), PIXELS_4K); 252 253 uv_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width / 2, META_STRIDE_ALIGNED >> 2), 254 META_STRIDE_ALIGNED); 255 uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height / 2, 256 META_SCANLINE_ALIGNED >> 1), 257 META_SCANLINE_ALIGNED); 258 uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K); 259 260 uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); 261 uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C), 262 PIXELS_4K); 263 264 return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K); 265 } 266 267 /* 268 * QC10C: 269 * UBWC-compressed format for P010. 270 * Contains 4 planes in the following order - 271 * (A) Y_Meta_Plane 272 * (B) Y_UBWC_Plane 273 * (C) UV_Meta_Plane 274 * (D) UV_UBWC_Plane 275 * 276 * Y_Meta_Plane consists of meta information to decode compressed 277 * tile data in Y_UBWC_Plane. 278 * Y_UBWC_Plane consists of Y data in compressed macro-tile format. 279 * UBWC decoder block will use the Y_Meta_Plane data together with 280 * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples. 281 * 282 * UV_Meta_Plane consists of meta information to decode compressed 283 * tile data in UV_UBWC_Plane. 284 * UV_UBWC_Plane consists of UV data in compressed macro-tile format. 285 * UBWC decoder block will use UV_Meta_Plane data together with 286 * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2 287 * subsampled color difference samples. 288 * 289 * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable 290 * and randomly accessible. There is no dependency between tiles. 291 * 292 * <----- Y Meta stride -----> (aligned to 64) 293 * <-------- Width ----------> (aligned to 48) 294 * M M M M M M M M M M M M . . ^ ^ 295 * M M M M M M M M M M M M . . | | 296 * M M M M M M M M M M M M . . Height | 297 * M M M M M M M M M M M M . . | Meta_Y_Scanlines (aligned to 16) 298 * M M M M M M M M M M M M . . | | 299 * M M M M M M M M M M M M . . | | 300 * M M M M M M M M M M M M . . | | 301 * M M M M M M M M M M M M . . V | 302 * . . . . . . . . . . . . . . | 303 * . . . . . . . . . . . . . . | 304 * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 305 * . . . . . . . . . . . . . . V 306 * <--Compressed tile Y stride --> (aligned to 256) 307 * <------- Width * 4/3 ---------> (aligned to 48) 308 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ 309 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 310 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | 311 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines (aligned to 16) 312 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 313 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 314 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | 315 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | 316 * . . . . . . . . . . . . . . . . | 317 * . . . . . . . . . . . . . . . . | 318 * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 319 * . . . . . . . . . . . . . . . . V 320 * <---- UV Meta stride ----> (aligned to 64) 321 * <----- Width / 2 --------> (aligned to 24) 322 * M M M M M M M M M M M M . . ^ ^ 323 * M M M M M M M M M M M M . . | | 324 * M M M M M M M M M M M M . . Height/2 | 325 * M M M M M M M M M M M M . . V M_UV_Scanlines (aligned to 16) 326 * . . . . . . . . . . . . . . | 327 * . . . . . . . . . . . . . . V 328 * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 329 * <--Compressed tile UV stride--> (aligned to 256) 330 * <------- Width * 4/3 ---------> (aligned to 48) 331 * U* V* U* V* U* V* U* V* . . . . ^ 332 * U* V* U* V* U* V* U* V* . . . . | 333 * U* V* U* V* U* V* U* V* . . . . | 334 * U* V* U* V* U* V* U* V* . . . . UV_Scanlines (aligned to 16) 335 * . . . . . . . . . . . . . . . . | 336 * . . . . . . . . . . . . . . . . V 337 * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k 338 * 339 * y_stride: width aligned to 256 340 * uv_stride: width aligned to 256 341 * y_scanlines: height aligned to 16 342 * uv_scanlines: height aligned to 16 343 * y_plane: buffer size aligned to 4096 344 * uv_plane: buffer size aligned to 4096 345 * y_meta_stride: width aligned to 64 346 * y_meta_scanlines: height aligned to 16 347 * y_meta_plane: buffer size aligned to 4096 348 * uv_meta_stride: width aligned to 64 349 * uv_meta_scanlines: height aligned to 16 350 * uv_meta_plane: buffer size aligned to 4096 351 * 352 * Total size = align( y_plane + uv_plane + 353 * y_meta_plane + uv_meta_plane, 4096) 354 * 355 * Note: All the alignments are hardware requirements. 356 */ 357 static u32 iris_yuv_buffer_size_qc10c(struct iris_inst *inst) 358 { 359 u32 y_plane, uv_plane, y_stride, uv_stride; 360 u32 uv_meta_stride, uv_meta_plane; 361 u32 y_meta_stride, y_meta_plane; 362 struct v4l2_format *f; 363 364 if (inst->domain == DECODER) 365 f = inst->fmt_dst; 366 else 367 f = inst->fmt_src; 368 369 y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, 48), 370 META_STRIDE_ALIGNED); 371 y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height, 4), 372 META_SCANLINE_ALIGNED); 373 y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K); 374 375 y_stride = ALIGN(f->fmt.pix_mp.width * 4 / 3, Y_STRIDE_ALIGN_P010); 376 y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN_QC10C), 377 PIXELS_4K); 378 379 uv_meta_stride = ALIGN(DIV_ROUND_UP((f->fmt.pix_mp.width + 1) >> 1, 24), 380 META_STRIDE_ALIGNED); 381 uv_meta_plane = uv_meta_stride * 382 ALIGN(DIV_ROUND_UP((f->fmt.pix_mp.height + 1) >> 1, 4), 383 META_SCANLINE_ALIGNED); 384 uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K); 385 386 uv_stride = ALIGN(f->fmt.pix_mp.width * 4 / 3, UV_STRIDE_ALIGN_P010); 387 uv_plane = ALIGN(uv_stride * ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN), 388 PIXELS_4K); 389 390 return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K); 391 } 392 393 static u32 iris_dec_bitstream_buffer_size(struct iris_inst *inst) 394 { 395 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; 396 u32 base_res_mbs = NUM_MBS_4K; 397 u32 frame_size, num_mbs; 398 u32 div_factor = 2; 399 400 num_mbs = iris_get_mbpf(inst); 401 if (num_mbs > NUM_MBS_4K) { 402 div_factor = 4; 403 base_res_mbs = caps->max_mbpf; 404 } else { 405 if (inst->codec == V4L2_PIX_FMT_VP9) 406 div_factor = 1; 407 } 408 409 /* 410 * frame_size = YUVsize / div_factor 411 * where YUVsize = resolution_in_MBs * MBs_in_pixel * 3 / 2 412 */ 413 frame_size = base_res_mbs * (16 * 16) * 3 / 2 / div_factor; 414 415 return ALIGN(frame_size, PIXELS_4K); 416 } 417 418 static u32 iris_enc_bitstream_buffer_size(struct iris_inst *inst) 419 { 420 u32 aligned_width, aligned_height, bitstream_size, yuv_size; 421 int bitrate_mode, frame_rc; 422 struct v4l2_format *f; 423 424 f = inst->fmt_dst; 425 426 bitrate_mode = inst->fw_caps[BITRATE_MODE].value; 427 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value; 428 429 aligned_width = ALIGN(f->fmt.pix_mp.width, 32); 430 aligned_height = ALIGN(f->fmt.pix_mp.height, 32); 431 bitstream_size = aligned_width * aligned_height * 3; 432 yuv_size = (aligned_width * aligned_height * 3) >> 1; 433 if (aligned_width * aligned_height > (4096 * 2176)) 434 /* bitstream_size = 0.25 * yuv_size; */ 435 bitstream_size = (bitstream_size >> 3); 436 else if (aligned_width * aligned_height > (1280 * 720)) 437 /* bitstream_size = 0.5 * yuv_size; */ 438 bitstream_size = (bitstream_size >> 2); 439 440 if ((!frame_rc || bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) && 441 bitstream_size < yuv_size) 442 bitstream_size = (bitstream_size << 1); 443 444 return ALIGN(bitstream_size, 4096); 445 } 446 447 int iris_get_buffer_size(struct iris_inst *inst, 448 enum iris_buffer_type buffer_type) 449 { 450 if (inst->domain == DECODER) { 451 switch (buffer_type) { 452 case BUF_INPUT: 453 return iris_dec_bitstream_buffer_size(inst); 454 case BUF_OUTPUT: 455 if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) 456 return iris_yuv_buffer_size_qc08c(inst); 457 else if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C) 458 return iris_yuv_buffer_size_qc10c(inst); 459 else if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_P010) 460 return iris_yuv_buffer_size_p010(inst); 461 else 462 return iris_yuv_buffer_size_nv12(inst); 463 case BUF_DPB: 464 if (iris_fmt_is_10bit(inst->fmt_dst->fmt.pix_mp.pixelformat)) 465 return iris_yuv_buffer_size_qc10c(inst); 466 else 467 return iris_yuv_buffer_size_qc08c(inst); 468 default: 469 return 0; 470 } 471 } else { 472 switch (buffer_type) { 473 case BUF_INPUT: 474 if (inst->fmt_src->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) 475 return iris_yuv_buffer_size_qc08c(inst); 476 else 477 return iris_yuv_buffer_size_nv12(inst); 478 case BUF_OUTPUT: 479 return iris_enc_bitstream_buffer_size(inst); 480 default: 481 return 0; 482 } 483 } 484 } 485 486 static void iris_fill_internal_buf_info(struct iris_inst *inst, 487 enum iris_buffer_type buffer_type) 488 { 489 struct iris_buffers *buffers = &inst->buffers[buffer_type]; 490 491 buffers->size = inst->core->iris_firmware_desc->get_vpu_buffer_size(inst, buffer_type); 492 buffers->min_count = iris_vpu_buf_count(inst, buffer_type); 493 } 494 495 static void iris_get_int_buf_tbl(struct iris_inst *inst, u32 plane, 496 const u32 **internal_buf_type, u32 *internal_buffer_count) 497 { 498 const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; 499 500 if (inst->domain == DECODER) { 501 if (V4L2_TYPE_IS_OUTPUT(plane)) { 502 *internal_buf_type = firmware_data->dec_ip_int_buf_tbl; 503 *internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; 504 } else { 505 *internal_buf_type = firmware_data->dec_op_int_buf_tbl; 506 *internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size; 507 } 508 } else { 509 if (V4L2_TYPE_IS_OUTPUT(plane)) { 510 *internal_buf_type = firmware_data->enc_ip_int_buf_tbl; 511 *internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size; 512 } else { 513 *internal_buf_type = firmware_data->enc_op_int_buf_tbl; 514 *internal_buffer_count = firmware_data->enc_op_int_buf_tbl_size; 515 } 516 } 517 } 518 519 void iris_get_internal_buffers(struct iris_inst *inst, u32 plane) 520 { 521 const u32 *internal_buf_type; 522 u32 internal_buffer_count, i; 523 524 iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count); 525 526 for (i = 0; i < internal_buffer_count; i++) 527 iris_fill_internal_buf_info(inst, internal_buf_type[i]); 528 } 529 530 static int iris_create_internal_buffer(struct iris_inst *inst, 531 enum iris_buffer_type buffer_type, u32 index) 532 { 533 struct iris_buffers *buffers = &inst->buffers[buffer_type]; 534 struct iris_core *core = inst->core; 535 struct iris_buffer *buffer; 536 537 if (!buffers->size) 538 return 0; 539 540 buffer = kzalloc_obj(*buffer); 541 if (!buffer) 542 return -ENOMEM; 543 544 INIT_LIST_HEAD(&buffer->list); 545 buffer->type = buffer_type; 546 buffer->index = index; 547 buffer->buffer_size = buffers->size; 548 buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING; 549 550 buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size, 551 &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs); 552 if (!buffer->kvaddr) { 553 kfree(buffer); 554 return -ENOMEM; 555 } 556 557 list_add_tail(&buffer->list, &buffers->list); 558 559 return 0; 560 } 561 562 int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) 563 { 564 u32 internal_buffer_count, i, j; 565 struct iris_buffers *buffers; 566 const u32 *internal_buf_type; 567 int ret; 568 569 iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count); 570 571 for (i = 0; i < internal_buffer_count; i++) { 572 buffers = &inst->buffers[internal_buf_type[i]]; 573 for (j = 0; j < buffers->min_count; j++) { 574 ret = iris_create_internal_buffer(inst, internal_buf_type[i], j); 575 if (ret) 576 return ret; 577 } 578 } 579 580 return 0; 581 } 582 583 int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) 584 { 585 const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; 586 int ret; 587 588 ret = hfi_ops->session_queue_buf(inst, buf); 589 if (ret) 590 return ret; 591 592 buf->attr &= ~BUF_ATTR_DEFERRED; 593 buf->attr |= BUF_ATTR_QUEUED; 594 595 return 0; 596 } 597 598 int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type) 599 { 600 struct iris_buffer *buffer, *next; 601 struct iris_buffers *buffers; 602 int ret = 0; 603 604 buffers = &inst->buffers[buffer_type]; 605 list_for_each_entry_safe(buffer, next, &buffers->list, list) { 606 if (buffer->attr & BUF_ATTR_PENDING_RELEASE) 607 continue; 608 if (buffer->attr & BUF_ATTR_QUEUED) 609 continue; 610 611 if (buffer->attr & BUF_ATTR_DEFERRED) { 612 ret = iris_queue_buffer(inst, buffer); 613 if (ret) 614 return ret; 615 } 616 } 617 618 return ret; 619 } 620 621 int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) 622 { 623 struct iris_buffer *buffer, *next; 624 struct iris_buffers *buffers; 625 const u32 *internal_buf_type; 626 u32 internal_buffer_count, i; 627 int ret; 628 629 iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &internal_buffer_count); 630 631 for (i = 0; i < internal_buffer_count; i++) { 632 buffers = &inst->buffers[internal_buf_type[i]]; 633 list_for_each_entry_safe(buffer, next, &buffers->list, list) { 634 if (buffer->attr & BUF_ATTR_PENDING_RELEASE) 635 continue; 636 if (buffer->attr & BUF_ATTR_QUEUED) 637 continue; 638 if (buffer->type == BUF_DPB && inst->state != IRIS_INST_STREAMING) { 639 buffer->attr |= BUF_ATTR_DEFERRED; 640 continue; 641 } 642 ret = iris_queue_buffer(inst, buffer); 643 if (ret) 644 return ret; 645 } 646 } 647 648 return 0; 649 } 650 651 void iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer) 652 { 653 struct iris_core *core = inst->core; 654 655 list_del(&buffer->list); 656 dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr, 657 buffer->device_addr, buffer->dma_attrs); 658 kfree(buffer); 659 } 660 661 static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force) 662 { 663 struct iris_buffer *buf, *next; 664 struct iris_buffers *buffers; 665 const u32 *internal_buf_type; 666 u32 i, len; 667 668 iris_get_int_buf_tbl(inst, plane, &internal_buf_type, &len); 669 670 for (i = 0; i < len; i++) { 671 buffers = &inst->buffers[internal_buf_type[i]]; 672 list_for_each_entry_safe(buf, next, &buffers->list, list) { 673 /* 674 * during stream on, skip destroying internal(DPB) buffer 675 * if firmware did not return it. 676 * during close, destroy all buffers irrespectively. 677 */ 678 if (!force && buf->attr & BUF_ATTR_QUEUED) 679 continue; 680 681 iris_destroy_internal_buffer(inst, buf); 682 } 683 } 684 685 if (force) { 686 if (inst->domain == DECODER) 687 buffers = &inst->buffers[BUF_PERSIST]; 688 else 689 buffers = &inst->buffers[BUF_ARP]; 690 691 list_for_each_entry_safe(buf, next, &buffers->list, list) 692 iris_destroy_internal_buffer(inst, buf); 693 } 694 695 return 0; 696 } 697 698 int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane) 699 { 700 return iris_destroy_internal_buffers(inst, plane, true); 701 } 702 703 int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane) 704 { 705 return iris_destroy_internal_buffers(inst, plane, false); 706 } 707 708 static int iris_release_internal_buffers(struct iris_inst *inst, 709 enum iris_buffer_type buffer_type) 710 { 711 const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; 712 struct iris_buffers *buffers = &inst->buffers[buffer_type]; 713 struct iris_buffer *buffer, *next; 714 int ret; 715 716 list_for_each_entry_safe(buffer, next, &buffers->list, list) { 717 if (buffer->attr & BUF_ATTR_PENDING_RELEASE) 718 continue; 719 if (!(buffer->attr & BUF_ATTR_QUEUED)) 720 continue; 721 buffer->attr |= BUF_ATTR_PENDING_RELEASE; 722 ret = hfi_ops->session_release_buf(inst, buffer); 723 if (ret) { 724 buffer->attr &= ~BUF_ATTR_PENDING_RELEASE; 725 return ret; 726 } 727 } 728 729 return 0; 730 } 731 732 static int iris_release_input_internal_buffers(struct iris_inst *inst) 733 { 734 const u32 *internal_buf_type; 735 u32 internal_buffer_count, i; 736 int ret; 737 738 iris_get_int_buf_tbl(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 739 &internal_buf_type, &internal_buffer_count); 740 741 for (i = 0; i < internal_buffer_count; i++) { 742 ret = iris_release_internal_buffers(inst, internal_buf_type[i]); 743 if (ret) 744 return ret; 745 } 746 747 return 0; 748 } 749 750 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst, enum iris_buffer_type buffer_type) 751 { 752 struct iris_buffers *buffers = &inst->buffers[buffer_type]; 753 struct iris_buffer *buffer, *next; 754 int ret; 755 u32 i; 756 757 if (!list_empty(&buffers->list)) 758 return 0; 759 760 iris_fill_internal_buf_info(inst, buffer_type); 761 762 for (i = 0; i < buffers->min_count; i++) { 763 ret = iris_create_internal_buffer(inst, buffer_type, i); 764 if (ret) 765 return ret; 766 } 767 768 list_for_each_entry_safe(buffer, next, &buffers->list, list) { 769 if (buffer->attr & BUF_ATTR_PENDING_RELEASE) 770 continue; 771 if (buffer->attr & BUF_ATTR_QUEUED) 772 continue; 773 ret = iris_queue_buffer(inst, buffer); 774 if (ret) 775 return ret; 776 } 777 778 return 0; 779 } 780 781 int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst) 782 { 783 int ret; 784 785 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 786 787 ret = iris_release_input_internal_buffers(inst); 788 if (ret) 789 return ret; 790 791 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 792 if (ret) 793 return ret; 794 795 return iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 796 } 797 798 int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type) 799 { 800 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 801 struct v4l2_m2m_buffer *buffer, *n; 802 struct iris_buffer *buf; 803 int ret; 804 805 iris_scale_power(inst); 806 807 if (buf_type == BUF_INPUT) { 808 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { 809 buf = to_iris_buffer(&buffer->vb); 810 if (!(buf->attr & BUF_ATTR_DEFERRED)) 811 continue; 812 ret = iris_queue_buffer(inst, buf); 813 if (ret) 814 return ret; 815 } 816 } else { 817 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { 818 buf = to_iris_buffer(&buffer->vb); 819 if (!(buf->attr & BUF_ATTR_DEFERRED)) 820 continue; 821 ret = iris_queue_buffer(inst, buf); 822 if (ret) 823 return ret; 824 } 825 } 826 827 return 0; 828 } 829 830 void iris_vb2_queue_error(struct iris_inst *inst) 831 { 832 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 833 struct vb2_queue *q; 834 835 q = v4l2_m2m_get_src_vq(m2m_ctx); 836 vb2_queue_error(q); 837 q = v4l2_m2m_get_dst_vq(m2m_ctx); 838 vb2_queue_error(q); 839 } 840 841 static struct vb2_v4l2_buffer * 842 iris_helper_find_buf(struct iris_inst *inst, u32 type, u32 idx) 843 { 844 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 845 846 if (V4L2_TYPE_IS_OUTPUT(type)) 847 return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx); 848 else 849 return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx); 850 } 851 852 static void iris_get_ts_metadata(struct iris_inst *inst, u64 timestamp_ns, 853 struct vb2_v4l2_buffer *vbuf) 854 { 855 u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK; 856 u32 i; 857 858 for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) { 859 if (inst->tss[i].ts_ns != timestamp_ns) 860 continue; 861 862 vbuf->flags &= ~mask; 863 vbuf->flags |= inst->tss[i].flags; 864 vbuf->timecode = inst->tss[i].tc; 865 return; 866 } 867 868 vbuf->flags &= ~mask; 869 vbuf->flags |= inst->tss[inst->metadata_idx].flags; 870 vbuf->timecode = inst->tss[inst->metadata_idx].tc; 871 } 872 873 int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) 874 { 875 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 876 struct vb2_v4l2_buffer *vbuf; 877 struct vb2_buffer *vb2; 878 u32 type, state; 879 880 switch (buf->type) { 881 case BUF_INPUT: 882 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 883 break; 884 case BUF_OUTPUT: 885 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 886 break; 887 default: 888 return 0; /* Internal DPB Buffers */ 889 } 890 891 vbuf = iris_helper_find_buf(inst, type, buf->index); 892 if (!vbuf) 893 return -EINVAL; 894 895 vb2 = &vbuf->vb2_buf; 896 897 vbuf->flags |= buf->flags; 898 899 if (buf->flags & V4L2_BUF_FLAG_ERROR) { 900 state = VB2_BUF_STATE_ERROR; 901 vb2_set_plane_payload(vb2, 0, 0); 902 vb2->timestamp = 0; 903 v4l2_m2m_buf_done(vbuf, state); 904 return 0; 905 } 906 907 if (V4L2_TYPE_IS_CAPTURE(type)) { 908 vb2_set_plane_payload(vb2, 0, buf->data_size); 909 vbuf->sequence = inst->sequence_cap++; 910 iris_get_ts_metadata(inst, buf->timestamp, vbuf); 911 } else { 912 vbuf->sequence = inst->sequence_out++; 913 } 914 915 if (vbuf->flags & V4L2_BUF_FLAG_LAST) { 916 if (!v4l2_m2m_has_stopped(m2m_ctx)) { 917 const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; 918 919 v4l2_event_queue_fh(&inst->fh, &ev); 920 v4l2_m2m_mark_stopped(m2m_ctx); 921 } 922 inst->last_buffer_dequeued = true; 923 } 924 925 state = VB2_BUF_STATE_DONE; 926 vb2->timestamp = buf->timestamp; 927 v4l2_m2m_buf_done(vbuf, state); 928 929 return 0; 930 } 931