cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

saa7146_vbi.c (13960B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <media/drv-intf/saa7146_vv.h>
      3
      4static int vbi_pixel_to_capture = 720 * 2;
      5
      6static int vbi_workaround(struct saa7146_dev *dev)
      7{
      8	struct saa7146_vv *vv = dev->vv_data;
      9
     10	u32          *cpu;
     11	dma_addr_t   dma_addr;
     12
     13	int count = 0;
     14	int i;
     15
     16	DECLARE_WAITQUEUE(wait, current);
     17
     18	DEB_VBI("dev:%p\n", dev);
     19
     20	/* once again, a bug in the saa7146: the brs acquisition
     21	   is buggy and especially the BXO-counter does not work
     22	   as specified. there is this workaround, but please
     23	   don't let me explain it. ;-) */
     24
     25	cpu = dma_alloc_coherent(&dev->pci->dev, 4096, &dma_addr, GFP_KERNEL);
     26	if (NULL == cpu)
     27		return -ENOMEM;
     28
     29	/* setup some basic programming, just for the workaround */
     30	saa7146_write(dev, BASE_EVEN3,	dma_addr);
     31	saa7146_write(dev, BASE_ODD3,	dma_addr+vbi_pixel_to_capture);
     32	saa7146_write(dev, PROT_ADDR3,	dma_addr+4096);
     33	saa7146_write(dev, PITCH3,	vbi_pixel_to_capture);
     34	saa7146_write(dev, BASE_PAGE3,	0x0);
     35	saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
     36	saa7146_write(dev, MC2, MASK_04|MASK_20);
     37
     38	/* load brs-control register */
     39	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
     40	/* BXO = 1h, BRS to outbound */
     41	WRITE_RPS1(0xc000008c);
     42	/* wait for vbi_a or vbi_b*/
     43	if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
     44		DEB_D("...using port b\n");
     45		WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
     46		WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
     47/*
     48		WRITE_RPS1(CMD_PAUSE | MASK_09);
     49*/
     50	} else {
     51		DEB_D("...using port a\n");
     52		WRITE_RPS1(CMD_PAUSE | MASK_10);
     53	}
     54	/* upload brs */
     55	WRITE_RPS1(CMD_UPLOAD | MASK_08);
     56	/* load brs-control register */
     57	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
     58	/* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
     59	WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
     60	/* wait for brs_done */
     61	WRITE_RPS1(CMD_PAUSE | MASK_08);
     62	/* upload brs */
     63	WRITE_RPS1(CMD_UPLOAD | MASK_08);
     64	/* load video-dma3 NumLines3 and NumBytes3 */
     65	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
     66	/* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
     67	WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
     68	/* load brs-control register */
     69	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
     70	/* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
     71	WRITE_RPS1((540 << 7) | (5 << 19));  // 5 == vbi_start
     72	/* wait for brs_done */
     73	WRITE_RPS1(CMD_PAUSE | MASK_08);
     74	/* upload brs and video-dma3*/
     75	WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
     76	/* load mc2 register: enable dma3 */
     77	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
     78	WRITE_RPS1(MASK_20 | MASK_04);
     79	/* generate interrupt */
     80	WRITE_RPS1(CMD_INTERRUPT);
     81	/* stop rps1 */
     82	WRITE_RPS1(CMD_STOP);
     83
     84	/* we have to do the workaround twice to be sure that
     85	   everything is ok */
     86	for(i = 0; i < 2; i++) {
     87
     88		/* indicate to the irq handler that we do the workaround */
     89		saa7146_write(dev, MC2, MASK_31|MASK_15);
     90
     91		saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
     92		saa7146_write(dev, MC2, MASK_04|MASK_20);
     93
     94		/* enable rps1 irqs */
     95		SAA7146_IER_ENABLE(dev,MASK_28);
     96
     97		/* prepare to wait to be woken up by the irq-handler */
     98		add_wait_queue(&vv->vbi_wq, &wait);
     99		set_current_state(TASK_INTERRUPTIBLE);
    100
    101		/* start rps1 to enable workaround */
    102		saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
    103		saa7146_write(dev, MC1, (MASK_13 | MASK_29));
    104
    105		schedule();
    106
    107		DEB_VBI("brs bug workaround %d/1\n", i);
    108
    109		remove_wait_queue(&vv->vbi_wq, &wait);
    110		__set_current_state(TASK_RUNNING);
    111
    112		/* disable rps1 irqs */
    113		SAA7146_IER_DISABLE(dev,MASK_28);
    114
    115		/* stop video-dma3 */
    116		saa7146_write(dev, MC1, MASK_20);
    117
    118		if(signal_pending(current)) {
    119
    120			DEB_VBI("aborted (rps:0x%08x)\n",
    121				saa7146_read(dev, RPS_ADDR1));
    122
    123			/* stop rps1 for sure */
    124			saa7146_write(dev, MC1, MASK_29);
    125
    126			dma_free_coherent(&dev->pci->dev, 4096, cpu, dma_addr);
    127			return -EINTR;
    128		}
    129	}
    130
    131	dma_free_coherent(&dev->pci->dev, 4096, cpu, dma_addr);
    132	return 0;
    133}
    134
    135static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
    136{
    137	struct saa7146_vv *vv = dev->vv_data;
    138
    139	struct saa7146_video_dma vdma3;
    140
    141	int count = 0;
    142	unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
    143	unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
    144
    145/*
    146	vdma3.base_even	= 0xc8000000+2560*70;
    147	vdma3.base_odd	= 0xc8000000;
    148	vdma3.prot_addr	= 0xc8000000+2560*164;
    149	vdma3.pitch	= 2560;
    150	vdma3.base_page	= 0;
    151	vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
    152*/
    153	vdma3.base_even	= buf->pt[2].offset;
    154	vdma3.base_odd	= buf->pt[2].offset + 16 * vbi_pixel_to_capture;
    155	vdma3.prot_addr	= buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
    156	vdma3.pitch	= vbi_pixel_to_capture;
    157	vdma3.base_page	= buf->pt[2].dma | ME1;
    158	vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
    159
    160	saa7146_write_out_dma(dev, 3, &vdma3);
    161
    162	/* write beginning of rps-program */
    163	count = 0;
    164
    165	/* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
    166
    167	/* we don't wait here for the first field anymore. this is different from the video
    168	   capture and might cause that the first buffer is only half filled (with only
    169	   one field). but since this is some sort of streaming data, this is not that negative.
    170	   but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
    171
    172/*
    173	WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
    174	WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
    175*/
    176	/* set bit 1 */
    177	WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
    178	WRITE_RPS1(MASK_28 | MASK_12);
    179
    180	/* turn on video-dma3 */
    181	WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
    182	WRITE_RPS1(MASK_04 | MASK_20);			/* => mask */
    183	WRITE_RPS1(MASK_04 | MASK_20);			/* => values */
    184
    185	/* wait for o_fid_a/b / e_fid_a/b toggle */
    186	WRITE_RPS1(CMD_PAUSE | o_wait);
    187	WRITE_RPS1(CMD_PAUSE | e_wait);
    188
    189	/* generate interrupt */
    190	WRITE_RPS1(CMD_INTERRUPT);
    191
    192	/* stop */
    193	WRITE_RPS1(CMD_STOP);
    194
    195	/* enable rps1 irqs */
    196	SAA7146_IER_ENABLE(dev, MASK_28);
    197
    198	/* write the address of the rps-program */
    199	saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
    200
    201	/* turn on rps */
    202	saa7146_write(dev, MC1, (MASK_13 | MASK_29));
    203}
    204
    205static int buffer_activate(struct saa7146_dev *dev,
    206			   struct saa7146_buf *buf,
    207			   struct saa7146_buf *next)
    208{
    209	struct saa7146_vv *vv = dev->vv_data;
    210	buf->vb.state = VIDEOBUF_ACTIVE;
    211
    212	DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
    213	saa7146_set_vbi_capture(dev,buf,next);
    214
    215	mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
    216	return 0;
    217}
    218
    219static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
    220{
    221	struct file *file = q->priv_data;
    222	struct saa7146_fh *fh = file->private_data;
    223	struct saa7146_dev *dev = fh->dev;
    224	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
    225
    226	int err = 0;
    227	int lines, llength, size;
    228
    229	lines   = 16 * 2 ; /* 2 fields */
    230	llength = vbi_pixel_to_capture;
    231	size = lines * llength;
    232
    233	DEB_VBI("vb:%p\n", vb);
    234
    235	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
    236		DEB_VBI("size mismatch\n");
    237		return -EINVAL;
    238	}
    239
    240	if (buf->vb.size != size)
    241		saa7146_dma_free(dev,q,buf);
    242
    243	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
    244		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
    245
    246		buf->vb.width  = llength;
    247		buf->vb.height = lines;
    248		buf->vb.size   = size;
    249		buf->vb.field  = field;	// FIXME: check this
    250
    251		saa7146_pgtable_free(dev->pci, &buf->pt[2]);
    252		saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
    253
    254		err = videobuf_iolock(q,&buf->vb, NULL);
    255		if (err)
    256			goto oops;
    257		err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
    258						 dma->sglist, dma->sglen);
    259		if (0 != err)
    260			return err;
    261	}
    262	buf->vb.state = VIDEOBUF_PREPARED;
    263	buf->activate = buffer_activate;
    264
    265	return 0;
    266
    267 oops:
    268	DEB_VBI("error out\n");
    269	saa7146_dma_free(dev,q,buf);
    270
    271	return err;
    272}
    273
    274static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
    275{
    276	int llength,lines;
    277
    278	lines   = 16 * 2 ; /* 2 fields */
    279	llength = vbi_pixel_to_capture;
    280
    281	*size = lines * llength;
    282	*count = 2;
    283
    284	DEB_VBI("count:%d, size:%d\n", *count, *size);
    285
    286	return 0;
    287}
    288
    289static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
    290{
    291	struct file *file = q->priv_data;
    292	struct saa7146_fh *fh = file->private_data;
    293	struct saa7146_dev *dev = fh->dev;
    294	struct saa7146_vv *vv = dev->vv_data;
    295	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
    296
    297	DEB_VBI("vb:%p\n", vb);
    298	saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
    299}
    300
    301static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
    302{
    303	struct file *file = q->priv_data;
    304	struct saa7146_fh *fh   = file->private_data;
    305	struct saa7146_dev *dev = fh->dev;
    306	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
    307
    308	DEB_VBI("vb:%p\n", vb);
    309	saa7146_dma_free(dev,q,buf);
    310}
    311
    312static const struct videobuf_queue_ops vbi_qops = {
    313	.buf_setup    = buffer_setup,
    314	.buf_prepare  = buffer_prepare,
    315	.buf_queue    = buffer_queue,
    316	.buf_release  = buffer_release,
    317};
    318
    319/* ------------------------------------------------------------------ */
    320
    321static void vbi_stop(struct saa7146_fh *fh, struct file *file)
    322{
    323	struct saa7146_dev *dev = fh->dev;
    324	struct saa7146_vv *vv = dev->vv_data;
    325	unsigned long flags;
    326	DEB_VBI("dev:%p, fh:%p\n", dev, fh);
    327
    328	spin_lock_irqsave(&dev->slock,flags);
    329
    330	/* disable rps1  */
    331	saa7146_write(dev, MC1, MASK_29);
    332
    333	/* disable rps1 irqs */
    334	SAA7146_IER_DISABLE(dev, MASK_28);
    335
    336	/* shut down dma 3 transfers */
    337	saa7146_write(dev, MC1, MASK_20);
    338
    339	if (vv->vbi_dmaq.curr)
    340		saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
    341
    342	videobuf_queue_cancel(&fh->vbi_q);
    343
    344	vv->vbi_streaming = NULL;
    345
    346	del_timer(&vv->vbi_dmaq.timeout);
    347	del_timer(&vv->vbi_read_timeout);
    348
    349	spin_unlock_irqrestore(&dev->slock, flags);
    350}
    351
    352static void vbi_read_timeout(struct timer_list *t)
    353{
    354	struct saa7146_vv *vv = from_timer(vv, t, vbi_read_timeout);
    355	struct file *file = vv->vbi_read_timeout_file;
    356	struct saa7146_fh *fh = file->private_data;
    357	struct saa7146_dev *dev = fh->dev;
    358
    359	DEB_VBI("dev:%p, fh:%p\n", dev, fh);
    360
    361	vbi_stop(fh, file);
    362}
    363
    364static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
    365{
    366	DEB_VBI("dev:%p\n", dev);
    367
    368	INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
    369
    370	timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0);
    371	vv->vbi_dmaq.dev              = dev;
    372
    373	init_waitqueue_head(&vv->vbi_wq);
    374}
    375
    376static int vbi_open(struct saa7146_dev *dev, struct file *file)
    377{
    378	struct saa7146_fh *fh = file->private_data;
    379	struct saa7146_vv *vv = fh->dev->vv_data;
    380
    381	u32 arbtr_ctrl	= saa7146_read(dev, PCI_BT_V1);
    382	int ret = 0;
    383
    384	DEB_VBI("dev:%p, fh:%p\n", dev, fh);
    385
    386	ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
    387	if (0 == ret) {
    388		DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
    389		return -EBUSY;
    390	}
    391
    392	/* adjust arbitrition control for video dma 3 */
    393	arbtr_ctrl &= ~0x1f0000;
    394	arbtr_ctrl |=  0x1d0000;
    395	saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
    396	saa7146_write(dev, MC2, (MASK_04|MASK_20));
    397
    398	videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
    399			    &dev->pci->dev, &dev->slock,
    400			    V4L2_BUF_TYPE_VBI_CAPTURE,
    401			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
    402			    sizeof(struct saa7146_buf),
    403			    file, &dev->v4l2_lock);
    404
    405	vv->vbi_read_timeout.function = vbi_read_timeout;
    406	vv->vbi_read_timeout_file = file;
    407
    408	/* initialize the brs */
    409	if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
    410		saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
    411	} else {
    412		saa7146_write(dev, BRS_CTRL, 0x00000001);
    413
    414		if (0 != (ret = vbi_workaround(dev))) {
    415			DEB_VBI("vbi workaround failed!\n");
    416			/* return ret;*/
    417		}
    418	}
    419
    420	/* upload brs register */
    421	saa7146_write(dev, MC2, (MASK_08|MASK_24));
    422	return 0;
    423}
    424
    425static void vbi_close(struct saa7146_dev *dev, struct file *file)
    426{
    427	struct saa7146_fh *fh = file->private_data;
    428	struct saa7146_vv *vv = dev->vv_data;
    429	DEB_VBI("dev:%p, fh:%p\n", dev, fh);
    430
    431	if( fh == vv->vbi_streaming ) {
    432		vbi_stop(fh, file);
    433	}
    434	saa7146_res_free(fh, RESOURCE_DMA3_BRS);
    435}
    436
    437static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
    438{
    439	struct saa7146_vv *vv = dev->vv_data;
    440	spin_lock(&dev->slock);
    441
    442	if (vv->vbi_dmaq.curr) {
    443		DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
    444		/* this must be += 2, one count for each field */
    445		vv->vbi_fieldcount+=2;
    446		vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
    447		saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
    448	} else {
    449		DEB_VBI("dev:%p\n", dev);
    450	}
    451	saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
    452
    453	spin_unlock(&dev->slock);
    454}
    455
    456static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
    457{
    458	struct saa7146_fh *fh = file->private_data;
    459	struct saa7146_dev *dev = fh->dev;
    460	struct saa7146_vv *vv = dev->vv_data;
    461	ssize_t ret = 0;
    462
    463	DEB_VBI("dev:%p, fh:%p\n", dev, fh);
    464
    465	if( NULL == vv->vbi_streaming ) {
    466		// fixme: check if dma3 is available
    467		// fixme: activate vbi engine here if necessary. (really?)
    468		vv->vbi_streaming = fh;
    469	}
    470
    471	if( fh != vv->vbi_streaming ) {
    472		DEB_VBI("open %p is already using vbi capture\n",
    473			vv->vbi_streaming);
    474		return -EBUSY;
    475	}
    476
    477	mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
    478	ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
    479				   file->f_flags & O_NONBLOCK);
    480/*
    481	printk("BASE_ODD3:      0x%08x\n", saa7146_read(dev, BASE_ODD3));
    482	printk("BASE_EVEN3:     0x%08x\n", saa7146_read(dev, BASE_EVEN3));
    483	printk("PROT_ADDR3:     0x%08x\n", saa7146_read(dev, PROT_ADDR3));
    484	printk("PITCH3:         0x%08x\n", saa7146_read(dev, PITCH3));
    485	printk("BASE_PAGE3:     0x%08x\n", saa7146_read(dev, BASE_PAGE3));
    486	printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
    487	printk("BRS_CTRL:       0x%08x\n", saa7146_read(dev, BRS_CTRL));
    488*/
    489	return ret;
    490}
    491
    492const struct saa7146_use_ops saa7146_vbi_uops = {
    493	.init		= vbi_init,
    494	.open		= vbi_open,
    495	.release	= vbi_close,
    496	.irq_done	= vbi_irq_done,
    497	.read		= vbi_read,
    498};