// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016 MediaTek Inc. * Author: Jungchang Tsao <[email protected]> * Daniel Hsiao <[email protected]> * PoChun Lin <[email protected]> */ #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/slab.h> #include "../mtk_vcodec_enc_drv.h" #include "../../common/mtk_vcodec_intr.h" #include "../mtk_vcodec_enc.h" #include "../mtk_vcodec_enc_pm.h" #include "../venc_drv_base.h" #include "../venc_ipi_msg.h" #include "../venc_vpu_if.h" static const char h264_filler_marker[] = …; #define H264_FILLER_MARKER_SIZE … #define VENC_PIC_BITSTREAM_BYTE_CNT … /* * enum venc_h264_frame_type - h264 encoder output bitstream frame type */ enum venc_h264_frame_type { … }; /* * enum venc_h264_vpu_work_buf - h264 encoder buffer index */ enum venc_h264_vpu_work_buf { … }; /* * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode */ enum venc_h264_bs_mode { … }; /* * struct venc_h264_vpu_config - Structure for h264 encoder configuration * AP-W/R : AP is writer/reader on this item * VPU-W/R: VPU is write/reader on this item * @input_fourcc: input fourcc * @bitrate: target bitrate (in bps) * @pic_w: picture width. Picture size is visible stream resolution, in pixels, * to be used for display purposes; must be smaller or equal to buffer * size. * @pic_h: picture height * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to * hardware requirements. * @buf_h: buffer height * @gop_size: group of picture size (idr frame) * @intra_period: intra frame period * @framerate: frame rate in fps * @profile: as specified in standard * @level: as specified in standard * @wfd: WFD mode 1:on, 0:off */ struct venc_h264_vpu_config { … }; /* * struct venc_h264_vpu_buf - Structure for buffer information * AP-W/R : AP is writer/reader on this item * VPU-W/R: VPU is write/reader on this item * @iova: IO virtual address * @vpua: VPU side memory addr which is used by RC_CODE * @size: buffer size (in bytes) */ struct venc_h264_vpu_buf { … }; /* * struct venc_h264_vsi - Structure for VPU driver control and info share * AP-W/R : AP is writer/reader on this item * VPU-W/R: VPU is write/reader on this item * This structure is allocated in VPU side and shared to AP side. * @config: h264 encoder configuration * @work_bufs: working buffer information in VPU side * The work_bufs here is for storing the 'size' info shared to AP side. * The similar item in struct venc_h264_inst is for memory allocation * in AP side. The AP driver will copy the 'size' from here to the one in * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for * register setting in VPU side. */ struct venc_h264_vsi { … }; /** * struct venc_h264_vpu_config_ext - Structure for h264 encoder configuration * AP-W/R : AP is writer/reader on this item * VPU-W/R: VPU is write/reader on this item * @input_fourcc: input fourcc * @bitrate: target bitrate (in bps) * @pic_w: picture width. Picture size is visible stream resolution, in pixels, * to be used for display purposes; must be smaller or equal to buffer * size. * @pic_h: picture height * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to * hardware requirements. * @buf_h: buffer height * @gop_size: group of picture size (idr frame) * @intra_period: intra frame period * @framerate: frame rate in fps * @profile: as specified in standard * @level: as specified in standard * @wfd: WFD mode 1:on, 0:off * @max_qp: max quant parameter * @min_qp: min quant parameter * @reserved: reserved configs */ struct venc_h264_vpu_config_ext { … }; /** * struct venc_h264_vpu_buf_34 - Structure for 34-bit buffer information * AP-W/R : AP is writer/reader on this item * VPU-W/R: VPU is write/reader on this item * @iova: 34-bit IO virtual address * @vpua: VPU side memory addr which is used by RC_CODE * @size: buffer size (in bytes) */ struct venc_h264_vpu_buf_34 { … }; /** * struct venc_h264_vsi_34 - Structure for VPU driver control and info share * Used for 34-bit iova sharing * @config: h264 encoder configuration * @work_bufs: working buffer information in VPU side */ struct venc_h264_vsi_34 { … }; /* * struct venc_h264_inst - h264 encoder AP driver instance * @hw_base: h264 encoder hardware register base * @work_bufs: working buffer * @pps_buf: buffer to store the pps bitstream * @work_buf_allocated: working buffer allocated flag * @frm_cnt: encoded frame count * @prepend_hdr: when the v4l2 layer send VENC_SET_PARAM_PREPEND_HEADER cmd * through h264_enc_set_param interface, it will set this flag and prepend the * sps/pps in h264_enc_encode function. * @vpu_inst: VPU instance to exchange information between AP and VPU * @vsi: driver structure allocated by VPU side and shared to AP side for * control and info share * @vsi_34: driver structure allocated by VPU side and shared to AP side for * control and info share, used for 34-bit iova sharing. * @ctx: context for v4l2 layer integration */ struct venc_h264_inst { … }; static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) { … } static unsigned int h264_get_profile(struct venc_h264_inst *inst, unsigned int profile) { … } static unsigned int h264_get_level(struct venc_h264_inst *inst, unsigned int level) { … } static void h264_enc_free_work_buf(struct venc_h264_inst *inst) { … } static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) { … } static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst) { … } static int h264_frame_type(unsigned int frm_cnt, unsigned int gop_size, unsigned int intra_period) { … } static int h264_encode_sps(struct venc_h264_inst *inst, struct mtk_vcodec_mem *bs_buf, unsigned int *bs_size) { … } static int h264_encode_pps(struct venc_h264_inst *inst, struct mtk_vcodec_mem *bs_buf, unsigned int *bs_size) { … } static int h264_encode_header(struct venc_h264_inst *inst, struct mtk_vcodec_mem *bs_buf, unsigned int *bs_size) { … } static int h264_encode_frame(struct venc_h264_inst *inst, struct venc_frm_buf *frm_buf, struct mtk_vcodec_mem *bs_buf, unsigned int *bs_size) { … } static void h264_encode_filler(struct venc_h264_inst *inst, void *buf, int size) { … } static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx) { … } static int h264_enc_encode(void *handle, enum venc_start_opt opt, struct venc_frm_buf *frm_buf, struct mtk_vcodec_mem *bs_buf, struct venc_done_result *result) { … } static void h264_enc_set_vsi_configs(struct venc_h264_inst *inst, struct venc_enc_param *enc_prm) { … } static void h264_enc_set_vsi_34_configs(struct venc_h264_inst *inst, struct venc_enc_param *enc_prm) { … } static int h264_enc_set_param(void *handle, enum venc_set_param_type type, struct venc_enc_param *enc_prm) { … } static int h264_enc_deinit(void *handle) { … } const struct venc_common_if venc_h264_if = …;