1c942fddfSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 234d1324eSAndrey Utkin /* 334d1324eSAndrey Utkin * TW5864 driver - common header file 434d1324eSAndrey Utkin * 534d1324eSAndrey Utkin * Copyright (C) 2016 Bluecherry, LLC <maintainers@bluecherrydvr.com> 634d1324eSAndrey Utkin */ 734d1324eSAndrey Utkin 834d1324eSAndrey Utkin #include <linux/pci.h> 934d1324eSAndrey Utkin #include <linux/videodev2.h> 1034d1324eSAndrey Utkin #include <linux/notifier.h> 1134d1324eSAndrey Utkin #include <linux/delay.h> 1234d1324eSAndrey Utkin #include <linux/mutex.h> 1334d1324eSAndrey Utkin #include <linux/io.h> 1434d1324eSAndrey Utkin #include <linux/interrupt.h> 15*1021dd01SAllen Pais #include <linux/workqueue.h> 1634d1324eSAndrey Utkin 1734d1324eSAndrey Utkin #include <media/v4l2-common.h> 1834d1324eSAndrey Utkin #include <media/v4l2-ioctl.h> 1934d1324eSAndrey Utkin #include <media/v4l2-ctrls.h> 2034d1324eSAndrey Utkin #include <media/v4l2-device.h> 2134d1324eSAndrey Utkin #include <media/videobuf2-dma-sg.h> 2234d1324eSAndrey Utkin 2334d1324eSAndrey Utkin #include "tw5864-reg.h" 2434d1324eSAndrey Utkin 2534d1324eSAndrey Utkin #define PCI_DEVICE_ID_TECHWELL_5864 0x5864 2634d1324eSAndrey Utkin 2734d1324eSAndrey Utkin #define TW5864_NORMS V4L2_STD_ALL 2834d1324eSAndrey Utkin 2934d1324eSAndrey Utkin /* ----------------------------------------------------------- */ 3034d1324eSAndrey Utkin /* card configuration */ 3134d1324eSAndrey Utkin 3234d1324eSAndrey Utkin #define TW5864_INPUTS 4 3334d1324eSAndrey Utkin 3434d1324eSAndrey Utkin /* The TW5864 uses 192 (16x12) detection cells in full screen for motion 3534d1324eSAndrey Utkin * detection. Each detection cell is composed of 44 pixels and 20 lines for 3634d1324eSAndrey Utkin * NTSC and 24 lines for PAL. 3734d1324eSAndrey Utkin */ 3834d1324eSAndrey Utkin #define MD_CELLS_HOR 16 3934d1324eSAndrey Utkin #define MD_CELLS_VERT 12 4034d1324eSAndrey Utkin #define MD_CELLS (MD_CELLS_HOR * MD_CELLS_VERT) 4134d1324eSAndrey Utkin 4234d1324eSAndrey Utkin #define H264_VLC_BUF_SIZE 0x80000 4334d1324eSAndrey Utkin #define H264_MV_BUF_SIZE 0x2000 /* device writes 5396 bytes */ 4434d1324eSAndrey Utkin #define QP_VALUE 28 4534d1324eSAndrey Utkin #define MAX_GOP_SIZE 255 4634d1324eSAndrey Utkin #define GOP_SIZE MAX_GOP_SIZE 4734d1324eSAndrey Utkin 4834d1324eSAndrey Utkin enum resolution { 4934d1324eSAndrey Utkin D1 = 1, 5034d1324eSAndrey Utkin HD1 = 2, /* half d1 - 360x(240|288) */ 5134d1324eSAndrey Utkin CIF = 3, 5234d1324eSAndrey Utkin QCIF = 4, 5334d1324eSAndrey Utkin }; 5434d1324eSAndrey Utkin 5534d1324eSAndrey Utkin /* ----------------------------------------------------------- */ 5634d1324eSAndrey Utkin /* device / file handle status */ 5734d1324eSAndrey Utkin 5834d1324eSAndrey Utkin struct tw5864_dev; /* forward delclaration */ 5934d1324eSAndrey Utkin 6034d1324eSAndrey Utkin /* buffer for one video/vbi/ts frame */ 6134d1324eSAndrey Utkin struct tw5864_buf { 6234d1324eSAndrey Utkin struct vb2_v4l2_buffer vb; 6334d1324eSAndrey Utkin struct list_head list; 6434d1324eSAndrey Utkin 6534d1324eSAndrey Utkin unsigned int size; 6634d1324eSAndrey Utkin }; 6734d1324eSAndrey Utkin 6834d1324eSAndrey Utkin struct tw5864_dma_buf { 6934d1324eSAndrey Utkin void *addr; 7034d1324eSAndrey Utkin dma_addr_t dma_addr; 7134d1324eSAndrey Utkin }; 7234d1324eSAndrey Utkin 7334d1324eSAndrey Utkin enum tw5864_vid_std { 7434d1324eSAndrey Utkin STD_NTSC = 0, /* NTSC (M) */ 7534d1324eSAndrey Utkin STD_PAL = 1, /* PAL (B, D, G, H, I) */ 7634d1324eSAndrey Utkin STD_SECAM = 2, /* SECAM */ 7734d1324eSAndrey Utkin STD_NTSC443 = 3, /* NTSC4.43 */ 7834d1324eSAndrey Utkin STD_PAL_M = 4, /* PAL (M) */ 7934d1324eSAndrey Utkin STD_PAL_CN = 5, /* PAL (CN) */ 8034d1324eSAndrey Utkin STD_PAL_60 = 6, /* PAL 60 */ 8134d1324eSAndrey Utkin STD_INVALID = 7, 8234d1324eSAndrey Utkin STD_AUTO = 7, 8334d1324eSAndrey Utkin }; 8434d1324eSAndrey Utkin 8534d1324eSAndrey Utkin struct tw5864_input { 8634d1324eSAndrey Utkin int nr; /* input number */ 8734d1324eSAndrey Utkin struct tw5864_dev *root; 8834d1324eSAndrey Utkin struct mutex lock; /* used for vidq and vdev */ 89*1021dd01SAllen Pais spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ 9034d1324eSAndrey Utkin struct video_device vdev; 9134d1324eSAndrey Utkin struct v4l2_ctrl_handler hdl; 9234d1324eSAndrey Utkin struct vb2_queue vidq; 9334d1324eSAndrey Utkin struct list_head active; 9434d1324eSAndrey Utkin enum resolution resolution; 9534d1324eSAndrey Utkin unsigned int width, height; 9634d1324eSAndrey Utkin unsigned int frame_seqno; 9734d1324eSAndrey Utkin unsigned int frame_gop_seqno; 9834d1324eSAndrey Utkin unsigned int h264_idr_pic_id; 9934d1324eSAndrey Utkin int enabled; 10034d1324eSAndrey Utkin enum tw5864_vid_std std; 10134d1324eSAndrey Utkin v4l2_std_id v4l2_std; 10234d1324eSAndrey Utkin int tail_nb_bits; 10334d1324eSAndrey Utkin u8 tail; 10434d1324eSAndrey Utkin u8 *buf_cur_ptr; 10534d1324eSAndrey Utkin int buf_cur_space_left; 10634d1324eSAndrey Utkin 10734d1324eSAndrey Utkin u32 reg_interlacing; 10834d1324eSAndrey Utkin u32 reg_vlc; 10934d1324eSAndrey Utkin u32 reg_dsp_codec; 11034d1324eSAndrey Utkin u32 reg_dsp; 11134d1324eSAndrey Utkin u32 reg_emu; 11234d1324eSAndrey Utkin u32 reg_dsp_qp; 11334d1324eSAndrey Utkin u32 reg_dsp_ref_mvp_lambda; 11434d1324eSAndrey Utkin u32 reg_dsp_i4x4_weight; 11534d1324eSAndrey Utkin u32 buf_id; 11634d1324eSAndrey Utkin 11734d1324eSAndrey Utkin struct tw5864_buf *vb; 11834d1324eSAndrey Utkin 11934d1324eSAndrey Utkin struct v4l2_ctrl *md_threshold_grid_ctrl; 12034d1324eSAndrey Utkin u16 md_threshold_grid_values[12 * 16]; 12134d1324eSAndrey Utkin int qp; 12234d1324eSAndrey Utkin int gop; 12334d1324eSAndrey Utkin 12434d1324eSAndrey Utkin /* 12534d1324eSAndrey Utkin * In (1/MAX_FPS) units. 12634d1324eSAndrey Utkin * For max FPS (default), set to 1. 12734d1324eSAndrey Utkin * For 1 FPS, set to e.g. 32. 12834d1324eSAndrey Utkin */ 12934d1324eSAndrey Utkin int frame_interval; 13034d1324eSAndrey Utkin unsigned long new_frame_deadline; 13134d1324eSAndrey Utkin }; 13234d1324eSAndrey Utkin 13334d1324eSAndrey Utkin struct tw5864_h264_frame { 13434d1324eSAndrey Utkin struct tw5864_dma_buf vlc; 13534d1324eSAndrey Utkin struct tw5864_dma_buf mv; 13634d1324eSAndrey Utkin int vlc_len; 13734d1324eSAndrey Utkin u32 checksum; 13834d1324eSAndrey Utkin struct tw5864_input *input; 13934d1324eSAndrey Utkin u64 timestamp; 14034d1324eSAndrey Utkin unsigned int seqno; 14134d1324eSAndrey Utkin unsigned int gop_seqno; 14234d1324eSAndrey Utkin }; 14334d1324eSAndrey Utkin 14434d1324eSAndrey Utkin /* global device status */ 14534d1324eSAndrey Utkin struct tw5864_dev { 146*1021dd01SAllen Pais spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */ 14734d1324eSAndrey Utkin struct v4l2_device v4l2_dev; 14834d1324eSAndrey Utkin struct tw5864_input inputs[TW5864_INPUTS]; 14934d1324eSAndrey Utkin #define H264_BUF_CNT 4 15034d1324eSAndrey Utkin struct tw5864_h264_frame h264_buf[H264_BUF_CNT]; 15134d1324eSAndrey Utkin int h264_buf_r_index; 15234d1324eSAndrey Utkin int h264_buf_w_index; 15334d1324eSAndrey Utkin 154*1021dd01SAllen Pais struct work_struct bh_work; 15534d1324eSAndrey Utkin 15634d1324eSAndrey Utkin int encoder_busy; 15734d1324eSAndrey Utkin /* Input number to check next for ready raw picture (in RR fashion) */ 15834d1324eSAndrey Utkin int next_input; 15934d1324eSAndrey Utkin 16034d1324eSAndrey Utkin /* pci i/o */ 16134d1324eSAndrey Utkin char name[64]; 16234d1324eSAndrey Utkin struct pci_dev *pci; 16334d1324eSAndrey Utkin void __iomem *mmio; 16434d1324eSAndrey Utkin u32 irqmask; 16534d1324eSAndrey Utkin }; 16634d1324eSAndrey Utkin 16734d1324eSAndrey Utkin #define tw_readl(reg) readl(dev->mmio + reg) 16834d1324eSAndrey Utkin #define tw_mask_readl(reg, mask) \ 16934d1324eSAndrey Utkin (tw_readl(reg) & (mask)) 17034d1324eSAndrey Utkin #define tw_mask_shift_readl(reg, mask, shift) \ 17134d1324eSAndrey Utkin (tw_mask_readl((reg), ((mask) << (shift))) >> (shift)) 17234d1324eSAndrey Utkin 17334d1324eSAndrey Utkin #define tw_writel(reg, value) writel((value), dev->mmio + reg) 17434d1324eSAndrey Utkin #define tw_mask_writel(reg, mask, value) \ 17534d1324eSAndrey Utkin tw_writel(reg, (tw_readl(reg) & ~(mask)) | ((value) & (mask))) 17634d1324eSAndrey Utkin #define tw_mask_shift_writel(reg, mask, shift, value) \ 17734d1324eSAndrey Utkin tw_mask_writel((reg), ((mask) << (shift)), ((value) << (shift))) 17834d1324eSAndrey Utkin 17934d1324eSAndrey Utkin #define tw_setl(reg, bit) tw_writel((reg), tw_readl(reg) | (bit)) 18034d1324eSAndrey Utkin #define tw_clearl(reg, bit) tw_writel((reg), tw_readl(reg) & ~(bit)) 18134d1324eSAndrey Utkin 18234d1324eSAndrey Utkin u8 tw5864_indir_readb(struct tw5864_dev *dev, u16 addr); 18334d1324eSAndrey Utkin #define tw_indir_readb(addr) tw5864_indir_readb(dev, addr) 18434d1324eSAndrey Utkin void tw5864_indir_writeb(struct tw5864_dev *dev, u16 addr, u8 data); 18534d1324eSAndrey Utkin #define tw_indir_writeb(addr, data) tw5864_indir_writeb(dev, addr, data) 18634d1324eSAndrey Utkin 18734d1324eSAndrey Utkin void tw5864_irqmask_apply(struct tw5864_dev *dev); 18834d1324eSAndrey Utkin int tw5864_video_init(struct tw5864_dev *dev, int *video_nr); 18934d1324eSAndrey Utkin void tw5864_video_fini(struct tw5864_dev *dev); 19034d1324eSAndrey Utkin void tw5864_prepare_frame_headers(struct tw5864_input *input); 19134d1324eSAndrey Utkin void tw5864_h264_put_stream_header(u8 **buf, size_t *space_left, int qp, 19234d1324eSAndrey Utkin int width, int height); 19334d1324eSAndrey Utkin void tw5864_h264_put_slice_header(u8 **buf, size_t *space_left, 19434d1324eSAndrey Utkin unsigned int idr_pic_id, 19534d1324eSAndrey Utkin unsigned int frame_gop_seqno, 19634d1324eSAndrey Utkin int *tail_nb_bits, u8 *tail); 19734d1324eSAndrey Utkin void tw5864_request_encoded_frame(struct tw5864_input *input); 198