/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) STMicroelectronics SA 2015 * Authors: Yannick Fertre <yannick.fertre@st.com> * Hugues Fruchet <hugues.fruchet@st.com> */ #ifndef HVA_H #define HVA_H #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/videobuf2-v4l2.h> #include <media/v4l2-mem2mem.h> #define fh_to_ctx(f) (container_of(f, struct hva_ctx, fh)) #define hva_to_dev(h) (h->dev) #define ctx_to_dev(c) (c->hva_dev->dev) #define ctx_to_hdev(c) (c->hva_dev) #define HVA_NAME "st-hva" #define HVA_PREFIX "[---:----]" extern const struct hva_enc nv12h264enc; extern const struct hva_enc nv21h264enc; /** * struct hva_frameinfo - information about hva frame * * @pixelformat: fourcc code for uncompressed video format * @width: width of frame * @height: height of frame * @aligned_width: width of frame (with encoder alignment constraint) * @aligned_height: height of frame (with encoder alignment constraint) * @size: maximum size in bytes required for data */ struct hva_frameinfo { u32 pixelformat; u32 width; u32 height; u32 aligned_width; u32 aligned_height; u32 size; }; /** * struct hva_streaminfo - information about hva stream * * @streamformat: fourcc code of compressed video format (H.264...) * @width: width of stream * @height: height of stream * @profile: profile string * @level: level string */ struct hva_streaminfo { u32 streamformat; u32 width; u32 height; u8 profile[32]; u8 level[32]; }; /** * struct hva_controls - hva controls set * * @time_per_frame: time per frame in seconds * @bitrate_mode: bitrate mode (constant bitrate or variable bitrate) * @gop_size: groupe of picture size * @bitrate: bitrate (in bps) * @aspect: video aspect * @profile: H.264 profile * @level: H.264 level * @entropy_mode: H.264 entropy mode (CABAC or CVLC) * @cpb_size: coded picture buffer size (in kB) * @dct8x8: transform mode 8x8 enable * @qpmin: minimum quantizer * @qpmax: maximum quantizer * @vui_sar: pixel aspect ratio enable * @vui_sar_idc: pixel aspect ratio identifier * @sei_fp: sei frame packing arrangement enable * @sei_fp_type: sei frame packing arrangement type */ struct hva_controls { struct v4l2_fract time_per_frame; enum v4l2_mpeg_video_bitrate_mode bitrate_mode; u32 gop_size; u32 bitrate; enum v4l2_mpeg_video_aspect aspect; enum v4l2_mpeg_video_h264_profile profile; enum v4l2_mpeg_video_h264_level level; enum v4l2_mpeg_video_h264_entropy_mode entropy_mode; u32 cpb_size; bool dct8x8; u32 qpmin; u32 qpmax; bool vui_sar; enum v4l2_mpeg_video_h264_vui_sar_idc vui_sar_idc; bool sei_fp; enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_type; }; /** * struct hva_frame - hva frame buffer (output) * * @vbuf: video buffer information for V4L2 * @list: V4L2 m2m list that the frame belongs to * @info: frame information (width, height, format, alignment...) * @paddr: physical address (for hardware) * @vaddr: virtual address (kernel can read/write) * @prepared: true if vaddr/paddr are resolved */ struct hva_frame { struct vb2_v4l2_buffer vbuf; struct list_head list; struct hva_frameinfo info; dma_addr_t paddr; void *vaddr; bool prepared; }; /* * to_hva_frame() - cast struct vb2_v4l2_buffer * to struct hva_frame * */ #define to_hva_frame(vb) \ container_of(vb, struct hva_frame, vbuf) /** * struct hva_stream - hva stream buffer (capture) * * @vbuf: video buffer information for V4L2 * @list: V4L2 m2m list that the frame belongs to * @paddr: physical address (for hardware) * @vaddr: virtual address (kernel can read/write) * @prepared: true if vaddr/paddr are resolved * @size: size of the buffer in bytes * @bytesused: number of bytes occupied by data in the buffer */ struct hva_stream { struct vb2_v4l2_buffer vbuf; struct list_head list; dma_addr_t paddr; void *vaddr; bool prepared; unsigned int size; unsigned int bytesused; }; /* * to_hva_stream() - cast struct vb2_v4l2_buffer * to struct hva_stream * */ #define to_hva_stream(vb) \ container_of(vb, struct hva_stream, vbuf) #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS /** * struct hva_ctx_dbg - instance context debug info * * @debugfs_entry: debugfs entry * @is_valid_period: true if the sequence is valid for performance * @begin: start time of last HW task * @total_duration: total HW processing durations in 0.1ms * @cnt_duration: number of HW processings * @min_duration: minimum HW processing duration in 0.1ms * @max_duration: maximum HW processing duration in 0.1ms * @avg_duration: average HW processing duration in 0.1ms * @max_fps: maximum frames encoded per second (in 0.1Hz) * @total_period: total encoding periods in 0.1ms * @cnt_period: number of periods * @min_period: minimum encoding period in 0.1ms * @max_period: maximum encoding period in 0.1ms * @avg_period: average encoding period in 0.1ms * @total_stream_size: total number of encoded bytes * @avg_fps: average frames encoded per second (in 0.1Hz) * @window_duration: duration of the sampling window in 0.1ms * @cnt_window: number of samples in the window * @window_stream_size: number of encoded bytes upon the sampling window * @last_bitrate: bitrate upon the last sampling window * @min_bitrate: minimum bitrate in kbps * @max_bitrate: maximum bitrate in kbps * @avg_bitrate: average bitrate in kbps */ struct hva_ctx_dbg { struct dentry *debugfs_entry; bool is_valid_period; ktime_t begin; u32 total_duration; u32 cnt_duration; u32 min_duration; u32 max_duration; u32 avg_duration; u32 max_fps; u32 total_period; u32 cnt_period; u32 min_period; u32 max_period; u32 avg_period; u32 total_stream_size; u32 avg_fps; u32 window_duration; u32 cnt_window; u32 window_stream_size; u32 last_bitrate; u32 min_bitrate; u32 max_bitrate; u32 avg_bitrate; }; #endif struct hva_dev; struct hva_enc; /** * struct hva_ctx - context of hva instance * * @hva_dev: the device that this instance is associated with * @fh: V4L2 file handle * @ctrl_handler: V4L2 controls handler * @ctrls: hva controls set * @id: instance identifier * @aborting: true if current job aborted * @name: instance name (debug purpose) * @run_work: encode work * @lock: mutex used to lock access of this context * @flags: validity of streaminfo and frameinfo fields * @frame_num: frame number * @stream_num: stream number * @max_stream_size: maximum size in bytes required for stream data * @colorspace: colorspace identifier * @xfer_func: transfer function identifier * @ycbcr_enc: Y'CbCr encoding identifier * @quantization: quantization identifier * @streaminfo: stream properties * @frameinfo: frame properties * @enc: current encoder * @priv: private codec data for this instance, allocated * by encoder @open time * @hw_err: true if hardware error detected * @encoded_frames: number of encoded frames * @sys_errors: number of system errors (memory, resource, pm...) * @encode_errors: number of encoding errors (hw/driver errors) * @frame_errors: number of frame errors (format, size, header...) * @dbg: context debug info */ struct hva_ctx { struct hva_dev *hva_dev; struct v4l2_fh fh; struct v4l2_ctrl_handler ctrl_handler; struct hva_controls ctrls; u8 id; bool aborting; char name[100]; struct work_struct run_work; /* mutex protecting this data structure */ struct mutex lock; u32 flags; u32 frame_num; u32 stream_num; u32 max_stream_size; enum v4l2_colorspace colorspace; enum v4l2_xfer_func xfer_func; enum v4l2_ycbcr_encoding ycbcr_enc; enum v4l2_quantization quantization; struct hva_streaminfo streaminfo; struct hva_frameinfo frameinfo; struct hva_enc *enc; void *priv; bool hw_err; u32 encoded_frames; u32 sys_errors; u32 encode_errors; u32 frame_errors; #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS struct hva_ctx_dbg dbg; #endif }; #define HVA_FLAG_STREAMINFO 0x0001 #define HVA_FLAG_FRAMEINFO 0x0002 #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS /** * struct hva_dev_dbg - device debug info * * @debugfs_entry: debugfs entry * @last_ctx: debug information about last running instance context */ struct hva_dev_dbg { struct dentry *debugfs_entry; struct hva_ctx last_ctx; }; #endif #define HVA_MAX_INSTANCES 16 #define HVA_MAX_ENCODERS 10 #define HVA_MAX_FORMATS HVA_MAX_ENCODERS /** * struct hva_dev - abstraction for hva entity * * @v4l2_dev: V4L2 device * @vdev: video device * @pdev: platform device * @dev: device * @lock: mutex used for critical sections & V4L2 ops * serialization * @m2m_dev: memory-to-memory V4L2 device information * @instances: opened instances * @nb_of_instances: number of opened instances * @instance_id: rolling counter identifying an instance (debug purpose) * @regs: register io memory access * @esram_addr: esram address * @esram_size: esram size * @clk: hva clock * @irq_its: status interruption * @irq_err: error interruption * @work_queue: work queue to handle the encode jobs * @protect_mutex: mutex used to lock access of hardware * @interrupt: completion interrupt * @ip_version: IP hardware version * @encoders: registered encoders * @nb_of_encoders: number of registered encoders * @pixelformats: supported uncompressed video formats * @nb_of_pixelformats: number of supported umcompressed video formats * @streamformats: supported compressed video formats * @nb_of_streamformats: number of supported compressed video formats * @sfl_reg: status fifo level register value * @sts_reg: status register value * @lmi_err_reg: local memory interface error register value * @emi_err_reg: external memory interface error register value * @hec_mif_err_reg: HEC memory interface error register value * @dbg: device debug info */ struct hva_dev { struct v4l2_device v4l2_dev; struct video_device *vdev; struct platform_device *pdev; struct device *dev; /* mutex protecting vb2_queue structure */ struct mutex lock; struct v4l2_m2m_dev *m2m_dev; struct hva_ctx *instances[HVA_MAX_INSTANCES]; unsigned int nb_of_instances; unsigned int instance_id; void __iomem *regs; u32 esram_addr; u32 esram_size; struct clk *clk; int irq_its; int irq_err; struct workqueue_struct *work_queue; /* mutex protecting hardware access */ struct mutex protect_mutex; struct completion interrupt; unsigned long int ip_version; const struct hva_enc *encoders[HVA_MAX_ENCODERS]; u32 nb_of_encoders; u32 pixelformats[HVA_MAX_FORMATS]; u32 nb_of_pixelformats; u32 streamformats[HVA_MAX_FORMATS]; u32 nb_of_streamformats; u32 sfl_reg; u32 sts_reg; u32 lmi_err_reg; u32 emi_err_reg; u32 hec_mif_err_reg; #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS struct hva_dev_dbg dbg; #endif }; /** * struct hva_enc - hva encoder * * @name: encoder name * @streamformat: fourcc code for compressed video format (H.264...) * @pixelformat: fourcc code for uncompressed video format * @max_width: maximum width of frame for this encoder * @max_height: maximum height of frame for this encoder * @open: open encoder * @close: close encoder * @encode: encode a frame (struct hva_frame) in a stream * (struct hva_stream) */ struct hva_enc { const char *name; u32 streamformat; u32 pixelformat; u32 max_width; u32 max_height; int (*open)(struct hva_ctx *ctx); int (*close)(struct hva_ctx *ctx); int (*encode)(struct hva_ctx *ctx, struct hva_frame *frame, struct hva_stream *stream); }; #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS void hva_debugfs_create(struct hva_dev *hva); void hva_debugfs_remove(struct hva_dev *hva); void hva_dbg_ctx_create(struct hva_ctx *ctx); void hva_dbg_ctx_remove(struct hva_ctx *ctx); void hva_dbg_perf_begin(struct hva_ctx *ctx); void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream); #endif #endif /* HVA_H */