xref: /linux/drivers/media/pci/tw5864/tw5864.h (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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