From e2e2aac868a85e9f9adc2f50731e8cebfdd7b7de Mon Sep 17 00:00:00 2001 From: sofus Date: Tue, 1 Sep 2026 16:51:22 +0200 Subject: [PATCH 1/5] media: apple: avd: check that buffer size is positive Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/apple/avd/avd-drv.c b/drivers/media/platform/apple/avd/avd-drv.c index 487d478b00f397..890e5939b968a9 100644 --- a/drivers/media/platform/apple/avd/avd-drv.c +++ b/drivers/media/platform/apple/avd/avd-drv.c @@ -103,6 +103,9 @@ int avd_buf_alloc(struct avd_dev *avd, struct avd_buf *buf, size_t size) else if (buf->cpu) avd_buf_free(avd, buf); + if (size <= 0) + return -ENOMEM; + buf->size = size; buf->cpu = dma_alloc_coherent(avd->dev, buf->size, &buf->addr, GFP_KERNEL); From 7b966eecc4be06b741f727cd49638fe05135da30 Mon Sep 17 00:00:00 2001 From: sofus Date: Mon, 31 Aug 2026 22:21:09 +0200 Subject: [PATCH 2/5] fixup! media: apple: avd: add av1 support Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-av1.c | 128 ++++++++++++++------- 1 file changed, 85 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/apple/avd/avd-av1.c b/drivers/media/platform/apple/avd/avd-av1.c index 1d8c6d2f2b798a..a34ee366febc55 100644 --- a/drivers/media/platform/apple/avd/avd-av1.c +++ b/drivers/media/platform/apple/avd/avd-av1.c @@ -60,10 +60,14 @@ }) #define AV1_REF_SCALE_SHIFT 14 +#define SUPERRES_SCALE_BITS 14 +#define SUPERRES_EXTRA_BITS 8 +#define SUPERRES_SCALE_MASK ((1 << 14) - 1) #define AV1_CODEC_MODE_INTRABC(v) FIELD_PREP(BIT(28), !!(v)) #define AV1_HDR_JNT_COMP(v) FIELD_PREP(BIT(0), !!(v)) +#define AV1_HDR_ORDER_HINT_BITS(v) FIELD_PREP(GENMASK(3, 1), v) #define AV1_HDR_ORDER_HINT(v) FIELD_PREP(BIT(4), !!(v)) #define AV1_HDR_DUAL_FILTER(v) FIELD_PREP(BIT(5), !!(v)) #define AV1_HDR_MASKED_COMPOUND(v) FIELD_PREP(BIT(6), !!(v)) @@ -124,6 +128,12 @@ #define AV1_QP_BASE_IDX(v) FIELD_PREP(GENMASK(28, 21), v) #define AV1_QP_DELTA_RES(v) FIELD_PREP(GENMASK(30, 29), v) #define AV1_QP_PRESENT(v) FIELD_PREP(BIT(31), !!(v)) +#define AV1_QP_V_DC(v) FIELD_PREP(GENMASK(26, 20), v) +#define AV1_QP_V_AC(v) FIELD_PREP(GENMASK(19, 13), v) +#define AV1_QP_QMATRIX(v) FIELD_PREP(BIT(12), !!(v)) +#define AV1_QP_QM_Y(v) FIELD_PREP(GENMASK(11, 8), v) +#define AV1_QP_QM_U(v) FIELD_PREP(GENMASK(7, 4), v) +#define AV1_QP_QM_V(v) FIELD_PREP(GENMASK(3, 0), v) #define AV1_GM_VALID(v) FIELD_PREP(BIT(30), !!(v)) #define AV1_GM_TYPE(v) FIELD_PREP(GENMASK(31, 30), v) @@ -154,7 +164,6 @@ #define AV1_LF_REF2(v) FIELD_PREP(GENMASK(13, 7), v) #define AV1_LF_REF3(v) FIELD_PREP(GENMASK(6, 0), v) -#define AV1_LF_LV(v) FIELD_PREP(GENMASK(31, 14), v) #define AV1_LF_MODE0(v) FIELD_PREP(GENMASK(13, 7), v) #define AV1_LF_MODE1(v) FIELD_PREP(GENMASK(6, 0), v) @@ -174,14 +183,22 @@ #define AV1_LR_TYPE1(v) FIELD_PREP(GENMASK(9, 8), v) #define AV1_LR_TYPE2(v) FIELD_PREP(GENMASK(7, 6), v) -#define AV1_LR_UNIT0(v) FIELD_PREP(GENMASK(1, 0), v) +#define AV1_LR_UNIT2(v) FIELD_PREP(GENMASK(1, 0), v) #define AV1_LR_UNIT1(v) FIELD_PREP(GENMASK(3, 2), v) -#define AV1_LR_UNIT2(v) FIELD_PREP(GENMASK(5, 4), v) +#define AV1_LR_UNIT0(v) FIELD_PREP(GENMASK(5, 4), v) #define AV1_REF_ORDER_HINT(v) FIELD_PREP(GENMASK(23, 0), v) #define AV1_REF_SCALE_X(v) FIELD_PREP(GENMASK(31, 16), v) #define AV1_REF_SCALE_Y(v) FIELD_PREP(GENMASK(15, 0), v) +#define AV1_SUPERRES_USE(v) FIELD_PREP(BIT(31), !!(v)) +#define AV1_SUPERRES_DENOM(v) FIELD_PREP(GENMASK(30, 28), v) +/* im gonna asume 16 like the others */ +#define AV1_SUPERRES_UPSCALE(v) FIELD_PREP(GENMASK(16, 0), v) + +#define AV1_UPSCALE_STEPX(v) FIELD_PREP(GENMASK(13, 0), v) +#define AV1_UPSCALE_UPSCX(v) FIELD_PREP(GENMASK(31, 14), v) + #define AVD_CDFS_SIZE (sizeof(struct avd_av1_cdfs)) #define AVD_AV1_TLB_OFFSET(dst, tlb) \ @@ -350,15 +367,17 @@ static void set_refs(struct avd_ctx *ctx, struct avd_av1_run *run) int shift = (gm->flags[ref_idx] & V4L2_AV1_GLOBAL_MOTION_FLAG_IS_TRANSLATION) ? - WARPEDMODEL_PREC_BITS - 3 : - 10 /* why? */; + (WARPEDMODEL_PREC_BITS - + 2) - (frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV ? + 1 : + 0) : + 10; push(AV1_GM_TYPE(gm->type[ref_idx]) | AV1_GM_PARAM0(gm->params[ref_idx][0] >> shift) | AV1_GM_PARAM1(gm->params[ref_idx][1] >> shift), "ref_gm_mv"); - /* TODO: precison or something, does not always fit */ push(AV1_GM_VALID(!(V4L2_AV1_GLOBAL_MOTION_IS_INVALID( ref_idx) & gm->invalid)) | @@ -367,12 +386,8 @@ static void set_refs(struct avd_ctx *ctx, struct avd_av1_run *run) AV1_GM_PARAM1(AV1_DIV_ROUND_UP_POW2_SIGNED( gm->params[ref_idx][3], 1)), "ref_gm_param"); - /* TODO: this does not quite fit */ - push(AV1_GM_PARAM1(gm->params[ref_idx][5] / 2) | - AV1_GM_PARAM0(AV1_DIV_ROUND_UP_POW2_SIGNED( - gm->params[ref_idx][4] - - gm->params[ref_idx][3], - 2)), + push(AV1_GM_PARAM1(gm->params[ref_idx][5] >> 1) | + AV1_GM_PARAM0(gm->params[ref_idx][4] >> 1), "ref_gm_unk2"); avd_av1_dec_get_shear_params(&gm->params[ref_idx][0], &alpha, &beta, &gamma, @@ -588,6 +603,27 @@ static void set_ref_hdr(struct avd_ctx *ctx, struct avd_av1_run *run) "reference_select"); } +/* 7.16. Upscaling process */ +static void calc_upscale(int frame_width, int upscaled_width, int sub_x, + int *step_x, int *initial_subpel_x) +{ + int downscaled_plane_w, upscaled_plane_w, err; + + downscaled_plane_w = AV1_DIV_ROUND_UP_POW2(frame_width, sub_x); + upscaled_plane_w = AV1_DIV_ROUND_UP_POW2(upscaled_width, sub_x); + *step_x = ((downscaled_plane_w << SUPERRES_SCALE_BITS) + + (upscaled_plane_w / 2)) / + upscaled_plane_w; + err = (upscaled_plane_w * *step_x) - + (downscaled_plane_w << SUPERRES_SCALE_BITS); + *initial_subpel_x = (-((upscaled_plane_w - downscaled_plane_w) + << (SUPERRES_SCALE_BITS - 1)) + + upscaled_plane_w / 2) / + upscaled_plane_w + + (1 << (SUPERRES_EXTRA_BITS - 1)) - err / 2; + *initial_subpel_x &= SUPERRES_SCALE_MASK; +} + static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) { struct avd_av1_ctx *av1_ctx = ctx->priv; @@ -599,6 +635,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) struct avd_dev *avd = ctx->dev; u32 bytesperline; int i, segid, segval, ref_idx; + int step_x, initial_subpel_x; u8 selected_refs[3] = { 0, 0, 0 }; bool coded_lossless = frame->tx_mode == V4L2_AV1_TX_MODE_ONLY_4X4; bool intrabc = !!(frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC); @@ -646,6 +683,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) AV1_HDR_DUAL_FILTER( seq->flags & V4L2_AV1_SEQUENCE_FLAG_ENABLE_DUAL_FILTER) | + AV1_HDR_ORDER_HINT_BITS((seq->order_hint_bits - 1)) | AV1_HDR_ORDER_HINT( seq->flags & V4L2_AV1_SEQUENCE_FLAG_ENABLE_ORDER_HINT) | @@ -666,17 +704,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK) | AV1_HDR_SCREEN_CONTENT_TOOLS( frame->flags & - V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS) | - - /* TODO: this seems like a coincidence */ - !!!(seq->flags & V4L2_AV1_SEQUENCE_FLAG_ENABLE_ORDER_HINT) - << 1 | - !!(seq->flags & - V4L2_AV1_SEQUENCE_FLAG_ENABLE_WARPED_MOTION) - << 2 | - !!(seq->flags & - V4L2_AV1_SEQUENCE_FLAG_ENABLE_MASKED_COMPOUND) - << 3, + V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS), "hdr_common"); push(AV1_FLAGS_TX_MODE_LARGEST(frame->tx_mode == @@ -826,10 +854,15 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) AV1_QP_U_AC(frame->quantization.delta_q_u_ac), "qp_base_q_idx"); - /* TODO: test294 test35 */ - push(0, "unk"); + push(AV1_QP_V_DC(frame->quantization.delta_q_v_dc) | + AV1_QP_V_AC(frame->quantization.delta_q_v_ac) | + AV1_QP_QMATRIX(frame->quantization.flags & + V4L2_AV1_QUANTIZATION_FLAG_USING_QMATRIX) | + AV1_QP_QM_Y(frame->quantization.qm_y) | + AV1_QP_QM_U(frame->quantization.qm_u) | + AV1_QP_QM_V(frame->quantization.qm_v), + "qp_qm"); - /* TODO */ push(AV1_LF_DELTA_ENABLED(frame->loop_filter.flags & V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED) | AV1_LF_DELTA_PRESENT( @@ -839,14 +872,14 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) frame->loop_filter.flags & V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_MULTI) | AV1_LF_DELTA_RES(frame->loop_filter.delta_lf_res) | - + AV1_LF_SHARPNESS(frame->loop_filter.sharpness) | AV1_LF_LV0(frame->loop_filter.level[0]) | AV1_LF_LV1(frame->loop_filter.level[1]) | AV1_LF_LV2(frame->loop_filter.level[2]) | AV1_LF_LV3(frame->loop_filter.level[3]), "lf_update"); - push(AV1_LF_SHARPNESS(frame->loop_filter.sharpness) | - AV1_LF_REF0(frame->loop_filter.ref_deltas[0]) | + + push(AV1_LF_REF0(frame->loop_filter.ref_deltas[0]) | AV1_LF_REF1(frame->loop_filter.ref_deltas[1]) | AV1_LF_REF2(frame->loop_filter.ref_deltas[2]) | AV1_LF_REF3(frame->loop_filter.ref_deltas[3]), @@ -857,8 +890,10 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) AV1_LF_REF2(frame->loop_filter.ref_deltas[6]) | AV1_LF_REF3(frame->loop_filter.ref_deltas[7]), "lf_ref_deltas"); - /* TODO */ - push(0, "lf_unk"); + + push(AV1_LF_MODE0(frame->loop_filter.mode_deltas[0]) | + AV1_LF_MODE1(frame->loop_filter.mode_deltas[1]), + "lf_mode"); #define AVD_AV1_SEC_FIXUP(i) ((i) == 4 ? 3 : i) @@ -881,16 +916,23 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) #undef AV1_CDEF_PACK_ONE #undef AV1_CDEF_PACK - push((frame->flags & V4L2_AV1_FRAME_FLAG_USE_SUPERRES << 31) | - /* TODO: this is wrong, has something to do with superres */ - (frame->flags & V4L2_AV1_FRAME_FLAG_USE_SUPERRES ? - (frame->superres_denom - 1) << 28 : - 0) | - (frame->upscaled_width - 1), - "upscaled_width"); - /* something superres related? test35 */ - push(0x200000, "flag_unk0"); - push(0x200000, "flag_unk1"); + push(AV1_SUPERRES_USE(frame->flags & V4L2_AV1_FRAME_FLAG_USE_SUPERRES) | + AV1_SUPERRES_DENOM( + frame->flags & V4L2_AV1_FRAME_FLAG_USE_SUPERRES ? + (frame->superres_denom - 1) : + 0) | + AV1_SUPERRES_UPSCALE(frame->upscaled_width - 1), + "superres"); + + calc_upscale(frame->frame_width_minus_1 + 1, frame->upscaled_width, 0, + &step_x, &initial_subpel_x); + push(AV1_UPSCALE_UPSCX(initial_subpel_x) | AV1_UPSCALE_STEPX(step_x), + "upscale_p0"); + calc_upscale(frame->frame_width_minus_1 + 1, frame->upscaled_width, + !!(seq->flags & V4L2_AV1_SEQUENCE_FLAG_SUBSAMPLING_X), + &step_x, &initial_subpel_x); + push(AV1_UPSCALE_UPSCX(initial_subpel_x) | AV1_UPSCALE_STEPX(step_x), + "upscale_p1"); u8 restoration_unit_size[V4L2_AV1_NUM_PLANES_MAX] = { 3, 3, 3 }; @@ -943,8 +985,8 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) push(0, "mark_section"); - push(AVD_HDR_HEIGHT(frame->frame_height_minus_1) | - AVD_HDR_WIDTH(frame->frame_width_minus_1), + push(AVD_HDR_HEIGHT(frame->render_height_minus_1 + 1) | + AVD_HDR_WIDTH(frame->render_width_minus_1 + 1), "height_width_3"); if (!intra_only || intrabc) set_refs(ctx, run); From 1d333633ab3596aef9af8f8009e381f2ab995cf0 Mon Sep 17 00:00:00 2001 From: sofus Date: Wed, 2 Sep 2026 21:09:31 +0200 Subject: [PATCH 3/5] media: apple: avd: rename buffers Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-av1.c | 199 ++++++++++---------- drivers/media/platform/apple/avd/avd-h264.c | 59 +++--- drivers/media/platform/apple/avd/avd-hevc.c | 102 +++++----- drivers/media/platform/apple/avd/avd-inst.h | 12 ++ drivers/media/platform/apple/avd/avd-vp9.c | 78 ++++---- drivers/media/platform/apple/avd/avd.h | 2 +- 6 files changed, 222 insertions(+), 230 deletions(-) diff --git a/drivers/media/platform/apple/avd/avd-av1.c b/drivers/media/platform/apple/avd/avd-av1.c index a34ee366febc55..9328e088c14ebe 100644 --- a/drivers/media/platform/apple/avd/avd-av1.c +++ b/drivers/media/platform/apple/avd/avd-av1.c @@ -199,19 +199,19 @@ #define AV1_UPSCALE_STEPX(v) FIELD_PREP(GENMASK(13, 0), v) #define AV1_UPSCALE_UPSCX(v) FIELD_PREP(GENMASK(31, 14), v) -#define AVD_CDFS_SIZE (sizeof(struct avd_av1_cdfs)) +#define AVD_CDFS_SIZE sizeof(struct avd_av1_cdfs) -#define AVD_AV1_TLB_OFFSET(dst, tlb) \ - ((dst) - ALIGN(tlb, AVD_ALIGN)) -#define AVD_AV1_CDFS_OFFSET(dst, tlb) \ - (AVD_AV1_TLB_OFFSET(dst, tlb) - ALIGN(AVD_CDFS_SIZE, AVD_ALIGN)) +#define AVD_AV1_COLOR_OFFSET(dst, cl) \ + ((dst) - ALIGN(cl, AVD_ALIGN)) +#define AVD_AV1_CDFS_OFFSET(dst, cl) \ + (AVD_AV1_COLOR_OFFSET(dst, cl) - ALIGN(AVD_CDFS_SIZE, AVD_ALIGN)) struct avd_av1_run { struct avd_run base; struct { dma_addr_t probs_out; - dma_addr_t priv_tlb; + dma_addr_t color; } addresses; const struct v4l2_ctrl_av1_sequence *seq; @@ -225,14 +225,21 @@ struct avd_av1_ctx { struct { struct avd_buf inst; struct avd_buf pipe_state; - struct avd_buf unk[2]; struct avd_buf probs; + struct avd_buf seg; + struct avd_buf above_info; + struct avd_buf rf_above_info; + struct avd_buf az_above; + struct avd_buf ip_above; + struct avd_buf lf_above; + struct avd_buf lf_above_info; + struct avd_buf lf_left; + struct avd_buf lf_left_info; + struct avd_buf sr_left; + struct avd_buf rf_left; + struct avd_buf rf_left_info; + struct avd_buf mv_above_info; } bufs; - struct { - struct avd_buf tile_col[4]; - struct avd_buf tile_row[4]; - struct avd_buf ref; - } scratch; }; /* @@ -345,7 +352,7 @@ static void set_refs(struct avd_ctx *ctx, struct avd_av1_run *run) dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); push(0, "ref_cnst0"); - pusha(av1_ctx->scratch.ref.addr, "unk_ref_buf", 0); + pusha(av1_ctx->bufs.mv_above_info.addr, "mv_above_info", 0); for (i = 0; i < 4; i++) push(0, "ref_cnst1"); @@ -742,7 +749,6 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) AV1_FLAGS_SEG_TEMPORAL_UPDATE( frame->segmentation.flags & V4L2_AV1_SEGMENTATION_FLAG_TEMPORAL_UPDATE) | - /* is this false? its always true if buf0 is set */ AV1_FLAGS_SEG_UPDATE_MAP( frame->segmentation.flags & V4L2_AV1_SEGMENTATION_FLAG_UPDATE_MAP) | @@ -816,14 +822,11 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) pusha(run->addresses.probs_out, "probs_out", 0); pusha(av1_ctx->bufs.probs.addr, "probs", 1); - - pusha(av1_ctx->scratch.tile_col[0].addr, "col", 0); - - /* TODO */ - pusha((dma_addr_t)0, "", 0); - pusha((dma_addr_t)0, "", 1); - - pusha(run->addresses.priv_tlb, "cur_ref_addr", 0); + pusha(av1_ctx->bufs.above_info.addr, "col", 0); + pusha(av1_ctx->bufs.seg.addr, "seg", 0); + /* make it obvious if its used */ + pusha((dma_addr_t)0xb0b0b0b0b0b0, "", 1); + pusha(run->addresses.color, "w_color", 0); for (i = 0; i < 3; i++) { if (selected_refs[i] < V4L2_AV1_REF_LAST_FRAME) { @@ -837,11 +840,11 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) ref_addr = vb2_dma_contig_plane_dma_addr( &ref->base.vb.vb2_buf, 0) + - AVD_AV1_TLB_OFFSET( + AVD_AV1_COLOR_OFFSET( ref->base.vb.vb2_buf.planes[0].length, - ref->av1.priv_tlb_size); + ref->av1.color_size); - pusha(ref_addr, "ref", ref_idx); + pusha(ref_addr, "r_color", ref_idx); } } @@ -957,24 +960,23 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) push(0, ""); push(0, ""); pusha(av1_ctx->bufs.pipe_state.addr, "pipe_state", 0); - pusha(av1_ctx->scratch.tile_col[1].addr, "col", 1); - pusha(av1_ctx->scratch.tile_col[2].addr, "col", 2); - pusha(av1_ctx->scratch.tile_col[3].addr, "col", 3); - - pusha(av1_ctx->scratch.tile_row[0].addr, "row", 0); - pusha(av1_ctx->scratch.tile_row[1].addr, "row", 1); - pusha(0, "unk", 0); - pusha(av1_ctx->bufs.unk[0].addr, "unk", 0); - pusha(av1_ctx->scratch.tile_row[2].addr, "row", 2); - pusha(av1_ctx->bufs.unk[1].addr, "unk", 1); - pusha(av1_ctx->scratch.tile_row[3].addr, "row", 3); + pusha(av1_ctx->bufs.ip_above.addr, "ip_above", 0); + pusha(av1_ctx->bufs.lf_above.addr, "lf_above", 2); + pusha(av1_ctx->bufs.lf_above_info.addr, "lf_above_info", 3); + pusha(av1_ctx->bufs.lf_left.addr, "lf_left", 0); + pusha(av1_ctx->bufs.lf_left_info.addr, "lf_left_info", 1); + /* make it obvious if its used */ + pusha((dma_addr_t)0xa0a0a0a0a0a0, "", 0); + pusha(av1_ctx->bufs.rf_above_info.addr, "rf_above_info", 0); + pusha(av1_ctx->bufs.sr_left.addr, "sr_left", 2); + pusha(av1_ctx->bufs.rf_left_info.addr, "rf_left_info", 1); + pusha(av1_ctx->bufs.rf_left.addr, "rf_left", 3); push(0, "mark_section"); push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); - push(0, ""); - push(0, "mark_section"); + pusha((u64)0, "packed_fmt_scratch", 0); /* ignored if decomp is disabled */ bytesperline = ctx->decoded_fmt.fmt.pix_mp.plane_fmt[0].bytesperline; @@ -1090,7 +1092,7 @@ static void avd_av1_set_prob(struct avd_ctx *ctx, struct avd_av1_run *run) vb2_plane_vaddr(&ref->base.vb.vb2_buf, 0) + AVD_AV1_CDFS_OFFSET( ref->base.vb.vb2_buf.planes[0].length, - ref->av1.priv_tlb_size), + ref->av1.color_size), sizeof(struct avd_av1_cdfs)); } @@ -1100,11 +1102,11 @@ static void avd_av1_set_prob(struct avd_ctx *ctx, struct avd_av1_run *run) */ memcpy(vb2_plane_vaddr(&dst->base.vb.vb2_buf, 0) + AVD_AV1_CDFS_OFFSET(dst->base.vb.vb2_buf.planes[0].length, - dst->av1.priv_tlb_size), + dst->av1.color_size), av1_ctx->bufs.probs.cpu, sizeof(struct avd_av1_cdfs)); } -static int avd_priv_tlb_size(int h, int w) +static int avd_color_size(int h, int w) { /* * in reality its dependent on quality @@ -1125,9 +1127,8 @@ static void update_dec_buf_info(struct avd_decoded_buffer *buf, buf->av1.frame_type = frame->frame_type; buf->av1.intrabc = frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC; - buf->av1.priv_tlb_size = - avd_priv_tlb_size(frame->frame_width_minus_1 + 1, - frame->frame_height_minus_1 + 1); + buf->av1.color_size = avd_color_size(frame->frame_width_minus_1 + 1, + frame->frame_height_minus_1 + 1); for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++) buf->av1.order_hints[i] = frame->order_hints[i]; @@ -1166,67 +1167,81 @@ static int avd_av1_run_preamble(struct avd_ctx *ctx, struct avd_av1_run *run) run->grain = ctrl->p_cur.p; dst_len = run->base.bufs.dst->vb2_buf.planes[0].length; - tlb_len = avd_priv_tlb_size(run->frame->frame_width_minus_1 + 1, - run->frame->frame_height_minus_1 + 1); + tlb_len = avd_color_size(run->frame->frame_width_minus_1 + 1, + run->frame->frame_height_minus_1 + 1); - run->addresses.priv_tlb = - run->base.y_out + AVD_AV1_TLB_OFFSET(dst_len, tlb_len); + run->addresses.color = + run->base.y_out + AVD_AV1_COLOR_OFFSET(dst_len, tlb_len); run->addresses.probs_out = run->base.y_out + AVD_AV1_CDFS_OFFSET(dst_len, tlb_len); return 0; } -static int avd_av1_alloc_scratch(struct avd_ctx *ctx, struct avd_av1_run *run) +static int avd_av1_alloc_work_bufs(struct avd_ctx *ctx, struct avd_av1_run *run) { struct avd_dev *avd = ctx->dev; struct avd_av1_ctx *av1_ctx = ctx->priv; const struct v4l2_ctrl_av1_frame *frame = run->frame; const struct v4l2_ctrl_av1_sequence *seq = run->seq; const struct v4l2_av1_tile_info *tile_info = &frame->tile_info; - int ret, max_sb_col = 0, max_sb_row = 0, i, sb_cols = 0, sb; + int ret, max_sb_col = 0, max_sb_row = 0, i, sb_cols1 = 0, sb_cols2 = 0, + sb; int sb_shift = seq->flags & V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK ? 1 : 0; int w = frame->frame_width_minus_1 + 1; + int h = frame->frame_height_minus_1 + 1; int bit_depth = seq->bit_depth; for (i = 0; i < tile_info->tile_cols; i++) { sb = tile_info->width_in_sbs_minus_1[i] + 1; max_sb_col = sb > max_sb_col ? sb : max_sb_col; - sb_cols += ALIGN((sb << sb_shift) * 44, 128); + sb_cols1 += ALIGN((sb << sb_shift) * 44, 128); + /* wrong alignment? */ + sb_cols2 += ALIGN((sb << sb_shift) * 12, 128); } max_sb_col <<= sb_shift; - ret = avd_buf_alloc(avd, &av1_ctx->scratch.ref, max_sb_col * 80); + ret = avd_buf_alloc(avd, &av1_ctx->bufs.mv_above_info, max_sb_col * 80); if (ret) return ret; /* first frame this is always much smaller */ - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_col[0], - (max_sb_col * 400)); + ret = avd_buf_alloc(avd, &av1_ctx->bufs.above_info, max_sb_col * 400); if (ret) return ret; - /* first frame this is always 0 */ - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_col[3], sb_cols); + ret = avd_buf_alloc(avd, &av1_ctx->bufs.lf_above_info, sb_cols1); if (ret) return ret; - /* i think this is the metadata buffer to the one below */ - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_col[1], - (max_sb_col * bit_depth * 22)); + ret = avd_buf_alloc(avd, &av1_ctx->bufs.ip_above, + max_sb_col * bit_depth * 22); if (ret) return ret; - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_col[2], + ret = avd_buf_alloc(avd, &av1_ctx->bufs.lf_above, ALIGN(ALIGN(w, 8) * bit_depth * 2 + tile_info->tile_cols * bit_depth * 16, 128)); if (ret) return ret; + ret = avd_buf_alloc(avd, &av1_ctx->bufs.rf_above_info, sb_cols2); + if (ret) + return ret; + + if (frame->segmentation.flags & V4L2_AV1_SEGMENTATION_FLAG_UPDATE_MAP) { + ret = avd_buf_alloc( + avd, &av1_ctx->bufs.seg, + (ALIGN(h, 64 << sb_shift) * ALIGN(w, 64 << sb_shift)) / + 128 * 3); + if (ret) + return ret; + } + /* this is not a mistake, but im not sure why */ if (tile_info->tile_cols > 1) { for (i = 0; i < tile_info->tile_rows; i++) { @@ -1236,12 +1251,8 @@ static int avd_av1_alloc_scratch(struct avd_ctx *ctx, struct avd_av1_run *run) max_sb_row = max_sb_row << sb_shift; - /* - * metadata buffer maybe? At least for row[0], they all seem to have - * some kinda alignment to 24 so could be for them all - */ - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_row[1], - (max_sb_row * 72)); + ret = avd_buf_alloc(avd, &av1_ctx->bufs.lf_left_info, + max_sb_row * 72); if (ret) return ret; @@ -1255,22 +1266,27 @@ static int avd_av1_alloc_scratch(struct avd_ctx *ctx, struct avd_av1_run *run) * I counted blocks as luma or chroma with padding until it * changes to the other */ - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_row[0], + ret = avd_buf_alloc(avd, &av1_ctx->bufs.lf_left, (max_sb_row * 72 + 1) * 2 * bit_depth); if (ret) return ret; - ret = avd_buf_alloc(avd, &av1_ctx->scratch.tile_row[2], + ret = avd_buf_alloc(avd, &av1_ctx->bufs.sr_left, max_sb_row * bit_depth * (53 + 52)); if (ret) return ret; ret = avd_buf_alloc( - avd, &av1_ctx->scratch.tile_row[3], + avd, &av1_ctx->bufs.rf_left, max_sb_row * bit_depth * (192 + 96 + (bit_depth > 8 ? 12 : 0))); if (ret) return ret; + + ret = avd_buf_alloc(avd, &av1_ctx->bufs.rf_left_info, + max_sb_row * 24); + if (ret) + return ret; } return 0; @@ -1307,7 +1323,7 @@ static int avd_av1_run(struct avd_ctx *ctx) ctx->fifo_idx, ctx->vp_slot); avd_av1_set_prob(ctx, &run); - avd_av1_alloc_scratch(ctx, &run); + avd_av1_alloc_work_bufs(ctx, &run); set_header(ctx, &run); set_tiles(ctx, &run); @@ -1317,21 +1333,6 @@ static int avd_av1_run(struct avd_ctx *ctx) return 0; } -static void avd_av1_dealloc_scratch(struct avd_ctx *ctx) -{ - struct avd_dev *avd = ctx->dev; - struct avd_av1_ctx *av1_ctx = ctx->priv; - int i; - - for (i = 0; i < 4; i++) - avd_buf_free(avd, &av1_ctx->scratch.tile_col[i]); - - for (i = 0; i < 4; i++) - avd_buf_free(avd, &av1_ctx->scratch.tile_row[i]); - - avd_buf_free(avd, &av1_ctx->scratch.ref); -} - static int avd_av1_alloc_bufs(struct avd_ctx *ctx) { struct avd_dev *avd = ctx->dev; @@ -1352,14 +1353,6 @@ static int avd_av1_alloc_bufs(struct avd_ctx *ctx) if (ret) return ret; - ret = avd_buf_alloc(avd, &av1_ctx->bufs.unk[0], 1024); - if (ret) - return ret; - - ret = avd_buf_alloc(avd, &av1_ctx->bufs.unk[1], 1024); - if (ret) - return ret; - return 0; } @@ -1390,15 +1383,23 @@ static void avd_av1_stop(struct avd_ctx *ctx) struct avd_av1_ctx *av1_ctx = ctx->priv; struct avd_dev *avd = ctx->dev; - avd_av1_dealloc_scratch(ctx); + avd_buf_free(avd, &av1_ctx->bufs.rf_above_info); + avd_buf_free(avd, &av1_ctx->bufs.az_above); + avd_buf_free(avd, &av1_ctx->bufs.ip_above); + avd_buf_free(avd, &av1_ctx->bufs.lf_above); + avd_buf_free(avd, &av1_ctx->bufs.lf_above_info); + avd_buf_free(avd, &av1_ctx->bufs.lf_left); + avd_buf_free(avd, &av1_ctx->bufs.lf_left_info); + avd_buf_free(avd, &av1_ctx->bufs.sr_left); + avd_buf_free(avd, &av1_ctx->bufs.rf_left); + avd_buf_free(avd, &av1_ctx->bufs.rf_left_info); + avd_buf_free(avd, &av1_ctx->bufs.seg); + avd_buf_free(avd, &av1_ctx->bufs.mv_above_info); avd_buf_free(avd, &av1_ctx->bufs.pipe_state); avd_buf_free(avd, &av1_ctx->bufs.inst); avd_buf_free(avd, &av1_ctx->bufs.probs); - for (int i = 0; i < 2; i++) - avd_buf_free(avd, &av1_ctx->bufs.unk[i]); - kfree(av1_ctx); } @@ -1465,8 +1466,8 @@ static void avd_av1_adjust_decoded_fmt(struct avd_ctx *ctx, struct v4l2_pix_format_mplane *pix_mp) { pix_mp->plane_fmt[0].sizeimage += ALIGN(AVD_CDFS_SIZE, AVD_ALIGN); - pix_mp->plane_fmt[0].sizeimage += ALIGN( - avd_priv_tlb_size(pix_mp->width, pix_mp->height), AVD_ALIGN); + pix_mp->plane_fmt[0].sizeimage += + ALIGN(avd_color_size(pix_mp->width, pix_mp->height), AVD_ALIGN); } static int avd_av1_validate_sequence(struct avd_ctx *ctx, diff --git a/drivers/media/platform/apple/avd/avd-h264.c b/drivers/media/platform/apple/avd/avd-h264.c index 1c8938a05a9a43..44656e8c1a892b 100644 --- a/drivers/media/platform/apple/avd/avd-h264.c +++ b/drivers/media/platform/apple/avd/avd-h264.c @@ -43,7 +43,7 @@ struct avd_h264_run { const struct v4l2_ctrl_h264_pred_weights *pred_weights; struct run_addr { - dma_addr_t sps; + dma_addr_t mv_color; } addresses; s32 cur_poc; @@ -59,9 +59,13 @@ struct avd_h264_ctx { } reflists; struct avd_h264_bufs { - struct avd_buf pps_tile[5]; struct avd_buf inst; struct avd_buf pipe_state; + struct avd_buf above_info; + struct avd_buf lf_above_info; + struct avd_buf lf_above; + struct avd_buf ip_above; + struct avd_buf mv_above_info; } bufs; }; @@ -81,7 +85,7 @@ static const u32 default_8x8_inter[] = { 0x191b1c1e, 0x1b1c1e20, 0x1c1e2021, 0x1e202123, }; -static inline u32 sps_size(u32 w, u32 h) +static inline u32 mv_color_size(u32 w, u32 h) { return (DIV_ROUND_UP(w, 16) + 1) * (DIV_ROUND_UP(h, 16) + 1) * 64; } @@ -100,8 +104,8 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_h264_run *run) dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); push(0, ""); - pusha(h264_ctx->bufs.pps_tile[4].addr, "hdr_9c_pps_tile_addr_lsb8", 7); - pusha(run->addresses.sps, "hdr_bc_sps_tile_addr_lsb8", 0); + pusha(h264_ctx->bufs.mv_above_info.addr, "mv_above_info", 7); + pusha(run->addresses.mv_color, "mv_color", 0); push(0, ""); push(0, ""); @@ -260,7 +264,7 @@ static void stream_hdr(struct avd_ctx *ctx, struct avd_h264_run *run) if (avd->variant->revision == 3) push(0, "zero"); - pusha(h264_ctx->bufs.pps_tile[0].addr, "hdr_9c_pps_tile_addr_lsb8", 0); + pusha(h264_ctx->bufs.above_info.addr, "hdr_9c_pps_tile_addr_lsb8", 0); push(0, ""); push(0, ""); @@ -270,9 +274,9 @@ static void stream_hdr(struct avd_ctx *ctx, struct avd_h264_run *run) else if (!(avd->variant->quirks & AVD_QUIRK_NO_PIPE_STATE)) pusha(h264_ctx->bufs.pipe_state.addr, "pipe_state", 0); - pusha(h264_ctx->bufs.pps_tile[1].addr, "hdr_9c_pps_tile_addr_lsb8", 1); - pusha(h264_ctx->bufs.pps_tile[2].addr, "hdr_9c_pps_tile_addr_lsb8", 2); - pusha(h264_ctx->bufs.pps_tile[3].addr, "hdr_9c_pps_tile_addr_lsb8", 3); + pusha(h264_ctx->bufs.ip_above.addr, "ip_above", 1); + pusha(h264_ctx->bufs.lf_above.addr, "lf_above", 2); + pusha(h264_ctx->bufs.lf_above_info.addr, "lf_above_info", 3); push(0, ""); push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); @@ -498,14 +502,14 @@ static u32 stream_slice(struct avd_ctx *ctx, struct avd_h264_run *run) &ctx->fh.m2m_ctx->cap_q_ctx.q, decode->dpb[sl->ref_pic_list1[0].index].reference_ts); - dma_addr_t sps_tile_addr = + dma_addr_t mv_color_addr = vb ? vb2_dma_contig_plane_dma_addr(vb, 0) + (vb->planes[0].length - - sps_size(fmt_width(ctx), - fmt_height(ctx))) : - run->addresses.sps; + mv_color_size(fmt_width(ctx), + fmt_height(ctx))) : + run->addresses.mv_color; - pusha(sps_tile_addr, "slc_a78_sps_tile_addr2_lsb8", 0); + pusha(mv_color_addr, "slc_a78_sps_tile_addr2_lsb8", 0); } /* only submit if this is the last slice */ @@ -544,25 +548,24 @@ static int avd_h264_alloc_bufs(struct avd_ctx *ctx) mb = DIV_ROUND_UP(w, 16); - ret = avd_buf_alloc(dev, &h264_ctx->bufs.pps_tile[0], mb * 20); + ret = avd_buf_alloc(dev, &h264_ctx->bufs.above_info, mb * 20); if (ret) return ret; - ret = avd_buf_alloc(dev, &h264_ctx->bufs.pps_tile[1], - bit_depth * 4 * mb); + ret = avd_buf_alloc(dev, &h264_ctx->bufs.ip_above, bit_depth * 4 * mb); if (ret) return ret; - ret = avd_buf_alloc(dev, &h264_ctx->bufs.pps_tile[2], + ret = avd_buf_alloc(dev, &h264_ctx->bufs.lf_above, bit_depth * 4 * 4 * mb); if (ret) return ret; - ret = avd_buf_alloc(dev, &h264_ctx->bufs.pps_tile[3], 32 * mb); + ret = avd_buf_alloc(dev, &h264_ctx->bufs.lf_above_info, 32 * mb); if (ret) return ret; - ret = avd_buf_alloc(dev, &h264_ctx->bufs.pps_tile[4], 32 * mb); + ret = avd_buf_alloc(dev, &h264_ctx->bufs.mv_above_info, 32 * mb); if (ret) return ret; @@ -579,9 +582,11 @@ static void avd_h264_free_bufs(struct avd_ctx *ctx) avd_buf_free(dev, &h264_ctx->bufs.pipe_state); avd_buf_free(dev, &h264_ctx->bufs.inst); - - for (int i = 0; i < 5; i++) - avd_buf_free(dev, &h264_ctx->bufs.pps_tile[i]); + avd_buf_free(dev, &h264_ctx->bufs.above_info); + avd_buf_free(dev, &h264_ctx->bufs.lf_above_info); + avd_buf_free(dev, &h264_ctx->bufs.lf_above); + avd_buf_free(dev, &h264_ctx->bufs.ip_above); + avd_buf_free(dev, &h264_ctx->bufs.mv_above_info); kfree(h264_ctx); } @@ -657,7 +662,7 @@ static void avd_h264_stop(struct avd_ctx *ctx) static void avd_h264_run_preamble(struct avd_ctx *ctx, struct avd_h264_run *run) { struct v4l2_ctrl *ctrl; - u32 dst_len, sps_len; + u32 dst_len, mv_color_len; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_H264_DECODE_PARAMS); @@ -680,9 +685,9 @@ static void avd_h264_run_preamble(struct avd_ctx *ctx, struct avd_h264_run *run) dst_len = run->base.bufs.dst->vb2_buf.planes[0].length; - sps_len = sps_size(fmt_width(ctx), fmt_height(ctx)); + mv_color_len = mv_color_size(fmt_width(ctx), fmt_height(ctx)); - run->addresses.sps = run->base.y_out + (dst_len - sps_len); + run->addresses.mv_color = run->base.y_out + (dst_len - mv_color_len); } static int avd_h264_run(struct avd_ctx *ctx) @@ -786,7 +791,7 @@ static void avd_h264_adjust_decoded_fmt(struct avd_ctx *ctx, struct v4l2_pix_format_mplane *pix_mp) { pix_mp->plane_fmt[0].sizeimage += - sps_size(pix_mp->width, pix_mp->height); + mv_color_size(pix_mp->width, pix_mp->height); } static int avd_h264_try_ctrl(struct avd_ctx *ctx, struct v4l2_ctrl *ctrl) diff --git a/drivers/media/platform/apple/avd/avd-hevc.c b/drivers/media/platform/apple/avd/avd-hevc.c index 4f47c5124bef7c..905f7ae7f599be 100644 --- a/drivers/media/platform/apple/avd/avd-hevc.c +++ b/drivers/media/platform/apple/avd/avd-hevc.c @@ -52,7 +52,7 @@ #define HEVC_SCL_DIMS 0x127ffff -static inline u32 sps_size(u32 w, u32 h) +static inline u32 mv_color_size(u32 w, u32 h) { /* this will waste some memory when max cu size != 64 */ return DIV_ROUND_UP(w, 64) * DIV_ROUND_UP(h, 64) * 256; @@ -80,7 +80,7 @@ struct avd_hevc_run { int num_slices; struct run_addr { - dma_addr_t sps; + dma_addr_t mv_color; } addresses; struct avd_hevc_tile_info tile_info; @@ -90,7 +90,14 @@ struct avd_hevc_ctx { struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix_cache; struct avd_h264_bufs { - struct avd_buf pps_tile[9]; + struct avd_buf mv_above_info; + struct avd_buf az_above; + struct avd_buf ip_above; + struct avd_buf lf_above; + struct avd_buf lf_above_info; + struct avd_buf lf_left; + struct avd_buf lf_left_info; + struct avd_buf sw_left; struct avd_buf inst; struct avd_buf pipe_state; } bufs; @@ -110,9 +117,8 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_hevc_run *run) dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); push(0, ""); - pusha(hevc_ctx->bufs.pps_tile[1].addr, "hdr_9c_pps_tile_addr_lsb8", 7); - pusha(run->addresses.sps, "hdr_bc_sps_tile_addr_lsb8", - sl->slice_pic_order_cnt); + pusha(hevc_ctx->bufs.mv_above_info.addr, "mv_above_info", 7); + pusha(run->addresses.mv_color, "mv_color", 0); push(0, ""); push(0, ""); @@ -365,35 +371,19 @@ static void set_header(struct avd_ctx *ctx, struct avd_hevc_run *run) else if (!(avd->variant->quirks & AVD_QUIRK_NO_PIPE_STATE)) pusha(hevc_ctx->bufs.pipe_state.addr, "pipe_state", 0); - pusha(hevc_ctx->bufs.pps_tile[0].addr, "hdr_dc_pps_tile_addr_lsb8", 0); - pusha(hevc_ctx->bufs.pps_tile[2].addr, "hdr_dc_pps_tile_addr_lsb8", 1); - pusha(hevc_ctx->bufs.pps_tile[3].addr, "hdr_dc_pps_tile_addr_lsb8", 2); - - if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) { - pusha(hevc_ctx->bufs.pps_tile[4].addr, - "hdr_dc_pps_tile_addr_lsb8", 3); - pusha(hevc_ctx->bufs.pps_tile[5].addr, - "hdr_dc_pps_tile_addr_lsb8", 4); - pusha(hevc_ctx->bufs.pps_tile[6].addr, - "hdr_dc_pps_tile_addr_lsb8", 8); - pusha(hevc_ctx->bufs.pps_tile[7].addr, - "hdr_dc_pps_tile_addr_lsb8", 9); - } else { - pusha(0, "", 3); - pusha(0, "", 4); - pusha(hevc_ctx->bufs.pps_tile[8].addr, - "hdr_dc_pps_tile_addr_lsb8", 8); - pusha(0, "", 9); - } + pusha(hevc_ctx->bufs.ip_above.addr, "ip_above", 0); + pusha(hevc_ctx->bufs.lf_above.addr, "lf_above", 1); + pusha(hevc_ctx->bufs.lf_above_info.addr, "lf_above_info", 2); + pusha(hevc_ctx->bufs.lf_left.addr, "lf_left", 3); + pusha(hevc_ctx->bufs.lf_left_info.addr, "lf_left_info", 4); + pusha(hevc_ctx->bufs.az_above.addr, "az_above", 8); + pusha(hevc_ctx->bufs.sw_left.addr, "sw_left", 9); push(0, ""); push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); - push(0, "cm3_mark_end_section"); - - if (!(avd->variant->quirks & AVD_QUIRK_LSR)) - push(0, "cm3_mark_end_section"); + pusha((u64)0, "packed_fmt_scratch", 0); bytesperline = ctx->decoded_fmt.fmt.pix_mp.plane_fmt[0].bytesperline; if (avd->variant->quirks & AVD_QUIRK_LSR) @@ -648,12 +638,12 @@ static void stream_slice_mv(struct avd_ctx *ctx, struct avd_hevc_run *run, "slc_a8c_cmd_ref_type"); if (ref_valid) { - dma_addr_t sps_tile_addr = + dma_addr_t mv_color_addr = vb2_dma_contig_plane_dma_addr(&ref->base.vb.vb2_buf, 0) + (ref->base.vb.planes[0].length - - sps_size(fmt_width(ctx), fmt_height(ctx))); - pusha(sps_tile_addr, "slc_bd4_sps_tile_addr2_lsb8", + mv_color_size(fmt_width(ctx), fmt_height(ctx))); + pusha(mv_color_addr, "slc_bd4_sps_tile_addr2_lsb8", decode->dpb[ref_list[sl->collocated_ref_idx]] .pic_order_cnt_val); } @@ -1039,7 +1029,7 @@ static void avd_hevc_adjust_decoded_fmt(struct avd_ctx *ctx, struct v4l2_pix_format_mplane *pix_mp) { pix_mp->plane_fmt[0].sizeimage += - sps_size(pix_mp->width, pix_mp->height); + mv_color_size(pix_mp->width, pix_mp->height); } static enum avd_image_fmt avd_hevc_get_image_fmt(struct avd_ctx *ctx, @@ -1154,52 +1144,51 @@ static int avd_hevc_alloc_scratch(struct avd_ctx *ctx, struct avd_hevc_run *run) tile_info->row_height[i] : max_row; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[0], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.ip_above, ((max_col * max_cu_width) / 4) * bit_depth); if (ret) return ret; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[1], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.mv_above_info, ((max_col * max_cu_width) / 16) * 20); if (ret) return ret; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[2], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.lf_above, DIV_ROUND_UP(w, 16) * bit_depth * (10 + 6) + (cols - 1) * 256); if (ret) return ret; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[3], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.lf_above_info, DIV_ROUND_UP(w + 7, 16) * 36 + cols * 128); if (ret) return ret; if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) { - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[4], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.lf_left, ((max_row * max_cu_width) / 4) * 36 + 144 /* why? */); if (ret) return ret; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[5], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.lf_left_info, ((max_row * max_cu_width) / 4) * 9); if (ret) return ret; - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[6], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.az_above, /* not sure if its cols or rows */ DIV_ROUND_UP(w, 64) * 144 + (cols - 1) * 128); if (ret) return ret; - /* 5 or 3 is info? */ - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[7], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.sw_left, ((max_row * max_cu_width) / 4) * 216); if (ret) return ret; } else { - ret = avd_buf_alloc(avd, &hevc_ctx->bufs.pps_tile[8], + ret = avd_buf_alloc(avd, &hevc_ctx->bufs.az_above, DIV_ROUND_UP(w + 7, 16) * 4 * bit_depth); if (ret) return ret; @@ -1285,15 +1274,6 @@ static int avd_hevc_compute_tiles(struct avd_ctx *ctx, struct avd_hevc_run *run) return 0; } -static void avd_hevc_dealloc_scratch(struct avd_ctx *ctx) -{ - struct avd_hevc_ctx *hevc_ctx = ctx->priv; - struct avd_dev *avd = ctx->dev; - - for (int i = 0; i < PPS_NUM; i++) - avd_buf_free(avd, &hevc_ctx->bufs.pps_tile[i]); -} - static void avd_hevc_stop(struct avd_ctx *ctx) { struct avd_hevc_ctx *hevc_ctx = ctx->priv; @@ -1304,8 +1284,14 @@ static void avd_hevc_stop(struct avd_ctx *ctx) avd_buf_free(avd, &hevc_ctx->bufs.pipe_state); avd_buf_free(avd, &hevc_ctx->bufs.inst); - - avd_hevc_dealloc_scratch(ctx); + avd_buf_free(avd, &hevc_ctx->bufs.mv_above_info); + avd_buf_free(avd, &hevc_ctx->bufs.az_above); + avd_buf_free(avd, &hevc_ctx->bufs.ip_above); + avd_buf_free(avd, &hevc_ctx->bufs.lf_above); + avd_buf_free(avd, &hevc_ctx->bufs.lf_above_info); + avd_buf_free(avd, &hevc_ctx->bufs.lf_left); + avd_buf_free(avd, &hevc_ctx->bufs.lf_left_info); + avd_buf_free(avd, &hevc_ctx->bufs.sw_left); free_vp_slot(avd, ctx); free_inst_slot(avd, ctx); @@ -1316,7 +1302,7 @@ static void avd_hevc_stop(struct avd_ctx *ctx) static int avd_hevc_run_preamble(struct avd_ctx *ctx, struct avd_hevc_run *run) { struct v4l2_ctrl *ctrl; - u32 dst_len, sps_len; + u32 dst_len, mv_color_len; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); @@ -1344,9 +1330,9 @@ static int avd_hevc_run_preamble(struct avd_ctx *ctx, struct avd_hevc_run *run) dst_len = run->base.bufs.dst->vb2_buf.planes[0].length; - sps_len = sps_size(fmt_width(ctx), fmt_height(ctx)); + mv_color_len = mv_color_size(fmt_width(ctx), fmt_height(ctx)); - run->addresses.sps = run->base.y_out + (dst_len - sps_len); + run->addresses.mv_color = run->base.y_out + (dst_len - mv_color_len); return 0; } diff --git a/drivers/media/platform/apple/avd/avd-inst.h b/drivers/media/platform/apple/avd/avd-inst.h index db741db572e77c..d880575766aa5d 100644 --- a/drivers/media/platform/apple/avd/avd-inst.h +++ b/drivers/media/platform/apple/avd/avd-inst.h @@ -17,6 +17,18 @@ #define AVD_OP_HDR FIELD_PREP(GENMASK(31, 20), 0x2db) #define AVD_OP_HDR_CONST FIELD_PREP(GENMASK(10, 0), 0x2e0) + +/* + * only for 10 bit. + * output in packed p010 / nv15 kinda format + * 10 bits per component. With groups of tree packed into 4 bytes (little + * endian order) + * P 3 2 1 + * [2:10:10:10] + * + * additionally, av1 and vp9 need an extra scratch buffer if this is set + */ +#define AVD_OP_HDR_FLAG_PACKED(v) FIELD_PREP(BIT(10), !!(v)) /* decompress pixel data */ #define AVD_OP_HDR_FLAG_DECOMP(v) FIELD_PREP(BIT(12), !!(v)) #define AVD_OP_HDR_FLAG_INTRA(v) FIELD_PREP(BIT(13), !!(v)) diff --git a/drivers/media/platform/apple/avd/avd-vp9.c b/drivers/media/platform/apple/avd/avd-vp9.c index 869c7257c5960e..789d4d56e0adca 100644 --- a/drivers/media/platform/apple/avd/avd-vp9.c +++ b/drivers/media/platform/apple/avd/avd-vp9.c @@ -149,13 +149,13 @@ struct avd_vp9_ctx { struct v4l2_vp9_frame_context frame_context[4]; struct avd_vp9_bufs { struct avd_buf inst; - /* only affect tiles */ - struct avd_buf tiles[3]; - /* just a guess (this name exists in tunables) */ + struct avd_buf az_left; struct avd_buf above_info; - /* if above is true, state and color are left */ - struct avd_buf state; - struct avd_buf color[2]; + struct avd_buf ip_above; + struct avd_buf lf_above; + struct avd_buf lf_left_info; + struct avd_buf lf_left; + struct avd_buf color; struct avd_buf seg; struct avd_buf pipe_state; struct avd_buf counts; @@ -324,18 +324,13 @@ static void set_header(struct avd_ctx *ctx, struct avd_vp9_run *run) push(0, ""); push(0, ""); - pusha(vp9_ctx->bufs.counts.addr, "frame_counts_addr", 0); - pusha(vp9_ctx->bufs.probs.addr, "hdr_104_probs_addr_lsb8", 0); - - /* always used */ - pusha(vp9_ctx->bufs.state.addr, "hdr_118_pps0_tile_addr_lsb8", 0); - - /* read / write segment buffers */ - pusha(vp9_ctx->bufs.seg.addr, "hdr_108_pps1_tile_addr_lsb8", 1); - pusha(vp9_ctx->bufs.seg.addr, "hdr_108_pps1_tile_addr_lsb8", 2); - /* ping pong buffers, not on intra frames (how apple uses them) */ - pusha(vp9_ctx->bufs.above_info.addr, "hdr_110_pps2_tile_addr_lsb8", 3); - pusha(vp9_ctx->bufs.above_info.addr, "hdr_110_pps2_tile_addr_lsb8", 4); + pusha(vp9_ctx->bufs.counts.addr, "counts", 0); + pusha(vp9_ctx->bufs.probs.addr, "probs", 0); + pusha(vp9_ctx->bufs.above_info.addr, "above_info", 0); + pusha(vp9_ctx->bufs.seg.addr, "seg", 1); + pusha(vp9_ctx->bufs.seg.addr, "seg", 2); + pusha(vp9_ctx->bufs.color.addr, "color", 3); + pusha(vp9_ctx->bufs.color.addr, "color", 4); push(VP9_Q_IDX(frame->quant.base_q_idx) | VP9_Q_DC_Y(frame->quant.delta_q_y_dc) | @@ -369,23 +364,19 @@ static void set_header(struct avd_ctx *ctx, struct avd_vp9_run *run) if (!(avd->variant->quirks & AVD_QUIRK_NO_PIPE_STATE)) pusha(vp9_ctx->bufs.pipe_state.addr, "pipe_state", 0); - pusha(vp9_ctx->bufs.color[0].addr, "hdr_e8_sps0_tile_addr_lsb8", 0); - pusha(vp9_ctx->bufs.color[1].addr, "hdr_e8_sps0_tile_addr_lsb8", 0); - + pusha(vp9_ctx->bufs.ip_above.addr, "ip_above", 0); + pusha(vp9_ctx->bufs.lf_above.addr, "lf_above", 0); + /* no lf_above_info? */ pusha((u64)0, "hdr_e8_sps0_tile_addr_lsb8", 0); - - /* not fatal */ - pusha(vp9_ctx->bufs.tiles[0].addr, "hdr_e8_sps0_tile_addr_lsb8", 0); - pusha(vp9_ctx->bufs.tiles[1].addr, "hdr_e8_sps0_tile_addr_lsb8", 0); - /* fatal if missing / wrong */ - pusha(vp9_ctx->bufs.tiles[2].addr, "hdr_e8_sps0_tile_addr_lsb8", 0); + pusha(vp9_ctx->bufs.lf_left.addr, "lf_left", 0); + pusha(vp9_ctx->bufs.lf_left_info.addr, "lf_left_info", 0); + pusha(vp9_ctx->bufs.az_left.addr, "az_left", 0); push(0, ""); push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); - /* confusing */ - pusha((u64)0, "hdr_f4_sps1_tile_addr_lsb8", 2); + pusha((u64)0, "packed_fmt_scratch", 0); bytesperline = ctx->decoded_fmt.fmt.pix_mp.plane_fmt[0].bytesperline; if (avd->variant->quirks & AVD_QUIRK_LSR) @@ -642,46 +633,42 @@ static int avd_vp9_alloc_bufs(struct avd_ctx *ctx) if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.above_info, + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.color, DIV_ROUND_UP(w, 16) * DIV_ROUND_UP(h, 64) * 144); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.color[0], + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.ip_above, DIV_ROUND_UP(w, 16) * 4 * bit_depth + (VP9_MAX_TILE_COLS - 1) * 128); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.color[1], + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.lf_above, DIV_ROUND_UP(w, 8) * 16 * bit_depth); if (ret) return ret; - /* - * randomly needs more space when resizing? - * maybe it does not need it? - */ ret = avd_buf_alloc(avd, &vp9_ctx->bufs.seg, DIV_ROUND_UP(w, 8) * 24); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.tiles[0], + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.lf_left, DIV_ROUND_UP(h, 8) * 16 * bit_depth); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.tiles[1], + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.lf_left_info, DIV_ROUND_UP(h, 64) * 16); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.tiles[2], + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.az_left, bit_depth * 36 * DIV_ROUND_UP(h, 8) + bit_depth * 18 * DIV_ROUND_UP(h, 16)); if (ret) return ret; - ret = avd_buf_alloc(avd, &vp9_ctx->bufs.state, + ret = avd_buf_alloc(avd, &vp9_ctx->bufs.above_info, DIV_ROUND_UP(w, 64) * 288 + (VP9_MAX_TILE_COLS - 1) * 128); if (ret) @@ -981,12 +968,13 @@ static void avd_vp9_stop(struct avd_ctx *ctx) avd_buf_free(avd, &vp9_ctx->bufs.probs); avd_buf_free(avd, &vp9_ctx->bufs.counts); avd_buf_free(avd, &vp9_ctx->bufs.seg); + avd_buf_free(avd, &vp9_ctx->bufs.color); + avd_buf_free(avd, &vp9_ctx->bufs.ip_above); + avd_buf_free(avd, &vp9_ctx->bufs.lf_above); avd_buf_free(avd, &vp9_ctx->bufs.above_info); - avd_buf_free(avd, &vp9_ctx->bufs.color[0]); - avd_buf_free(avd, &vp9_ctx->bufs.color[1]); - avd_buf_free(avd, &vp9_ctx->bufs.state); - for (int i = 0; i < 3; i++) - avd_buf_free(avd, &vp9_ctx->bufs.tiles[i]); + avd_buf_free(avd, &vp9_ctx->bufs.az_left); + avd_buf_free(avd, &vp9_ctx->bufs.lf_left_info); + avd_buf_free(avd, &vp9_ctx->bufs.lf_left); kfree(vp9_ctx); } diff --git a/drivers/media/platform/apple/avd/avd.h b/drivers/media/platform/apple/avd/avd.h index 92252934cb0d5a..12c1a4abe1e574 100644 --- a/drivers/media/platform/apple/avd/avd.h +++ b/drivers/media/platform/apple/avd/avd.h @@ -89,7 +89,7 @@ struct avd_av1_decoded_buffer_info { u32 order_hints[V4L2_AV1_TOTAL_REFS_PER_FRAME]; u8 ref_frame_idx[V4L2_AV1_REFS_PER_FRAME]; bool intrabc; - size_t priv_tlb_size; + size_t color_size; }; struct avd_hevc_decoded_buffer_info { From a264a9f0dff40a41fa45cf4b1d2e26d9f51df7ae Mon Sep 17 00:00:00 2001 From: sofus Date: Fri, 4 Sep 2026 09:54:21 +0200 Subject: [PATCH 4/5] fixup! media: apple: avd: define static values and bitmasks Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-h264.c | 10 +++++++--- drivers/media/platform/apple/avd/avd-hevc.c | 17 +++++++++++------ drivers/media/platform/apple/avd/avd-vp9.c | 21 ++++++++++++++------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/apple/avd/avd-h264.c b/drivers/media/platform/apple/avd/avd-h264.c index 44656e8c1a892b..d795c4ae227d70 100644 --- a/drivers/media/platform/apple/avd/avd-h264.c +++ b/drivers/media/platform/apple/avd/avd-h264.c @@ -807,9 +807,13 @@ static int avd_h264_try_ctrl(struct avd_ctx *ctx, struct v4l2_ctrl *ctrl) static void avd_h264_submit(struct avd_ctx *ctx) { writel_relaxed( - 0x2b000000 | - (ctx->dev->variant->revision == 3 ? 0x100 : 0x200) | - (ctx->fifo_idx << 4) | ctx->dev->variant->fifo_slots, + AVD_OP_EXEC | + AVD_OP_EXEC_FLAG_START_REV4( + ctx->dev->variant->revision == 4) | + AVD_OP_EXEC_FLAG_START_REV3( + ctx->dev->variant->revision == 3) | + AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | + AVD_OP_EXEC_FIFO_MASK(ctx->dev->variant->fifo_slots), ctx->dev->ctrl + ctx->dev->variant->submit_offset); } diff --git a/drivers/media/platform/apple/avd/avd-hevc.c b/drivers/media/platform/apple/avd/avd-hevc.c index 905f7ae7f599be..970a9c445a25e9 100644 --- a/drivers/media/platform/apple/avd/avd-hevc.c +++ b/drivers/media/platform/apple/avd/avd-hevc.c @@ -1399,12 +1399,17 @@ static void avd_hevc_submit(struct avd_ctx *ctx) struct avd_hevc_ctx *hevc_ctx = ctx->priv; struct avd_dev *avd = ctx->dev; - for (int i = 0; i < hevc_ctx->submit_num; i++) { - writel(0x2b000000 | - (i == 0 ? (avd->variant->revision == 3 ? 0x100 : - 0x200) : - 0) | - (ctx->fifo_idx << 4) | avd->variant->fifo_slots, + writel(AVD_OP_EXEC | + AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == + 4) | + AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == + 3) | + AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | + AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), + avd->ctrl + avd->variant->submit_offset); + for (int i = 0; i < hevc_ctx->submit_num - 1; i++) { + writel(AVD_OP_EXEC | AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | + AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), avd->ctrl + avd->variant->submit_offset); } } diff --git a/drivers/media/platform/apple/avd/avd-vp9.c b/drivers/media/platform/apple/avd/avd-vp9.c index 789d4d56e0adca..5b445d586061ec 100644 --- a/drivers/media/platform/apple/avd/avd-vp9.c +++ b/drivers/media/platform/apple/avd/avd-vp9.c @@ -1006,15 +1006,22 @@ static void avd_vp9_submit(struct avd_ctx *ctx) { struct avd_vp9_ctx *vp9_ctx = ctx->priv; struct avd_dev *avd = ctx->dev; - u32 submit_mask = ctx->dev->variant->revision == 3 ? 0xfff000 : 0; - - writel(0x2b000000 | submit_mask | - (avd->variant->revision == 3 ? 0x100 : 0x200) | - (ctx->fifo_idx << 4) | avd->variant->fifo_slots, + u32 submit_mask = ctx->dev->variant->revision == 3 ? + AVD_OP_EXEC_REV3_VP9_MASK : + 0; + + writel(AVD_OP_EXEC | submit_mask | + AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == + 4) | + AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == + 3) | + AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | + AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), avd->ctrl + avd->variant->submit_offset); for (int i = 0; i < vp9_ctx->submit_num - 1; i++) - writel(0x2b000000 | submit_mask | (ctx->fifo_idx << 4) | - avd->variant->fifo_slots, + writel(AVD_OP_EXEC | submit_mask | + AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | + AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), avd->ctrl + avd->variant->submit_offset); } From 012af10f7875bf0e470018fb6bb75227a200b749 Mon Sep 17 00:00:00 2001 From: sofus Date: Fri, 4 Sep 2026 14:25:37 +0200 Subject: [PATCH 5/5] media: apple: avd: add a dedicated "submit" step Moves the "program hw" logic away from the "prepare instructions" logic. Removes the broken vp/fifo slot logic, but adds manual slice buffer handling to h264 Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-av1.c | 65 ++------ drivers/media/platform/apple/avd/avd-drv.c | 130 +++++++++++----- drivers/media/platform/apple/avd/avd-h264.c | 162 +++++++++----------- drivers/media/platform/apple/avd/avd-hevc.c | 101 ++---------- drivers/media/platform/apple/avd/avd-inst.h | 35 +++-- drivers/media/platform/apple/avd/avd-vp9.c | 49 ++---- drivers/media/platform/apple/avd/avd.h | 58 +++---- 7 files changed, 248 insertions(+), 352 deletions(-) diff --git a/drivers/media/platform/apple/avd/avd-av1.c b/drivers/media/platform/apple/avd/avd-av1.c index 9328e088c14ebe..ddb38a8961c6cd 100644 --- a/drivers/media/platform/apple/avd/avd-av1.c +++ b/drivers/media/platform/apple/avd/avd-av1.c @@ -16,10 +16,6 @@ * Tomasz Figa */ -#include "linux/v4l2-controls.h" -#include -#include - #include #include "avd.h" @@ -340,7 +336,6 @@ static void set_refs(struct avd_ctx *ctx, struct avd_av1_run *run) struct avd_av1_ctx *av1_ctx = ctx->priv; const struct v4l2_ctrl_av1_frame *frame = run->frame; const struct v4l2_av1_global_motion *gm = &frame->global_motion; - struct avd_dev *avd = ctx->dev; int i, ref_idx; struct avd_decoded_buffer *dst, *ref; bool intrabc = !!(frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC); @@ -424,7 +419,7 @@ static void set_refs(struct avd_ctx *ctx, struct avd_av1_run *run) push(AV1_REF_SCALE_X(x_scale) | AV1_REF_SCALE_Y(y_scale), "ref_scale"); - push_comp(avd, ctx, addr, ref->comp.offsets); + push_comp(ctx, addr, ref->comp.offsets); } } @@ -538,7 +533,6 @@ static void set_ref_hints(struct avd_ctx *ctx, struct avd_av1_run *run, u8 *selected_refs) { const struct v4l2_ctrl_av1_frame *frame = run->frame; - struct avd_dev *avd = ctx->dev; int i, ref_idx; struct avd_decoded_buffer *dst, *ref; dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); @@ -576,7 +570,6 @@ static void set_ref_hints(struct avd_ctx *ctx, struct avd_av1_run *run, static void set_ref_hdr(struct avd_ctx *ctx, struct avd_av1_run *run) { const struct v4l2_ctrl_av1_frame *frame = run->frame; - struct avd_dev *avd = ctx->dev; u8 ref_slots[7] = { 1, 2, 3, 4, 5, 6, 7 }; int sign_bias = 0; int ref_slot = 0; @@ -639,7 +632,6 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) const struct v4l2_av1_loop_restoration *lr = &frame->loop_restoration; const struct v4l2_av1_cdef *cdef = &frame->cdef; const struct v4l2_av1_segmentation *seg = &frame->segmentation; - struct avd_dev *avd = ctx->dev; u32 bytesperline; int i, segid, segval, ref_idx; int step_x, initial_subpel_x; @@ -657,10 +649,6 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) dma_addr_t ref_addr; dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); - push(AVD_OP_EXEC | - AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == 4) | - AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx), - "vp_start"); push(AVD_OP_HDR | AVD_OP_HDR_FLAG_DECOMP(ctx->decomp) | AVD_OP_HDR_FLAG_INTRA(intra_only && !intrabc) | AVD_OP_HDR_CONST | AVD_OP_HDR_FLAG_PIPE_STATE(1), @@ -974,7 +962,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_av1_run *run) push(0, "mark_section"); - push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); + push_comp(ctx, run->base.comp_out, ctx->comp.offsets); pusha((u64)0, "packed_fmt_scratch", 0); @@ -1001,9 +989,7 @@ static void set_tiles(struct avd_ctx *ctx, struct avd_av1_run *run) const struct v4l2_ctrl_av1_sequence *seq = run->seq; const struct v4l2_ctrl_av1_tile_group_entry *tile_group; const struct v4l2_av1_tile_info *tile_info = &frame->tile_info; - bool is_last; - struct avd_dev *avd = ctx->dev; - int row, col, sb_row, sb_col; + int row, col, sb_row, sb_col, tile_id; int sb_shift = seq->flags & V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK ? 5 : 4; @@ -1012,9 +998,8 @@ static void set_tiles(struct avd_ctx *ctx, struct avd_av1_run *run) for (row = 0; row < tile_info->tile_rows; row++) { for (col = 0; col < tile_info->tile_cols; col++) { - is_last = col == tile_info->tile_cols - 1 && - row == tile_info->tile_rows - 1; - int tile_id = row * tile_info->tile_cols + col; + ctx->job.num++; + tile_id = row * tile_info->tile_cols + col; tile_group = &run->tile_group[tile_id]; push(AVD_OP_CODED_DATA | @@ -1057,8 +1042,6 @@ static void set_tiles(struct avd_ctx *ctx, struct avd_av1_run *run) tile_info->width_in_sbs_minus_1 [tile_group->tile_col]), "tile_op_end"); - push(AVD_OP_EXEC | AVD_OP_EXEC_FLAG_END(is_last), - "submit"); #ifdef DEBUG_INST pr_info("\n"); #endif @@ -1294,9 +1277,7 @@ static int avd_av1_alloc_work_bufs(struct avd_ctx *ctx, struct avd_av1_run *run) static int avd_av1_run(struct avd_ctx *ctx) { - struct avd_dev *avd = ctx->dev; struct avd_av1_run run; - struct avd_av1_ctx *av1_ctx; struct avd_decoded_buffer *dst; int ret; @@ -1306,22 +1287,16 @@ static int avd_av1_run(struct avd_ctx *ctx) return ret; } - av1_ctx = ctx->priv; - - ret = alloc_slots(avd, ctx, AVD_CODEC_AV1); - if (ret) { - dev_err(avd->dev, "no free slots: %d", ret); + ret = avd_init_job(ctx, AVD_CODEC_AV1, + run.frame->tile_info.tile_cols * + run.frame->tile_info.tile_rows + + 1); + if (ret) return ret; - } dst = vb2_to_avd_decoded_buf(&run.base.bufs.dst->vb2_buf); update_dec_buf_info(dst, run.seq, run.frame); - schedule_delayed_work(&ctx->watchdog_work, msecs_to_jiffies(2000)); - - avd->variant->configure_stream(avd, av1_ctx->bufs.inst.addr, - ctx->fifo_idx, ctx->vp_slot); - avd_av1_set_prob(ctx, &run); avd_av1_alloc_work_bufs(ctx, &run); @@ -1330,7 +1305,7 @@ static int avd_av1_run(struct avd_ctx *ctx) avd_run_postamble(ctx, &run.base); - return 0; + return avd_submit_job(ctx); } static int avd_av1_alloc_bufs(struct avd_ctx *ctx) @@ -1437,29 +1412,11 @@ static void avd_av1_submit(struct avd_ctx *ctx) AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), avd->ctrl + avd->variant->submit_offset); -#ifdef DEBUG_INST - pr_info("%8lx | %s %2d\n", - AVD_OP_EXEC | - AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == - 4) | - AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | - AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), - "submit", 0); -#endif for (int i = 0; i < av1_ctx->submit_num - 1; i++) { -#ifdef DEBUG_INST - pr_info("%8lx | %s %2d\n", - AVD_OP_EXEC | AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | - AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), - "submit", i + 1); -#endif writel(AVD_OP_EXEC | AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | AVD_OP_EXEC_FIFO_MASK(avd->variant->fifo_slots), avd->ctrl + avd->variant->submit_offset); } -#ifdef DEBUG_INST - pr_info("\n"); -#endif } static void avd_av1_adjust_decoded_fmt(struct avd_ctx *ctx, diff --git a/drivers/media/platform/apple/avd/avd-drv.c b/drivers/media/platform/apple/avd/avd-drv.c index 890e5939b968a9..c856a8638a1522 100644 --- a/drivers/media/platform/apple/avd/avd-drv.c +++ b/drivers/media/platform/apple/avd/avd-drv.c @@ -14,11 +14,13 @@ #include #include #include +#include #include #include #include "avd.h" +#include "avd-inst.h" #include "avd-regs.h" static void calc_tile_meta(u32 w, u32 h, u32 bpb, u32 tile_dim, @@ -67,35 +69,6 @@ void fill_comp(struct avd_comp *comp, enum avd_image_fmt image_fmt, u32 width, comp->size = y_meta + y + uv_meta + uv; } - -int alloc_slots(struct avd_dev *avd, struct avd_ctx *ctx, enum avd_codec codec) { - u32 free; - u32 offset = 0; - for (int i = 0; i < codec; i++) - offset += avd->variant->vp_slots[i]; - - free = find_next_zero_bit(&avd->vp_slots, - offset + avd->variant->vp_slots[codec], - offset); - - if (free >= offset + avd->variant->vp_slots[codec]) - return -ENOMEM; - - set_bit(free, &avd->vp_slots); - ctx->vp_slot = free; - - ctx->fifo_idx = find_first_zero_bit(&avd->inst_fifo_slots, - avd->variant->fifo_slots); - - if (WARN_ON(ctx->fifo_idx >= avd->variant->fifo_slots)) { - clear_bit(free, &avd->vp_slots); - return -ENOMEM; - } - set_bit(ctx->fifo_idx, &avd->inst_fifo_slots); - - return 0; -} - int avd_buf_alloc(struct avd_dev *avd, struct avd_buf *buf, size_t size) { if (!buf->cpu && size < buf->size) @@ -137,12 +110,89 @@ avd_get_ref_buf(struct avd_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp) return vb2_to_avd_decoded_buf(buf); } +static int avd_wait_submission_queue(struct avd_ctx *ctx, int vp) +{ + struct avd_dev *avd = ctx->dev; + u32 max = readl_relaxed(avd->ctrl + + avd->variant->submit_queue_max_offset + vp * 4); + u32 cur = readl_relaxed( + avd->ctrl + avd->variant->submit_queue_status_offset + vp * 4); + + if (cur == max) { + dev_err(avd->dev, "instruction que full! %d/%d", cur, max); + return 1; + } + + if (cur >= max / 2) { + /* TODO: to high? low? Has weird side effects??? */ + usleep_range(500, 650); + } + return 0; +} + +int avd_init_job(struct avd_ctx *ctx, enum avd_codec codec, size_t segments) +{ + int ret = 0; + struct avd_job *job = &ctx->job; + + job->codec = codec; + job->num = 0; + job->segments = kzalloc(sizeof(*job->segments) * segments, GFP_KERNEL); + if (!job->segments) + ret = -ENOMEM; + return ret; +} + +int avd_submit_job(struct avd_ctx *ctx) +{ + struct avd_dev *avd = ctx->dev; + struct avd_job *sub = &ctx->job; + struct avd_segment *seg; + int i, idx = 0, vp = 0; + void __iomem *reg; + u32 exec_mask = sub->codec == AVD_CODEC_VP9 && + avd->variant->revision == 3 ? + AVD_OP_EXEC_REV3_VP9_MASK : + 0; + u32 exec_rev_flag = + AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == 4) | + AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == 3); + + ctx->fifo_idx = 0; + for (i = 0; i < sub->codec; i++) + vp += avd->variant->vp_slots[i]; + + schedule_delayed_work(&ctx->watchdog_work, msecs_to_jiffies(2000)); + avd->variant->configure_stream(avd, ctx->inst.addr, ctx->fifo_idx, vp); + reg = avd->ctrl + avd->variant->vp_slot_offset + vp * 4; + + /* the first segment is always the header (needs special handling) */ + + writel(AVD_OP_EXEC | exec_mask | exec_rev_flag | + AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx), + reg); + seg = &sub->segments[idx++]; + for (i = 0; i < seg->num; i++) + writel(seg->instructions[i], reg); + for (; idx <= sub->num; idx++) { + seg = &sub->segments[idx]; + for (i = 0; i < seg->num; i++) + writel(seg->instructions[i], reg); + if (avd_wait_submission_queue(ctx, vp)) + break; + writel(AVD_OP_EXEC | exec_mask | + AVD_OP_EXEC_FLAG_END(idx == sub->num), + reg); + } + + kfree(sub->segments); + sub->segments = NULL; + return 0; +} static int avd_reset(struct avd_dev *avd) { int ret = 0; - avd->vp_slots = 0; - avd->inst_fifo_slots = 0; ret = pm_runtime_resume_and_get(avd->dev); if (ret < 0) @@ -178,11 +228,7 @@ static void avd_watchdog_func(struct work_struct *work) avd = ctx->dev; - dev_err(avd->dev, "Frame processing timed out! Vp: %d (%02d)", - ctx->vp_slot, ctx->fifo_idx); - - free_vp_slot(avd, ctx); - free_inst_slot(avd, ctx); + dev_err(avd->dev, "Frame processing timed out!"); writel(0, avd->mbox + AVD_REG_MBOX_IRQ_ENABLE); ret = avd_reset(avd); @@ -215,17 +261,13 @@ static irqreturn_t avd_irq_handler(int irq, void *data) if (status & 0x1000) { /* pp is done ! we are done */ state = VB2_BUF_STATE_DONE; - - free_inst_slot(avd, ctx); } else if (status & 0x100) { - free_vp_slot(avd, ctx); /* a vp is done, kick the pp and hope for the best */ if(ctx->coded_fmt_desc->ops->submit) ctx->coded_fmt_desc->ops->submit(ctx); - goto done; } else { - dev_err(avd->dev, "H%d %02d error", status, ctx->fifo_idx); + dev_err(avd->dev, "H%d error", status); /* let watchdog handle */ goto done; } @@ -310,6 +352,10 @@ static int avd_open(struct file *filp) ctx->dev = avd; + ret = avd_buf_alloc(avd, &ctx->inst, fifo_size()); + if (ret) + goto err_free_ctx; + INIT_DELAYED_WORK(&ctx->watchdog_work, avd_watchdog_func); avd_reset_coded_fmt(ctx); @@ -335,6 +381,7 @@ static int avd_open(struct file *filp) v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); err_free_ctx: + avd_buf_free(avd, &ctx->inst); kfree(ctx); return ret; } @@ -347,6 +394,7 @@ static int avd_release(struct file *filp) v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_fh_exit(&ctx->fh); + avd_buf_free(ctx->dev, &ctx->inst); kfree(ctx); return 0; diff --git a/drivers/media/platform/apple/avd/avd-h264.c b/drivers/media/platform/apple/avd/avd-h264.c index d795c4ae227d70..2db9bd660b74c1 100644 --- a/drivers/media/platform/apple/avd/avd-h264.c +++ b/drivers/media/platform/apple/avd/avd-h264.c @@ -13,9 +13,7 @@ * Tomasz Figa */ -#include "linux/dev_printk.h" -#include -#include +#include #include #include @@ -31,6 +29,9 @@ #define H264_TRANSFORM_8X8_MODE(v) FIELD_PREP(BIT(7), !!(v)) +/* not a hardware constraint */ +#define MAX_SLICES 4096 + struct avd_h264_run { struct avd_run base; @@ -58,6 +59,10 @@ struct avd_h264_ctx { struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN]; } reflists; + struct avd_buf slices[MAX_SLICES]; + struct avd_buf *active_slice; + size_t slice_num; + struct avd_h264_bufs { struct avd_buf inst; struct avd_buf pipe_state; @@ -97,7 +102,6 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_h264_run *run) const struct v4l2_ctrl_h264_decode_params *decode = run->decode_params; const struct v4l2_h264_dpb_entry *dpb = decode->dpb; struct avd_h264_ctx *h264_ctx = ctx->priv; - struct avd_dev *avd = ctx->dev; struct avd_decoded_buffer *dst, *ref; dma_addr_t addr; @@ -129,7 +133,7 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_h264_run *run) dpb[i].top_field_order_cnt), "hdr_d0_ref_hdr"); - push_comp(avd, ctx, addr, ctx->comp.offsets); + push_comp(ctx, addr, ctx->comp.offsets); } } @@ -138,7 +142,6 @@ static void stream_scaling(struct avd_ctx *ctx, struct avd_h264_run *run) const struct v4l2_ctrl_h264_pps *pps = run->pps; const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; - struct avd_dev *avd = ctx->dev; push(H264_SCL_DIMS, "hdr_4c_pic_scaling_list_dims"); @@ -200,11 +203,6 @@ static void stream_hdr(struct avd_ctx *ctx, struct avd_h264_run *run) u32 width = (sps->pic_width_in_mbs_minus1 + 1) * 16; u32 height = (sps->pic_height_in_map_units_minus1 + 1) * 16; - push(AVD_OP_EXEC | AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | - AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == 3) | - AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == 4), - "inst_fifo_start"); - push(AVD_OP_HDR | AVD_OP_HDR_FLAG_DECOMP(ctx->decomp) | AVD_OP_HDR_FLAG_INTRA( decode->flags & @@ -279,7 +277,7 @@ static void stream_hdr(struct avd_ctx *ctx, struct avd_h264_run *run) pusha(h264_ctx->bufs.lf_above_info.addr, "lf_above_info", 3); push(0, ""); - push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); + push_comp(ctx, run->base.comp_out, ctx->comp.offsets); bytesperline = ctx->decoded_fmt.fmt.pix_mp.plane_fmt[0].bytesperline; if (avd->variant->quirks & AVD_QUIRK_LSR) @@ -312,7 +310,6 @@ static void stream_weights(struct avd_ctx *ctx, struct avd_h264_run *run) const struct v4l2_ctrl_h264_pred_weights *weights = run->pred_weights; const struct v4l2_ctrl_h264_pps *pps = run->pps; const struct v4l2_ctrl_h264_slice_params *sl = run->slice_params; - struct avd_dev *avd = ctx->dev; bool pred_weight_req = V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, sl); bool default_weights = pps->weighted_bipred_idc == 2 && @@ -390,18 +387,17 @@ static void stream_weights(struct avd_ctx *ctx, struct avd_h264_run *run) } } -static u32 stream_slice(struct avd_ctx *ctx, struct avd_h264_run *run) +static void stream_slice(struct avd_ctx *ctx, struct avd_h264_run *run) { const struct v4l2_ctrl_h264_decode_params *decode = run->decode_params; const struct v4l2_ctrl_h264_pps *pps = run->pps; const struct v4l2_ctrl_h264_sps *sps = run->sps; const struct v4l2_ctrl_h264_slice_params *sl = run->slice_params; - struct avd_dev *avd = ctx->dev; - struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - u32 payload_len = vb2_get_plane_payload(&src->vb2_buf, 0); + struct avd_h264_ctx *h264_ctx = ctx->priv; + u32 payload_len = h264_ctx->active_slice->size; bool en_mode = (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) == 0; - const u8 *data = vb2_plane_vaddr(&src->vb2_buf, 0); + const u8 *data = h264_ctx->active_slice->cpu; u32 min_off = (sl->header_bit_size + (en_mode ? 0 : 7)) / 8; @@ -417,7 +413,7 @@ static u32 stream_slice(struct avd_ctx *ctx, struct avd_h264_run *run) off++; } - dma_addr_t slc_a84 = run->base.coded_in + off; + dma_addr_t slc_a84 = h264_ctx->active_slice->addr + off; push(AVD_OP_CODED_DATA | AVD_OP_CODED_DATA_BIT_OFF( @@ -511,14 +507,6 @@ static u32 stream_slice(struct avd_ctx *ctx, struct avd_h264_run *run) pusha(mv_color_addr, "slc_a78_sps_tile_addr2_lsb8", 0); } - - /* only submit if this is the last slice */ - push(AVD_OP_EXEC | - AVD_OP_EXEC_FLAG_END(!( - src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)), - "cm3_cmd_inst_fifo_end"); - - return payload_len - off; } static int avd_h264_alloc_bufs(struct avd_ctx *ctx) @@ -534,14 +522,12 @@ static int avd_h264_alloc_bufs(struct avd_ctx *ctx) ret = avd_buf_alloc(dev, &h264_ctx->bufs.inst, fifo_size()); if (ret) { - dev_err(dev->dev, "inst alloc failed\n"); return ret; } if (!(dev->variant->quirks & AVD_QUIRK_NO_PIPE_STATE)) { ret = avd_buf_alloc(dev, &h264_ctx->bufs.pipe_state, 0x200); if (ret) { - dev_err(dev->dev, "pipe state alloc failed\n"); return ret; } } @@ -572,25 +558,6 @@ static int avd_h264_alloc_bufs(struct avd_ctx *ctx) return 0; } -static void avd_h264_free_bufs(struct avd_ctx *ctx) -{ - struct avd_h264_ctx *h264_ctx = ctx->priv; - struct avd_dev *dev = ctx->dev; - - if (!h264_ctx) - return; - - avd_buf_free(dev, &h264_ctx->bufs.pipe_state); - avd_buf_free(dev, &h264_ctx->bufs.inst); - avd_buf_free(dev, &h264_ctx->bufs.above_info); - avd_buf_free(dev, &h264_ctx->bufs.lf_above_info); - avd_buf_free(dev, &h264_ctx->bufs.lf_above); - avd_buf_free(dev, &h264_ctx->bufs.ip_above); - avd_buf_free(dev, &h264_ctx->bufs.mv_above_info); - - kfree(h264_ctx); -} - static int avd_h264_validate_pps(struct avd_ctx *ctx, const struct v4l2_ctrl_h264_pps *pps) { @@ -652,11 +619,25 @@ static int avd_h264_start(struct avd_ctx *ctx) static void avd_h264_stop(struct avd_ctx *ctx) { - avd_h264_free_bufs(ctx); + struct avd_h264_ctx *h264_ctx = ctx->priv; + struct avd_dev *dev = ctx->dev; + int i; + + if (!h264_ctx) + return; - /* needed for all so automatic? */ - free_vp_slot(ctx->dev, ctx); - free_inst_slot(ctx->dev, ctx); + avd_buf_free(dev, &h264_ctx->bufs.pipe_state); + avd_buf_free(dev, &h264_ctx->bufs.inst); + avd_buf_free(dev, &h264_ctx->bufs.above_info); + avd_buf_free(dev, &h264_ctx->bufs.lf_above_info); + avd_buf_free(dev, &h264_ctx->bufs.lf_above); + avd_buf_free(dev, &h264_ctx->bufs.ip_above); + avd_buf_free(dev, &h264_ctx->bufs.mv_above_info); + + for (i = 0; i < h264_ctx->slice_num; i++) + avd_buf_free(dev, &h264_ctx->slices[i]); + + kfree(h264_ctx); } static void avd_h264_run_preamble(struct avd_ctx *ctx, struct avd_h264_run *run) @@ -692,14 +673,28 @@ static void avd_h264_run_preamble(struct avd_ctx *ctx, struct avd_h264_run *run) static int avd_h264_run(struct avd_ctx *ctx) { - struct avd_dev *avd = ctx->dev; struct avd_h264_ctx *h264_ctx = ctx->priv; struct v4l2_h264_reflist_builder reflist_builder; struct avd_h264_run run; - u32 slice_size, slice_parsed, reg; int ret; avd_h264_run_preamble(ctx, &run); + if (h264_ctx->slice_num >= MAX_SLICES) { + dev_err_ratelimited(ctx->dev->dev, + "slice_num > %d, stream was rejected!", + MAX_SLICES); + return -EINVAL; + } + + struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + u32 payload_len = vb2_get_plane_payload(&src->vb2_buf, 0); + const u8 *data = vb2_plane_vaddr(&src->vb2_buf, 0); + h264_ctx->active_slice = &h264_ctx->slices[h264_ctx->slice_num]; + ret = avd_buf_alloc(ctx->dev, h264_ctx->active_slice, payload_len); + if (ret) + return ret; + memcpy(h264_ctx->active_slice->cpu, data, payload_len); + h264_ctx->slice_num++; /* Build the P/B{0,1} ref lists. */ v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, @@ -715,53 +710,37 @@ static int avd_h264_run(struct avd_ctx *ctx) avd_run_postamble(ctx, &run.base); if (is_new_frame(run.slice_params)) { - ret = alloc_slots(avd, ctx, AVD_CODEC_H264); - if (ret) { - dev_err_ratelimited(avd->dev, "no free slots: %d", ret); + ret = avd_init_job(ctx, AVD_CODEC_H264, MAX_SLICES); + if (ret) return ret; - } - avd->variant->configure_stream(ctx->dev, - h264_ctx->bufs.inst.addr, - ctx->fifo_idx, ctx->vp_slot); stream_hdr(ctx, &run); } - if (ctx->vp_slot == VP_SLOT_NONE) { - /* Only happens if its a multi slice frame and there was an error */ - dev_err_ratelimited(avd->dev, "no assigned VP slots: %04lx", - avd->vp_slots); - return -ENOMEM; - } - - schedule_delayed_work(&ctx->watchdog_work, msecs_to_jiffies(2000)); + if (!ctx->job.segments) + return -EINVAL; - slice_size = stream_slice(ctx, &run); + ctx->job.num++; + stream_slice(ctx, &run); if (run.base.bufs.src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) { - if (avd->variant->revision == 3) - reg = (0x18 | ctx->vp_slot << 12); - else - reg = (0x1018 | ctx->vp_slot << 8); - - /* seems to be take ~ slice_size / 16 us */ - ret = readl_poll_timeout( - avd->ctrl + reg, slice_parsed, - slice_parsed >= round_down(slice_size, 8), 5, 1000); + avd_job_finish(ctx, VB2_BUF_STATE_DONE); + return 0; + } - if (ret) { - dev_err(avd->dev, - "VP%d: timed out (%02d)! size: %08x parsed: %08x", - ctx->vp_slot, ctx->fifo_idx, slice_size, - slice_parsed); - avd_status(avd, ctx->vp_slot); - return 0; - } + return avd_submit_job(ctx); +} - if (cancel_delayed_work(&ctx->watchdog_work)) - avd_job_finish(ctx, VB2_BUF_STATE_DONE); - } +static void avd_h264_done(struct avd_ctx *ctx, struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf, + enum vb2_buffer_state result) +{ + struct avd_dev *avd = ctx->dev; + struct avd_h264_ctx *h264_ctx = ctx->priv; + int i; - return 0; + if (!(src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)) + for (i = 0; i < h264_ctx->slice_num; i++) + avd_buf_free(avd, &h264_ctx->slices[i]); } static enum avd_image_fmt avd_h264_get_image_fmt(struct avd_ctx *ctx, @@ -821,6 +800,7 @@ const struct avd_coded_fmt_ops avd_h264_fmt_ops = { .adjust_decoded_fmt = avd_h264_adjust_decoded_fmt, .start = avd_h264_start, .stop = avd_h264_stop, + .done = avd_h264_done, .run = avd_h264_run, .submit = avd_h264_submit, .try_ctrl = avd_h264_try_ctrl, diff --git a/drivers/media/platform/apple/avd/avd-hevc.c b/drivers/media/platform/apple/avd/avd-hevc.c index 970a9c445a25e9..be062bf09b3020 100644 --- a/drivers/media/platform/apple/avd/avd-hevc.c +++ b/drivers/media/platform/apple/avd/avd-hevc.c @@ -13,19 +13,11 @@ * Tomasz Figa */ -#include "asm-generic/errno-base.h" -#include "linux/dev_printk.h" -#include -#include - -#include #include #include "avd.h" #include "avd-inst.h" -#define PPS_NUM 9 - #define NEW_TILE_ID BIT(0) #define NEW_SLICE BIT(1) @@ -111,7 +103,6 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_hevc_run *run) const struct v4l2_ctrl_hevc_slice_params *sl = &run->sl[0]; const struct v4l2_hevc_dpb_entry *dpb; struct avd_hevc_ctx *hevc_ctx = ctx->priv; - struct avd_dev *avd = ctx->dev; struct avd_decoded_buffer *dst, *ref_buf; dst = vb2_to_avd_decoded_buf(&run->base.bufs.dst->vb2_buf); @@ -143,14 +134,13 @@ static void stream_refs(struct avd_ctx *ctx, struct avd_hevc_run *run) dpb->pic_order_cnt_val), "hdr_d0_ref_hdr"); - push_comp(avd, ctx, comp_addr, ref_buf->comp.offsets); + push_comp(ctx, comp_addr, ref_buf->comp.offsets); } } static void set_scaling_lists(struct avd_ctx *ctx, struct avd_hevc_run *run) { const struct v4l2_ctrl_hevc_scaling_matrix *s = run->scaling_matrix; - struct avd_dev *avd = ctx->dev; int i, j, k; u8 (*dc_16x16)[3] = (u8(*)[3])s->scaling_list_dc_coef_16x16; @@ -226,7 +216,6 @@ static void hevc_set_flags(struct avd_ctx *ctx, struct avd_hevc_run *run) const struct v4l2_ctrl_hevc_decode_params *decode = run->decode; const struct v4l2_ctrl_hevc_sps *sps = run->sps; const struct v4l2_ctrl_hevc_pps *pps = run->pps; - struct avd_dev *avd = ctx->dev; u32 log2_ctb_size = ((sps->log2_min_luma_coding_block_size_minus3) + sps->log2_diff_max_min_luma_coding_block_size); @@ -300,7 +289,6 @@ static void hevc_set_flags(struct avd_ctx *ctx, struct avd_hevc_run *run) static void set_header(struct avd_ctx *ctx, struct avd_hevc_run *run) { const struct v4l2_ctrl_hevc_sps *sps = run->sps; - const struct v4l2_ctrl_hevc_pps *pps = run->pps; struct avd_dev *avd = ctx->dev; struct avd_hevc_ctx *hevc_ctx = ctx->priv; u32 bytesperline; @@ -309,11 +297,6 @@ static void set_header(struct avd_ctx *ctx, struct avd_hevc_run *run) bool is_intra = run->sl[0].slice_type == V4L2_HEVC_SLICE_TYPE_I; - push(AVD_OP_EXEC | AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx) | - AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == 3) | - AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == 4), - "inst_fifo_start"); - push(AVD_OP_HDR | AVD_OP_HDR_FLAG_DECOMP(ctx->decomp) | AVD_OP_HDR_FLAG_INTRA(is_intra) | AVD_OP_HDR_CONST | AVD_OP_HDR_FLAG_PIPE_STATE( @@ -381,7 +364,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_hevc_run *run) push(0, ""); - push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); + push_comp(ctx, run->base.comp_out, ctx->comp.offsets); pusha((u64)0, "packed_fmt_scratch", 0); @@ -413,7 +396,6 @@ static void stream_weights(struct avd_ctx *ctx, struct avd_hevc_run *run, u8 chroma_log2_weight_denom; const struct v4l2_ctrl_hevc_pps *pps = run->pps; const struct v4l2_hevc_pred_weight_table *pred = &sl->pred_weight_table; - struct avd_dev *avd = ctx->dev; bool has_luma_weights = ((pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED) && sl->slice_type == V4L2_HEVC_SLICE_TYPE_P) || @@ -513,7 +495,6 @@ static void stream_slice_dqtblk(struct avd_ctx *ctx, struct avd_hevc_run *run, { const struct v4l2_ctrl_hevc_pps *pps = run->pps; const struct v4l2_ctrl_hevc_sps *sps = run->sps; - struct avd_dev *avd = ctx->dev; push(AVD_OP_QP | AVD_OP_QP_VAL(pps->init_qp_minus26 + 26 + @@ -581,7 +562,6 @@ static void stream_slice_mv(struct avd_ctx *ctx, struct avd_hevc_run *run, bool is_first) { const struct v4l2_ctrl_hevc_decode_params *decode = run->decode; - struct avd_dev *avd = ctx->dev; struct avd_decoded_buffer *dst, *ref; bool ref_valid; const u8 *ref_list; @@ -653,7 +633,6 @@ static void set_slice(struct avd_ctx *ctx, struct avd_hevc_run *run, const struct v4l2_ctrl_hevc_slice_params *sl, u32 size, u32 offset, u32 flags) { - struct avd_dev *avd = ctx->dev; dma_addr_t slc_addr = run->base.coded_in + offset + sl->data_byte_offset; push(AVD_OP_CODED_DATA | flags | AVD_OP_CODED_DATA_ADDR(slc_addr >> 32), @@ -666,11 +645,10 @@ static int submit_slice_segment(struct avd_ctx *ctx, struct avd_hevc_run *run, const struct v4l2_ctrl_hevc_slice_params *sl, int row, int col, u32 col_bd[23], u32 row_bd[23], u32 pic_in_cts_width, - u32 pic_in_cts_height, bool is_last, - bool first_slice, bool hflip, bool vflip, - u32 coded_flags, u32 last_tile_block) + u32 pic_in_cts_height, bool first_slice, + bool hflip, bool vflip, u32 coded_flags, + u32 last_tile_block) { - struct avd_dev *avd = ctx->dev; const struct v4l2_ctrl_hevc_pps *pps = run->pps; u32 tb_x, tb_y, tile_block, tile_boundary; @@ -725,9 +703,6 @@ static int submit_slice_segment(struct avd_ctx *ctx, struct avd_hevc_run *run, (coded_flags & NEW_SLICE ? tile_block : tile_boundary), "cm3_set_mv_xy"); - push(AVD_OP_EXEC | AVD_OP_EXEC_FLAG_END(is_last), - "cm3_cmd_inst_fifo_end"); - return last_tile_block; } @@ -836,30 +811,6 @@ static void compute_tile_ids(struct avd_hevc_run *run, u32 pic_in_ctbs_width, x]] = tile_idx; } -static int avd_wait_submission_queue(struct avd_ctx *ctx) -{ - struct avd_dev *avd = ctx->dev; - u32 max = readl_relaxed(avd->ctrl + - avd->variant->submit_queue_max_offset + - (ctx->vp_slot) * 4); - u32 cur = readl_relaxed(avd->ctrl + - avd->variant->submit_queue_status_offset + - (ctx->vp_slot) * 4); - - /* pr_info("%d/%d\n", cur, max); */ - - if (cur == max) { - dev_err(avd->dev, "instruction que full! %d/%d", cur, max); - return 1; - } - - if (cur >= max / 2) { - /* TODO: to high? low? Has weird side effects??? */ - usleep_range(100, 150); - } - return 0; -} - struct sl_ctx { u32 ctx_col; u32 ctx_row; @@ -875,7 +826,7 @@ static void stream_slices(struct avd_ctx *ctx, struct avd_hevc_run *run) struct avd_hevc_ctx *hevc_ctx = ctx->priv; const struct v4l2_ctrl_hevc_slice_params *sl; struct avd_hevc_tile_info *tile_info = &run->tile_info; - bool tiles_enabled, is_last, first_slice, first_segment; + bool tiles_enabled, first_slice, first_segment; bool hflip, vflip; int slice_segment_offset, entry_point_idx = 0, pos = 0, offset = 0; int row, col, i, s, to; @@ -917,10 +868,11 @@ static void stream_slices(struct avd_ctx *ctx, struct avd_hevc_run *run) return; } for (i = 0; i < to; i++) { - is_last = i == to - 1 && s == run->num_slices - 1; first_segment = i == 0; first_slice = s == 0; + ctx->job.num++; + if (tiles_enabled && to > 1) { if (i < sl->num_entry_point_offsets) { size = run->entry_point_offsets @@ -1002,16 +954,13 @@ static void stream_slices(struct avd_ctx *ctx, struct avd_hevc_run *run) last_tile_block = submit_slice_segment( ctx, run, sl, row, col, tile_info->col_bd, tile_info->row_bd, pic_in_ctbs_width, - pic_in_ctbs_height, is_last, first_slice, hflip, - vflip, slice_flag, last_tile_block); + pic_in_ctbs_height, first_slice, hflip, vflip, + slice_flag, last_tile_block); if (slice_flag & NEW_TILE_ID) pos++; slice_segment_offset += new_offset; - - if (avd_wait_submission_queue(ctx)) - return; } offset += sl->bit_size / 8; } @@ -1293,9 +1242,6 @@ static void avd_hevc_stop(struct avd_ctx *ctx) avd_buf_free(avd, &hevc_ctx->bufs.lf_left_info); avd_buf_free(avd, &hevc_ctx->bufs.sw_left); - free_vp_slot(avd, ctx); - free_inst_slot(avd, ctx); - kfree(hevc_ctx); } @@ -1338,28 +1284,17 @@ static int avd_hevc_run_preamble(struct avd_ctx *ctx, struct avd_hevc_run *run) static int avd_hevc_run(struct avd_ctx *ctx) { - struct avd_dev *avd = ctx->dev; struct avd_hevc_run run; - struct avd_hevc_ctx *hevc_ctx; struct avd_decoded_buffer *dst; int ret; ret = avd_hevc_run_preamble(ctx, &run); - if (ret) { - dev_err(avd->dev, "avd_hevc_run_preamble: failed %d", ret); + if (ret) return ret; - } - hevc_ctx = ctx->priv; dst = vb2_to_avd_decoded_buf(&run.base.bufs.dst->vb2_buf); update_dec_buf_info(dst, &run.sl[0]); - ret = alloc_slots(avd, ctx, AVD_CODEC_HEVC); - if (ret) { - dev_err(avd->dev, "no free slots: %d", ret); - return ret; - } - ret = avd_hevc_compute_tiles(ctx, &run); if (ret) goto done; @@ -1368,18 +1303,16 @@ static int avd_hevc_run(struct avd_ctx *ctx) if (ret) goto done; - /* pr_info("VP%d: start\n", ctx->vp_slot); */ - avd->variant->configure_stream(avd, hevc_ctx->bufs.inst.addr, - ctx->fifo_idx, ctx->vp_slot); - /* avd_status(avd, ctx->vp_slot); */ - set_header(ctx, &run); + ret = avd_init_job(ctx, AVD_CODEC_HEVC, + run.num_slices + run.num_entry_point_offsets + 1); + if (ret) + goto done; - schedule_delayed_work(&ctx->watchdog_work, msecs_to_jiffies(2000)); + set_header(ctx, &run); stream_slices(ctx, &run); - /* avd_status(avd, ctx->vp_slot); */ avd_run_postamble(ctx, &run.base); - ret = 0; + ret = avd_submit_job(ctx); done: kfree(run.tile_info.ctb_addr_rs_to_ts); kfree(run.tile_info.tile_ids); diff --git a/drivers/media/platform/apple/avd/avd-inst.h b/drivers/media/platform/apple/avd/avd-inst.h index d880575766aa5d..e9b9ef908b8d55 100644 --- a/drivers/media/platform/apple/avd/avd-inst.h +++ b/drivers/media/platform/apple/avd/avd-inst.h @@ -165,30 +165,31 @@ static inline bool boolify(u32 v) return !!(v); } -static inline void push(struct avd_dev *avd, struct avd_ctx *ctx, u32 inst) +static inline void push(struct avd_ctx *ctx, u32 inst) { - writel(inst, avd->ctrl + avd->variant->vp_slot_offset + ctx->vp_slot * 4); + struct avd_job *job = &ctx->job; + struct avd_segment *seg = &job->segments[job->num]; + seg->instructions[seg->num++] = inst; } -static inline void push_address(struct avd_dev *avd, struct avd_ctx *ctx, - dma_addr_t addr) +static inline void push_address(struct avd_ctx *ctx, dma_addr_t addr) { - if (avd->variant->quirks & AVD_QUIRK_LSR) { - push(avd, ctx, (addr >> 8)); + if (ctx->dev->variant->quirks & AVD_QUIRK_LSR) { + push(ctx, (addr >> 8)); } else { - push(avd, ctx, (u32)(addr & 0xffffffff)); - push(avd, ctx, (u32)(addr >> 32)); + push(ctx, (u32)(addr & 0xffffffff)); + push(ctx, (u32)(addr >> 32)); } } -static inline void push_comp(struct avd_dev *avd, struct avd_ctx *ctx, - dma_addr_t addr, u32 offsets[4]) +static inline void push_comp(struct avd_ctx *ctx, dma_addr_t addr, + u32 offsets[4]) { - if (avd->variant->quirks & AVD_QUIRK_LSR) { + if (ctx->dev->variant->quirks & AVD_QUIRK_LSR) { for (int i = 0; i < 4; i++) - push(avd, ctx, (addr + offsets[i]) >> 7); + push(ctx, (addr + offsets[i]) >> 7); } else { for (int i = 0; i < 4; i++) - push_address(avd, ctx, (addr + offsets[i])); + push_address(ctx, (addr + offsets[i])); } } @@ -196,11 +197,11 @@ static inline void push_comp(struct avd_dev *avd, struct avd_ctx *ctx, #define push(inst, name) \ do { \ dev_info(ctx->dev->dev, "%8x | %s", (inst), name); \ - push(avd, ctx, inst); \ + push(ctx, inst); \ } while (0) #else -#define push(inst, name) push(avd, ctx, inst) +#define push(inst, name) push(ctx, inst) #endif #ifdef DEBUG_INST_ADDR @@ -210,11 +211,11 @@ static inline void push_comp(struct avd_dev *avd, struct avd_ctx *ctx, name, i); \ dev_info(ctx->dev->dev, "%8llx | %s[%d] (high)", (inst) >> 32, \ name, i); \ - push_address(avd, ctx, inst); \ + push_address(ctx, inst); \ } while (0) #else -#define pusha(inst, name, i) push_address(avd, ctx, inst) +#define pusha(inst, name, i) push_address(ctx, inst) #endif #endif /* AVD_INST_H_ */ diff --git a/drivers/media/platform/apple/avd/avd-vp9.c b/drivers/media/platform/apple/avd/avd-vp9.c index 5b445d586061ec..07237d33438c89 100644 --- a/drivers/media/platform/apple/avd/avd-vp9.c +++ b/drivers/media/platform/apple/avd/avd-vp9.c @@ -14,9 +14,7 @@ * Alpha Lin */ -#include "linux/v4l2-controls.h" #include -#include #include #include @@ -169,7 +167,6 @@ struct avd_vp9_ctx { static void set_refs(struct avd_ctx *ctx, struct avd_vp9_run *run) { const struct v4l2_ctrl_vp9_frame *frame = run->decode_params; - struct avd_dev *avd = ctx->dev; struct avd_decoded_buffer *dst, *ref_buf[4]; dma_addr_t addr; @@ -196,7 +193,7 @@ static void set_refs(struct avd_ctx *ctx, struct avd_vp9_run *run) "hdr_70_ref_height_width"); push(0x40004000, "hdr_7c_ref_align"); - push_comp(avd, ctx, addr, ref_buf[i]->comp.offsets); + push_comp(ctx, addr, ref_buf[i]->comp.offsets); } } @@ -281,14 +278,6 @@ static void set_header(struct avd_ctx *ctx, struct avd_vp9_run *run) bool intra_only = !!(frame->flags & (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); - push(AVD_OP_EXEC | - AVD_OP_EXEC_FLAG_START_REV3(avd->variant->revision == 3) | - AVD_OP_EXEC_FLAG_START_REV4(avd->variant->revision == 4) | - (avd->variant->revision == 3 ? AVD_OP_EXEC_REV3_VP9_MASK : - 0) | - AVD_OP_EXEC_FIFO_IDX(ctx->fifo_idx), - "inst_fifo_start"); - push(AVD_OP_HDR | AVD_OP_HDR_FLAG_DECOMP(ctx->decomp) | AVD_OP_HDR_FLAG_INTRA(intra_only) | AVD_OP_HDR_CONST | AVD_OP_HDR_FLAG_PIPE_STATE( @@ -374,7 +363,7 @@ static void set_header(struct avd_ctx *ctx, struct avd_vp9_run *run) push(0, ""); - push_comp(avd, ctx, run->base.comp_out, ctx->comp.offsets); + push_comp(ctx, run->base.comp_out, ctx->comp.offsets); pusha((u64)0, "packed_fmt_scratch", 0); @@ -398,11 +387,9 @@ static void set_header(struct avd_ctx *ctx, struct avd_vp9_run *run) static void set_tiles(struct avd_ctx *ctx, struct avd_vp9_run *run) { const struct v4l2_ctrl_vp9_frame *frame = run->decode_params; - struct avd_dev *avd = ctx->dev; struct avd_vp9_ctx *vp9_ctx = ctx->priv; struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); const u8 *data = vb2_plane_vaddr(&src->vb2_buf, 0); - bool is_last; u32 offset = frame->uncompressed_header_size + frame->compressed_header_size; @@ -417,8 +404,7 @@ static void set_tiles(struct avd_ctx *ctx, struct avd_vp9_run *run) for (int row = 0; row < num_tile_rows; row++) for (int col = 0; col < num_tile_cols; col++) { - is_last = row == num_tile_rows - 1 && - col == num_tile_cols - 1; + ctx->job.num++; if (row == num_tile_rows - 1 && col == num_tile_cols - 1) { tile_size = size; @@ -450,11 +436,7 @@ static void set_tiles(struct avd_ctx *ctx, struct avd_vp9_run *run) AVD_SL_DIM_END_X(((col + 1) * sb_64_cols) / num_tile_cols - 1), "til_ac0_tile_dims"); - push(AVD_OP_EXEC | AVD_OP_EXEC_FLAG_END(is_last) | - (avd->variant->revision == 3 ? - AVD_OP_EXEC_REV3_VP9_MASK : - 0), - "cm3_cmd_inst_fifo_end"); + offset += tile_size; size -= tile_size; vp9_ctx->submit_num++; @@ -718,7 +700,6 @@ static int avd_vp9_run_preamble(struct avd_ctx *ctx, struct avd_vp9_run *run) static int avd_vp9_run(struct avd_ctx *ctx) { - struct avd_dev *avd = ctx->dev; struct avd_vp9_run run; struct avd_vp9_ctx *vp9_ctx; struct avd_decoded_buffer *dst; @@ -730,6 +711,14 @@ static int avd_vp9_run(struct avd_ctx *ctx) return ret; } + ret = avd_init_job( + ctx, AVD_CODEC_VP9, + (1 << run.decode_params->tile_rows_log2) * + (1 << run.decode_params->tile_cols_log2) + + 1); + if (ret) + return ret; + init_probs(ctx, &run); vp9_ctx = ctx->priv; @@ -737,24 +726,12 @@ static int avd_vp9_run(struct avd_ctx *ctx) update_dec_buf_info(dst, run.decode_params); update_ctx_cur_info(vp9_ctx, dst, run.decode_params); - ret = alloc_slots(avd, ctx, AVD_CODEC_VP9); - if (ret) { - dev_err(avd->dev, "no free slots: %d", ret); - return ret; - } - - schedule_delayed_work(&ctx->watchdog_work, msecs_to_jiffies(2000)); - - avd->variant->configure_stream(avd, vp9_ctx->bufs.inst.addr, - ctx->fifo_idx, ctx->vp_slot); - set_header(ctx, &run); - vp9_ctx->submit_num = 0; set_tiles(ctx, &run); avd_run_postamble(ctx, &run.base); - return 0; + return avd_submit_job(ctx); } #define copy_tx_and_skip(p1, p2) \ diff --git a/drivers/media/platform/apple/avd/avd.h b/drivers/media/platform/apple/avd/avd.h index 12c1a4abe1e574..98efb70cc666cd 100644 --- a/drivers/media/platform/apple/avd/avd.h +++ b/drivers/media/platform/apple/avd/avd.h @@ -14,7 +14,6 @@ #ifndef AVD_H_ #define AVD_H_ -#include "linux/bitmap.h" #include #include #include @@ -36,9 +35,14 @@ #define VP_SLOT_NONE 255 #define INST_FIFO_SLOT_NONE 255 -/* AVD needs most addresses to be aligned to 256 */ +/* + * AVD needs most addresses to be aligned to 256 + * the only exception are the compressed buffers, they are aligned to 128 + * instead + */ #define AVD_ALIGN 256 - +/* hevc, with a b slice where all references are active and weights are sent */ +#define AVD_MAX_INST 512 struct avd_ctx; struct avd_dev; @@ -97,7 +101,6 @@ struct avd_hevc_decoded_buffer_info { bool is_intra; }; - struct avd_comp { u32 size; /* offset to start of compressed data */ @@ -117,7 +120,6 @@ struct avd_decoded_buffer { struct avd_hevc_decoded_buffer_info hevc; struct avd_av1_decoded_buffer_info av1; }; - }; static inline struct avd_decoded_buffer * @@ -205,12 +207,26 @@ struct avd_dev { struct reset_control *rstc; - unsigned long vp_slots; - unsigned long inst_fifo_slots; - const struct avd_variant *variant; }; +struct avd_segment { + size_t num; + u32 instructions[AVD_MAX_INST]; +}; + +struct avd_job { + enum avd_codec codec; + size_t num; + struct avd_segment *segments; +}; + +struct avd_buf { + void *cpu; + dma_addr_t addr; + size_t size; +}; + struct avd_ctx { struct v4l2_fh fh; struct avd_dev *dev; @@ -228,16 +244,13 @@ struct avd_ctx { void *priv; struct avd_comp comp; - - u8 fifo_idx; - u8 vp_slot; + int fifo_idx; + struct avd_job job; + struct avd_buf inst; }; -struct avd_buf { - void *cpu; - dma_addr_t addr; - size_t size; -}; +int avd_init_job(struct avd_ctx *ctx, enum avd_codec codec, size_t segments); +int avd_submit_job(struct avd_ctx *ctx); int avd_buf_alloc(struct avd_dev *avd, struct avd_buf *buf, size_t size); void avd_buf_free(struct avd_dev *avd, struct avd_buf *buf); @@ -272,19 +285,6 @@ static inline u32 fmt_width(struct avd_ctx *ctx) void fill_comp(struct avd_comp *comp, enum avd_image_fmt image_fmt, u32 width, u32 height); -int alloc_slots(struct avd_dev *avd, struct avd_ctx *ctx, enum avd_codec codec); - -static inline void free_vp_slot(struct avd_dev *avd, struct avd_ctx *ctx) -{ - clear_bit(ctx->vp_slot, &avd->vp_slots); - ctx->vp_slot = VP_SLOT_NONE; -} - -static inline void free_inst_slot(struct avd_dev *avd, struct avd_ctx *ctx) -{ - clear_bit(ctx->fifo_idx, &avd->inst_fifo_slots); - ctx->fifo_idx = INST_FIFO_SLOT_NONE; -} static inline struct avd_ctx *file_to_ctx(struct file *filp) {