FILE
hantro_g2.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/verisilicon/hantro_g2.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Hantro VPU codec driver 4 * 5 * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz <andrzej.p@collabora.com> 6 */ 7 8#include <linux/delay.h> 9#include "hantro_hw.h" 10#include "hantro_g2_regs.h" 11 12#define G2_ALIGN 16 13 14static bool hantro_g2_active(struct hantro_ctx *ctx) 15{ 16 struct hantro_dev *vpu = ctx->dev; 17 u32 status; 18 19 status = vdpu_read(vpu, G2_REG_INTERRUPT); 20 21 return (status & G2_REG_INTERRUPT_DEC_E); 22} 23 24/** 25 * hantro_g2_reset: 26 * @ctx: the hantro context 27 * 28 * Emulates a reset using Hantro abort function. Failing this procedure would 29 * results in programming a running IP which leads to CPU hang. 30 * 31 * Using a hard reset procedure instead is prefferred. 32 */ 33void hantro_g2_reset(struct hantro_ctx *ctx) 34{ 35 struct hantro_dev *vpu = ctx->dev; 36 u32 status; 37 38 status = vdpu_read(vpu, G2_REG_INTERRUPT); 39 if (status & G2_REG_INTERRUPT_DEC_E) { 40 dev_warn_ratelimited(vpu->dev, "device still running, aborting"); 41 status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; 42 vdpu_write(vpu, status, G2_REG_INTERRUPT); 43 44 do { 45 mdelay(1); 46 } while (hantro_g2_active(ctx)); 47 } 48} 49 50irqreturn_t hantro_g2_irq(int irq, void *dev_id) 51{ 52 struct hantro_dev *vpu = dev_id; 53 u32 status; 54 55 status = vdpu_read(vpu, G2_REG_INTERRUPT); 56 57 if (!(status & G2_REG_INTERRUPT_DEC_IRQ)) 58 return IRQ_NONE; 59 60 hantro_reg_write(vpu, &g2_dec_irq, 0); 61 hantro_reg_write(vpu, &g2_dec_int_stat, 0); 62 hantro_reg_write(vpu, &g2_clk_gate_e, 1); 63 64 if (status & G2_REG_INTERRUPT_DEC_RDY_INT) { 65 hantro_irq_done(vpu, VB2_BUF_STATE_DONE); 66 return IRQ_HANDLED; 67 } 68 69 if (status & G2_REG_INTERRUPT_DEC_ABORT_INT) { 70 /* disabled on abort, though lets be safe and handle it */ 71 dev_warn_ratelimited(vpu->dev, "decode operation aborted."); 72 return IRQ_HANDLED; 73 } 74 75 if (status & G2_REG_INTERRUPT_DEC_LAST_SLICE_INT) 76 dev_warn_ratelimited(vpu->dev, "not all macroblocks were decoded."); 77 78 if (status & G2_REG_INTERRUPT_DEC_BUS_INT) 79 dev_warn_ratelimited(vpu->dev, "bus error detected."); 80 81 if (status & G2_REG_INTERRUPT_DEC_ERROR_INT) 82 dev_warn_ratelimited(vpu->dev, "decode error detected."); 83 84 if (status & G2_REG_INTERRUPT_DEC_TIMEOUT) 85 dev_warn_ratelimited(vpu->dev, "frame decode timed out."); 86 87 /** 88 * If the decoding haven't stopped, let it continue. The hardware timeout 89 * will trigger if it is trully stuck. 90 */ 91 if (status & G2_REG_INTERRUPT_DEC_E) 92 return IRQ_HANDLED; 93 94 hantro_irq_done(vpu, VB2_BUF_STATE_ERROR); 95 return IRQ_HANDLED; 96} 97 98size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx) 99{ 100 return ctx->ref_fmt.plane_fmt[0].bytesperline * ctx->ref_fmt.height; 101} 102 103size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx) 104{ 105 size_t cr_offset = hantro_g2_chroma_offset(ctx); 106 107 return ALIGN((cr_offset * 3) / 2, G2_ALIGN); 108} 109 110static size_t hantro_g2_mv_size(struct hantro_ctx *ctx) 111{ 112 const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; 113 const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; 114 unsigned int pic_width_in_ctbs, pic_height_in_ctbs; 115 unsigned int max_log2_ctb_size; 116 117 max_log2_ctb_size = sps->log2_min_luma_coding_block_size_minus3 + 3 + 118 sps->log2_diff_max_min_luma_coding_block_size; 119 pic_width_in_ctbs = (sps->pic_width_in_luma_samples + 120 (1 << max_log2_ctb_size) - 1) >> max_log2_ctb_size; 121 pic_height_in_ctbs = (sps->pic_height_in_luma_samples + (1 << max_log2_ctb_size) - 1) 122 >> max_log2_ctb_size; 123 124 return pic_width_in_ctbs * pic_height_in_ctbs * (1 << (2 * (max_log2_ctb_size - 4))) * 16; 125} 126 127size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx) 128{ 129 return hantro_g2_motion_vectors_offset(ctx) + 130 hantro_g2_mv_size(ctx); 131} 132 133size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx) 134{ 135 return hantro_g2_luma_compress_offset(ctx) + 136 hantro_hevc_luma_compressed_size(ctx->dst_fmt.width, ctx->dst_fmt.height); 137}
~/
Read-only file preview.