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

saa7134-go7007.c (14414B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2005-2006 Micronas USA Inc.
      4 */
      5
      6#include "saa7134.h"
      7#include "saa7134-reg.h"
      8
      9#include <linux/module.h>
     10#include <linux/kernel.h>
     11#include <linux/init.h>
     12#include <linux/spinlock.h>
     13#include <linux/wait.h>
     14#include <linux/list.h>
     15#include <linux/slab.h>
     16#include <linux/time.h>
     17#include <linux/mm.h>
     18#include <linux/usb.h>
     19#include <linux/i2c.h>
     20#include <asm/byteorder.h>
     21#include <media/v4l2-common.h>
     22#include <media/v4l2-device.h>
     23#include <media/v4l2-subdev.h>
     24
     25#include "go7007-priv.h"
     26
     27/*#define GO7007_HPI_DEBUG*/
     28
     29enum hpi_address {
     30	HPI_ADDR_VIDEO_BUFFER = 0xe4,
     31	HPI_ADDR_INIT_BUFFER = 0xea,
     32	HPI_ADDR_INTR_RET_VALUE = 0xee,
     33	HPI_ADDR_INTR_RET_DATA = 0xec,
     34	HPI_ADDR_INTR_STATUS = 0xf4,
     35	HPI_ADDR_INTR_WR_PARAM = 0xf6,
     36	HPI_ADDR_INTR_WR_INDEX = 0xf8,
     37};
     38
     39enum gpio_command {
     40	GPIO_COMMAND_RESET = 0x00, /* 000b */
     41	GPIO_COMMAND_REQ1  = 0x04, /* 001b */
     42	GPIO_COMMAND_WRITE = 0x20, /* 010b */
     43	GPIO_COMMAND_REQ2  = 0x24, /* 011b */
     44	GPIO_COMMAND_READ  = 0x80, /* 100b */
     45	GPIO_COMMAND_VIDEO = 0x84, /* 101b */
     46	GPIO_COMMAND_IDLE  = 0xA0, /* 110b */
     47	GPIO_COMMAND_ADDR  = 0xA4, /* 111b */
     48};
     49
     50struct saa7134_go7007 {
     51	struct v4l2_subdev sd;
     52	struct saa7134_dev *dev;
     53	u8 *top;
     54	u8 *bottom;
     55	dma_addr_t top_dma;
     56	dma_addr_t bottom_dma;
     57};
     58
     59static const struct go7007_board_info board_voyager = {
     60	.flags		 = 0,
     61	.sensor_flags	 = GO7007_SENSOR_656 |
     62				GO7007_SENSOR_VALID_ENABLE |
     63				GO7007_SENSOR_TV |
     64				GO7007_SENSOR_VBI,
     65	.audio_flags	= GO7007_AUDIO_I2S_MODE_1 |
     66				GO7007_AUDIO_WORD_16,
     67	.audio_rate	 = 48000,
     68	.audio_bclk_div	 = 8,
     69	.audio_main_div	 = 2,
     70	.hpi_buffer_cap  = 7,
     71	.num_inputs	 = 1,
     72	.inputs		 = {
     73		{
     74			.name		= "SAA7134",
     75		},
     76	},
     77};
     78
     79/********************* Driver for GPIO HPI interface *********************/
     80
     81static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
     82{
     83	saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
     84
     85	/* Write HPI address */
     86	saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
     87	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
     88	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
     89
     90	/* Write low byte */
     91	saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
     92	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
     93	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
     94
     95	/* Write high byte */
     96	saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
     97	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
     98	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
     99
    100	return 0;
    101}
    102
    103static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
    104{
    105	saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
    106
    107	/* Write HPI address */
    108	saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
    109	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
    110	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
    111
    112	saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
    113
    114	/* Read low byte */
    115	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
    116	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    117	saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    118	*data = saa_readb(SAA7134_GPIO_GPSTATUS0);
    119	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
    120
    121	/* Read high byte */
    122	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
    123	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    124	saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    125	*data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
    126	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
    127
    128	return 0;
    129}
    130
    131static int saa7134_go7007_interface_reset(struct go7007 *go)
    132{
    133	struct saa7134_go7007 *saa = go->hpi_context;
    134	struct saa7134_dev *dev = saa->dev;
    135	u16 intr_val, intr_data;
    136	int count = 20;
    137
    138	saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
    139	saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
    140	saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
    141
    142	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
    143	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
    144	msleep(1);
    145	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
    146	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
    147	msleep(10);
    148
    149	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    150	saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    151
    152	saa_readb(SAA7134_GPIO_GPSTATUS2);
    153	/*pr_debug("status is %s\n", saa_readb(SAA7134_GPIO_GPSTATUS2) & 0x40 ? "OK" : "not OK"); */
    154
    155	/* enter command mode...(?) */
    156	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
    157	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
    158
    159	do {
    160		saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    161		saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
    162		saa_readb(SAA7134_GPIO_GPSTATUS2);
    163		/*pr_info("gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
    164	} while (--count > 0);
    165
    166	/* Wait for an interrupt to indicate successful hardware reset */
    167	if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
    168			(intr_val & ~0x1) != 0x55aa) {
    169		pr_err("saa7134-go7007: unable to reset the GO7007\n");
    170		return -1;
    171	}
    172	return 0;
    173}
    174
    175static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
    176{
    177	struct saa7134_go7007 *saa = go->hpi_context;
    178	struct saa7134_dev *dev = saa->dev;
    179	int i;
    180	u16 status_reg;
    181
    182#ifdef GO7007_HPI_DEBUG
    183	pr_debug("saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
    184#endif
    185
    186	for (i = 0; i < 100; ++i) {
    187		gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
    188		if (!(status_reg & 0x0010))
    189			break;
    190		msleep(10);
    191	}
    192	if (i == 100) {
    193		pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
    194			status_reg);
    195		return -1;
    196	}
    197	gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
    198	gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
    199
    200	return 0;
    201}
    202
    203static int saa7134_go7007_read_interrupt(struct go7007 *go)
    204{
    205	struct saa7134_go7007 *saa = go->hpi_context;
    206	struct saa7134_dev *dev = saa->dev;
    207
    208	/* XXX we need to wait if there is no interrupt available */
    209	go->interrupt_available = 1;
    210	gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
    211	gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
    212#ifdef GO7007_HPI_DEBUG
    213	pr_debug("saa7134-go7007: ReadInterrupt: %04x %04x\n",
    214			go->interrupt_value, go->interrupt_data);
    215#endif
    216	return 0;
    217}
    218
    219static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
    220						unsigned long status)
    221{
    222	struct go7007 *go = video_get_drvdata(dev->empress_dev);
    223	struct saa7134_go7007 *saa = go->hpi_context;
    224
    225	if (!vb2_is_streaming(&go->vidq))
    226		return;
    227	if (0 != (status & 0x000f0000))
    228		pr_debug("saa7134-go7007: irq: lost %ld\n",
    229				(status >> 16) & 0x0f);
    230	if (status & 0x100000) {
    231		dma_sync_single_for_cpu(&dev->pci->dev,
    232					saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
    233		go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
    234		saa_writel(SAA7134_RS_BA2(5), saa->bottom_dma);
    235	} else {
    236		dma_sync_single_for_cpu(&dev->pci->dev,
    237					saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
    238		go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
    239		saa_writel(SAA7134_RS_BA1(5), saa->top_dma);
    240	}
    241}
    242
    243static int saa7134_go7007_stream_start(struct go7007 *go)
    244{
    245	struct saa7134_go7007 *saa = go->hpi_context;
    246	struct saa7134_dev *dev = saa->dev;
    247
    248	saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
    249			0, PAGE_SIZE, DMA_FROM_DEVICE);
    250	if (dma_mapping_error(&dev->pci->dev, saa->top_dma))
    251		return -ENOMEM;
    252	saa->bottom_dma = dma_map_page(&dev->pci->dev,
    253			virt_to_page(saa->bottom),
    254			0, PAGE_SIZE, DMA_FROM_DEVICE);
    255	if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) {
    256		dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
    257				DMA_FROM_DEVICE);
    258		return -ENOMEM;
    259	}
    260
    261	saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
    262	saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
    263
    264	/* Set HPI interface for video */
    265	saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
    266	saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
    267	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
    268	saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
    269
    270	/* Enable TS interface */
    271	saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
    272
    273	/* Reset TS interface */
    274	saa_setb(SAA7134_TS_SERIAL1, 0x01);
    275	saa_clearb(SAA7134_TS_SERIAL1, 0x01);
    276
    277	/* Set up transfer block size */
    278	saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
    279	saa_writeb(SAA7134_TS_DMA0, ((PAGE_SIZE >> 7) - 1) & 0xff);
    280	saa_writeb(SAA7134_TS_DMA1, (PAGE_SIZE >> 15) & 0xff);
    281	saa_writeb(SAA7134_TS_DMA2, (PAGE_SIZE >> 31) & 0x3f);
    282
    283	/* Enable video streaming mode */
    284	saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
    285
    286	saa_writel(SAA7134_RS_BA1(5), saa->top_dma);
    287	saa_writel(SAA7134_RS_BA2(5), saa->bottom_dma);
    288	saa_writel(SAA7134_RS_PITCH(5), 128);
    289	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
    290
    291	/* Enable TS FIFO */
    292	saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
    293
    294	/* Enable DMA IRQ */
    295	saa_setl(SAA7134_IRQ1,
    296			SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
    297
    298	return 0;
    299}
    300
    301static int saa7134_go7007_stream_stop(struct go7007 *go)
    302{
    303	struct saa7134_go7007 *saa = go->hpi_context;
    304	struct saa7134_dev *dev;
    305
    306	if (!saa)
    307		return -EINVAL;
    308	dev = saa->dev;
    309	if (!dev)
    310		return -EINVAL;
    311
    312	/* Shut down TS FIFO */
    313	saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
    314
    315	/* Disable DMA IRQ */
    316	saa_clearl(SAA7134_IRQ1,
    317			SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
    318
    319	/* Disable TS interface */
    320	saa_clearb(SAA7134_TS_PARALLEL, 0x80);
    321
    322	dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
    323			DMA_FROM_DEVICE);
    324	dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
    325			DMA_FROM_DEVICE);
    326
    327	return 0;
    328}
    329
    330static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
    331{
    332	struct saa7134_go7007 *saa = go->hpi_context;
    333	struct saa7134_dev *dev = saa->dev;
    334	u16 status_reg;
    335	int i;
    336
    337#ifdef GO7007_HPI_DEBUG
    338	pr_debug("saa7134-go7007: DownloadBuffer sending %d bytes\n", len);
    339#endif
    340
    341	while (len > 0) {
    342		i = len > 64 ? 64 : len;
    343		saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
    344		saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
    345		saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
    346		saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
    347		while (i-- > 0) {
    348			saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
    349			saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
    350			saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
    351			++data;
    352			--len;
    353		}
    354		for (i = 0; i < 100; ++i) {
    355			gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
    356			if (!(status_reg & 0x0002))
    357				break;
    358		}
    359		if (i == 100) {
    360			pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
    361			       status_reg);
    362			return -1;
    363		}
    364	}
    365	return 0;
    366}
    367
    368static const struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
    369	.interface_reset	= saa7134_go7007_interface_reset,
    370	.write_interrupt	= saa7134_go7007_write_interrupt,
    371	.read_interrupt		= saa7134_go7007_read_interrupt,
    372	.stream_start		= saa7134_go7007_stream_start,
    373	.stream_stop		= saa7134_go7007_stream_stop,
    374	.send_firmware		= saa7134_go7007_send_firmware,
    375};
    376MODULE_FIRMWARE("go7007/go7007tv.bin");
    377
    378/* --------------------------------------------------------------------------*/
    379
    380static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
    381{
    382#if 0
    383	struct saa7134_go7007 *saa = container_of(sd, struct saa7134_go7007, sd);
    384	struct saa7134_dev *dev = saa->dev;
    385
    386	return saa7134_s_std_internal(dev, NULL, norm);
    387#else
    388	return 0;
    389#endif
    390}
    391
    392static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = {
    393	.s_std = saa7134_go7007_s_std,
    394};
    395
    396static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
    397	.video = &saa7134_go7007_video_ops,
    398};
    399
    400/* --------------------------------------------------------------------------*/
    401
    402
    403/********************* Add/remove functions *********************/
    404
    405static int saa7134_go7007_init(struct saa7134_dev *dev)
    406{
    407	struct go7007 *go;
    408	struct saa7134_go7007 *saa;
    409	struct v4l2_subdev *sd;
    410
    411	pr_debug("saa7134-go7007: probing new SAA713X board\n");
    412
    413	go = go7007_alloc(&board_voyager, &dev->pci->dev);
    414	if (go == NULL)
    415		return -ENOMEM;
    416
    417	saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
    418	if (saa == NULL) {
    419		kfree(go);
    420		return -ENOMEM;
    421	}
    422
    423	go->board_id = GO7007_BOARDID_PCI_VOYAGER;
    424	snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
    425	strscpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
    426	go->hpi_ops = &saa7134_go7007_hpi_ops;
    427	go->hpi_context = saa;
    428	saa->dev = dev;
    429
    430	/* Init the subdevice interface */
    431	sd = &saa->sd;
    432	v4l2_subdev_init(sd, &saa7134_go7007_sd_ops);
    433	v4l2_set_subdevdata(sd, saa);
    434	strscpy(sd->name, "saa7134-go7007", sizeof(sd->name));
    435
    436	/* Allocate a couple pages for receiving the compressed stream */
    437	saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
    438	if (!saa->top)
    439		goto allocfail;
    440	saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
    441	if (!saa->bottom)
    442		goto allocfail;
    443
    444	/* Boot the GO7007 */
    445	if (go7007_boot_encoder(go, go->board_info->flags &
    446					GO7007_BOARD_USE_ONBOARD_I2C) < 0)
    447		goto allocfail;
    448
    449	/* Do any final GO7007 initialization, then register the
    450	 * V4L2 and ALSA interfaces */
    451	if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
    452		goto allocfail;
    453
    454	/* Register the subdevice interface with the go7007 device */
    455	if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
    456		pr_info("saa7134-go7007: register subdev failed\n");
    457
    458	dev->empress_dev = &go->vdev;
    459
    460	go->status = STATUS_ONLINE;
    461	return 0;
    462
    463allocfail:
    464	if (saa->top)
    465		free_page((unsigned long)saa->top);
    466	if (saa->bottom)
    467		free_page((unsigned long)saa->bottom);
    468	kfree(saa);
    469	kfree(go);
    470	return -ENOMEM;
    471}
    472
    473static int saa7134_go7007_fini(struct saa7134_dev *dev)
    474{
    475	struct go7007 *go;
    476	struct saa7134_go7007 *saa;
    477
    478	if (NULL == dev->empress_dev)
    479		return 0;
    480
    481	go = video_get_drvdata(dev->empress_dev);
    482	if (go->audio_enabled)
    483		go7007_snd_remove(go);
    484
    485	saa = go->hpi_context;
    486	go->status = STATUS_SHUTDOWN;
    487	free_page((unsigned long)saa->top);
    488	free_page((unsigned long)saa->bottom);
    489	v4l2_device_unregister_subdev(&saa->sd);
    490	kfree(saa);
    491	vb2_video_unregister_device(&go->vdev);
    492
    493	v4l2_device_put(&go->v4l2_dev);
    494	dev->empress_dev = NULL;
    495
    496	return 0;
    497}
    498
    499static struct saa7134_mpeg_ops saa7134_go7007_ops = {
    500	.type          = SAA7134_MPEG_GO7007,
    501	.init          = saa7134_go7007_init,
    502	.fini          = saa7134_go7007_fini,
    503	.irq_ts_done   = saa7134_go7007_irq_ts_done,
    504};
    505
    506static int __init saa7134_go7007_mod_init(void)
    507{
    508	return saa7134_ts_register(&saa7134_go7007_ops);
    509}
    510
    511static void __exit saa7134_go7007_mod_cleanup(void)
    512{
    513	saa7134_ts_unregister(&saa7134_go7007_ops);
    514}
    515
    516module_init(saa7134_go7007_mod_init);
    517module_exit(saa7134_go7007_mod_cleanup);
    518
    519MODULE_LICENSE("GPL v2");