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

cx88-core.c (30130B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * device driver for Conexant 2388x based TV cards
      4 * driver core
      5 *
      6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
      7 *
      8 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org>
      9 *     - Multituner support
     10 *     - video_ioctl2 conversion
     11 *     - PAL/M fixes
     12 */
     13
     14#include "cx88.h"
     15
     16#include <linux/init.h>
     17#include <linux/list.h>
     18#include <linux/module.h>
     19#include <linux/kernel.h>
     20#include <linux/slab.h>
     21#include <linux/kmod.h>
     22#include <linux/sound.h>
     23#include <linux/interrupt.h>
     24#include <linux/pci.h>
     25#include <linux/delay.h>
     26#include <linux/videodev2.h>
     27#include <linux/mutex.h>
     28
     29#include <media/v4l2-common.h>
     30#include <media/v4l2-ioctl.h>
     31
     32MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
     33MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
     34MODULE_LICENSE("GPL v2");
     35
     36/* ------------------------------------------------------------------ */
     37
     38unsigned int cx88_core_debug;
     39module_param_named(core_debug, cx88_core_debug, int, 0644);
     40MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
     41
     42static unsigned int nicam;
     43module_param(nicam, int, 0644);
     44MODULE_PARM_DESC(nicam, "tv audio is nicam");
     45
     46static unsigned int nocomb;
     47module_param(nocomb, int, 0644);
     48MODULE_PARM_DESC(nocomb, "disable comb filter");
     49
     50#define dprintk0(fmt, arg...)				\
     51	printk(KERN_DEBUG pr_fmt("%s: core:" fmt),	\
     52		__func__, ##arg)			\
     53
     54#define dprintk(level, fmt, arg...)	do {			\
     55	if (cx88_core_debug >= level)				\
     56		printk(KERN_DEBUG pr_fmt("%s: core:" fmt),	\
     57		       __func__, ##arg);			\
     58} while (0)
     59
     60static unsigned int cx88_devcount;
     61static LIST_HEAD(cx88_devlist);
     62static DEFINE_MUTEX(devlist);
     63
     64#define NO_SYNC_LINE (-1U)
     65
     66/*
     67 * @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
     68 * generated _after_ lpi lines are transferred.
     69 */
     70static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
     71			       unsigned int offset, u32 sync_line,
     72			       unsigned int bpl, unsigned int padding,
     73			       unsigned int lines, unsigned int lpi, bool jump)
     74{
     75	struct scatterlist *sg;
     76	unsigned int line, todo, sol;
     77
     78	if (jump) {
     79		(*rp++) = cpu_to_le32(RISC_JUMP);
     80		(*rp++) = 0;
     81	}
     82
     83	/* sync instruction */
     84	if (sync_line != NO_SYNC_LINE)
     85		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
     86
     87	/* scan lines */
     88	sg = sglist;
     89	for (line = 0; line < lines; line++) {
     90		while (offset && offset >= sg_dma_len(sg)) {
     91			offset -= sg_dma_len(sg);
     92			sg = sg_next(sg);
     93		}
     94		if (lpi && line > 0 && !(line % lpi))
     95			sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
     96		else
     97			sol = RISC_SOL;
     98		if (bpl <= sg_dma_len(sg) - offset) {
     99			/* fits into current chunk */
    100			*(rp++) = cpu_to_le32(RISC_WRITE | sol |
    101					      RISC_EOL | bpl);
    102			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
    103			offset += bpl;
    104		} else {
    105			/* scanline needs to be split */
    106			todo = bpl;
    107			*(rp++) = cpu_to_le32(RISC_WRITE | sol |
    108					      (sg_dma_len(sg) - offset));
    109			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
    110			todo -= (sg_dma_len(sg) - offset);
    111			offset = 0;
    112			sg = sg_next(sg);
    113			while (todo > sg_dma_len(sg)) {
    114				*(rp++) = cpu_to_le32(RISC_WRITE |
    115						      sg_dma_len(sg));
    116				*(rp++) = cpu_to_le32(sg_dma_address(sg));
    117				todo -= sg_dma_len(sg);
    118				sg = sg_next(sg);
    119			}
    120			*(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
    121			*(rp++) = cpu_to_le32(sg_dma_address(sg));
    122			offset += todo;
    123		}
    124		offset += padding;
    125	}
    126
    127	return rp;
    128}
    129
    130int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc,
    131		     struct scatterlist *sglist,
    132		     unsigned int top_offset, unsigned int bottom_offset,
    133		     unsigned int bpl, unsigned int padding, unsigned int lines)
    134{
    135	u32 instructions, fields;
    136	__le32 *rp;
    137
    138	fields = 0;
    139	if (top_offset != UNSET)
    140		fields++;
    141	if (bottom_offset != UNSET)
    142		fields++;
    143
    144	/*
    145	 * estimate risc mem: worst case is one write per page border +
    146	 * one write per scan line + syncs + jump (all 2 dwords).  Padding
    147	 * can cause next bpl to start close to a page border.  First DMA
    148	 * region may be smaller than PAGE_SIZE
    149	 */
    150	instructions  = fields * (1 + ((bpl + padding) * lines) /
    151				  PAGE_SIZE + lines);
    152	instructions += 4;
    153	risc->size = instructions * 8;
    154	risc->dma = 0;
    155	risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma,
    156				       GFP_KERNEL);
    157	if (!risc->cpu)
    158		return -ENOMEM;
    159
    160	/* write risc instructions */
    161	rp = risc->cpu;
    162	if (top_offset != UNSET)
    163		rp = cx88_risc_field(rp, sglist, top_offset, 0,
    164				     bpl, padding, lines, 0, true);
    165	if (bottom_offset != UNSET)
    166		rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
    167				     bpl, padding, lines, 0,
    168				     top_offset == UNSET);
    169
    170	/* save pointer to jmp instruction address */
    171	risc->jmp = rp;
    172	WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
    173	return 0;
    174}
    175EXPORT_SYMBOL(cx88_risc_buffer);
    176
    177int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc,
    178			 struct scatterlist *sglist, unsigned int bpl,
    179			 unsigned int lines, unsigned int lpi)
    180{
    181	u32 instructions;
    182	__le32 *rp;
    183
    184	/*
    185	 * estimate risc mem: worst case is one write per page border +
    186	 * one write per scan line + syncs + jump (all 2 dwords).  Here
    187	 * there is no padding and no sync.  First DMA region may be smaller
    188	 * than PAGE_SIZE
    189	 */
    190	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
    191	instructions += 3;
    192	risc->size = instructions * 8;
    193	risc->dma = 0;
    194	risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma,
    195				       GFP_KERNEL);
    196	if (!risc->cpu)
    197		return -ENOMEM;
    198
    199	/* write risc instructions */
    200	rp = risc->cpu;
    201	rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
    202			     lines, lpi, !lpi);
    203
    204	/* save pointer to jmp instruction address */
    205	risc->jmp = rp;
    206	WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
    207	return 0;
    208}
    209EXPORT_SYMBOL(cx88_risc_databuffer);
    210
    211/*
    212 * our SRAM memory layout
    213 */
    214
    215/*
    216 * we are going to put all thr risc programs into host memory, so we
    217 * can use the whole SDRAM for the DMA fifos.  To simplify things, we
    218 * use a static memory layout.  That surely will waste memory in case
    219 * we don't use all DMA channels at the same time (which will be the
    220 * case most of the time).  But that still gives us enough FIFO space
    221 * to be able to deal with insane long pci latencies ...
    222 *
    223 * FIFO space allocations:
    224 *    channel  21    (y video)  - 10.0k
    225 *    channel  22    (u video)  -  2.0k
    226 *    channel  23    (v video)  -  2.0k
    227 *    channel  24    (vbi)      -  4.0k
    228 *    channels 25+26 (audio)    -  4.0k
    229 *    channel  28    (mpeg)     -  4.0k
    230 *    channel  27    (audio rds)-  3.0k
    231 *    TOTAL                     = 29.0k
    232 *
    233 * Every channel has 160 bytes control data (64 bytes instruction
    234 * queue and 6 CDT entries), which is close to 2k total.
    235 *
    236 * Address layout:
    237 *    0x0000 - 0x03ff    CMDs / reserved
    238 *    0x0400 - 0x0bff    instruction queues + CDs
    239 *    0x0c00 -           FIFOs
    240 */
    241
    242const struct sram_channel cx88_sram_channels[] = {
    243	[SRAM_CH21] = {
    244		.name       = "video y / packed",
    245		.cmds_start = 0x180040,
    246		.ctrl_start = 0x180400,
    247		.cdt        = 0x180400 + 64,
    248		.fifo_start = 0x180c00,
    249		.fifo_size  = 0x002800,
    250		.ptr1_reg   = MO_DMA21_PTR1,
    251		.ptr2_reg   = MO_DMA21_PTR2,
    252		.cnt1_reg   = MO_DMA21_CNT1,
    253		.cnt2_reg   = MO_DMA21_CNT2,
    254	},
    255	[SRAM_CH22] = {
    256		.name       = "video u",
    257		.cmds_start = 0x180080,
    258		.ctrl_start = 0x1804a0,
    259		.cdt        = 0x1804a0 + 64,
    260		.fifo_start = 0x183400,
    261		.fifo_size  = 0x000800,
    262		.ptr1_reg   = MO_DMA22_PTR1,
    263		.ptr2_reg   = MO_DMA22_PTR2,
    264		.cnt1_reg   = MO_DMA22_CNT1,
    265		.cnt2_reg   = MO_DMA22_CNT2,
    266	},
    267	[SRAM_CH23] = {
    268		.name       = "video v",
    269		.cmds_start = 0x1800c0,
    270		.ctrl_start = 0x180540,
    271		.cdt        = 0x180540 + 64,
    272		.fifo_start = 0x183c00,
    273		.fifo_size  = 0x000800,
    274		.ptr1_reg   = MO_DMA23_PTR1,
    275		.ptr2_reg   = MO_DMA23_PTR2,
    276		.cnt1_reg   = MO_DMA23_CNT1,
    277		.cnt2_reg   = MO_DMA23_CNT2,
    278	},
    279	[SRAM_CH24] = {
    280		.name       = "vbi",
    281		.cmds_start = 0x180100,
    282		.ctrl_start = 0x1805e0,
    283		.cdt        = 0x1805e0 + 64,
    284		.fifo_start = 0x184400,
    285		.fifo_size  = 0x001000,
    286		.ptr1_reg   = MO_DMA24_PTR1,
    287		.ptr2_reg   = MO_DMA24_PTR2,
    288		.cnt1_reg   = MO_DMA24_CNT1,
    289		.cnt2_reg   = MO_DMA24_CNT2,
    290	},
    291	[SRAM_CH25] = {
    292		.name       = "audio from",
    293		.cmds_start = 0x180140,
    294		.ctrl_start = 0x180680,
    295		.cdt        = 0x180680 + 64,
    296		.fifo_start = 0x185400,
    297		.fifo_size  = 0x001000,
    298		.ptr1_reg   = MO_DMA25_PTR1,
    299		.ptr2_reg   = MO_DMA25_PTR2,
    300		.cnt1_reg   = MO_DMA25_CNT1,
    301		.cnt2_reg   = MO_DMA25_CNT2,
    302	},
    303	[SRAM_CH26] = {
    304		.name       = "audio to",
    305		.cmds_start = 0x180180,
    306		.ctrl_start = 0x180720,
    307		.cdt        = 0x180680 + 64,  /* same as audio IN */
    308		.fifo_start = 0x185400,       /* same as audio IN */
    309		.fifo_size  = 0x001000,       /* same as audio IN */
    310		.ptr1_reg   = MO_DMA26_PTR1,
    311		.ptr2_reg   = MO_DMA26_PTR2,
    312		.cnt1_reg   = MO_DMA26_CNT1,
    313		.cnt2_reg   = MO_DMA26_CNT2,
    314	},
    315	[SRAM_CH28] = {
    316		.name       = "mpeg",
    317		.cmds_start = 0x180200,
    318		.ctrl_start = 0x1807C0,
    319		.cdt        = 0x1807C0 + 64,
    320		.fifo_start = 0x186400,
    321		.fifo_size  = 0x001000,
    322		.ptr1_reg   = MO_DMA28_PTR1,
    323		.ptr2_reg   = MO_DMA28_PTR2,
    324		.cnt1_reg   = MO_DMA28_CNT1,
    325		.cnt2_reg   = MO_DMA28_CNT2,
    326	},
    327	[SRAM_CH27] = {
    328		.name       = "audio rds",
    329		.cmds_start = 0x1801C0,
    330		.ctrl_start = 0x180860,
    331		.cdt        = 0x180860 + 64,
    332		.fifo_start = 0x187400,
    333		.fifo_size  = 0x000C00,
    334		.ptr1_reg   = MO_DMA27_PTR1,
    335		.ptr2_reg   = MO_DMA27_PTR2,
    336		.cnt1_reg   = MO_DMA27_CNT1,
    337		.cnt2_reg   = MO_DMA27_CNT2,
    338	},
    339};
    340EXPORT_SYMBOL(cx88_sram_channels);
    341
    342int cx88_sram_channel_setup(struct cx88_core *core,
    343			    const struct sram_channel *ch,
    344			    unsigned int bpl, u32 risc)
    345{
    346	unsigned int i, lines;
    347	u32 cdt;
    348
    349	bpl   = (bpl + 7) & ~7; /* alignment */
    350	cdt   = ch->cdt;
    351	lines = ch->fifo_size / bpl;
    352	if (lines > 6)
    353		lines = 6;
    354	WARN_ON(lines < 2);
    355
    356	/* write CDT */
    357	for (i = 0; i < lines; i++)
    358		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
    359
    360	/* write CMDS */
    361	cx_write(ch->cmds_start +  0, risc);
    362	cx_write(ch->cmds_start +  4, cdt);
    363	cx_write(ch->cmds_start +  8, (lines * 16) >> 3);
    364	cx_write(ch->cmds_start + 12, ch->ctrl_start);
    365	cx_write(ch->cmds_start + 16, 64 >> 2);
    366	for (i = 20; i < 64; i += 4)
    367		cx_write(ch->cmds_start + i, 0);
    368
    369	/* fill registers */
    370	cx_write(ch->ptr1_reg, ch->fifo_start);
    371	cx_write(ch->ptr2_reg, cdt);
    372	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
    373	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
    374
    375	dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
    376	return 0;
    377}
    378EXPORT_SYMBOL(cx88_sram_channel_setup);
    379
    380/* ------------------------------------------------------------------ */
    381/* debug helper code                                                  */
    382
    383static int cx88_risc_decode(u32 risc)
    384{
    385	static const char * const instr[16] = {
    386		[RISC_SYNC    >> 28] = "sync",
    387		[RISC_WRITE   >> 28] = "write",
    388		[RISC_WRITEC  >> 28] = "writec",
    389		[RISC_READ    >> 28] = "read",
    390		[RISC_READC   >> 28] = "readc",
    391		[RISC_JUMP    >> 28] = "jump",
    392		[RISC_SKIP    >> 28] = "skip",
    393		[RISC_WRITERM >> 28] = "writerm",
    394		[RISC_WRITECM >> 28] = "writecm",
    395		[RISC_WRITECR >> 28] = "writecr",
    396	};
    397	static int const incr[16] = {
    398		[RISC_WRITE   >> 28] = 2,
    399		[RISC_JUMP    >> 28] = 2,
    400		[RISC_WRITERM >> 28] = 3,
    401		[RISC_WRITECM >> 28] = 3,
    402		[RISC_WRITECR >> 28] = 4,
    403	};
    404	static const char * const bits[] = {
    405		"12",   "13",   "14",   "resync",
    406		"cnt0", "cnt1", "18",   "19",
    407		"20",   "21",   "22",   "23",
    408		"irq1", "irq2", "eol",  "sol",
    409	};
    410	int i;
    411
    412	dprintk0("0x%08x [ %s", risc,
    413		 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
    414	for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
    415		if (risc & (1 << (i + 12)))
    416			pr_cont(" %s", bits[i]);
    417	pr_cont(" count=%d ]\n", risc & 0xfff);
    418	return incr[risc >> 28] ? incr[risc >> 28] : 1;
    419}
    420
    421void cx88_sram_channel_dump(struct cx88_core *core,
    422			    const struct sram_channel *ch)
    423{
    424	static const char * const name[] = {
    425		"initial risc",
    426		"cdt base",
    427		"cdt size",
    428		"iq base",
    429		"iq size",
    430		"risc pc",
    431		"iq wr ptr",
    432		"iq rd ptr",
    433		"cdt current",
    434		"pci target",
    435		"line / byte",
    436	};
    437	u32 risc;
    438	unsigned int i, j, n;
    439
    440	dprintk0("%s - dma channel status dump\n", ch->name);
    441	for (i = 0; i < ARRAY_SIZE(name); i++)
    442		dprintk0("   cmds: %-12s: 0x%08x\n",
    443			 name[i], cx_read(ch->cmds_start + 4 * i));
    444	for (n = 1, i = 0; i < 4; i++) {
    445		risc = cx_read(ch->cmds_start + 4 * (i + 11));
    446		pr_cont("  risc%d: ", i);
    447		if (--n)
    448			pr_cont("0x%08x [ arg #%d ]\n", risc, n);
    449		else
    450			n = cx88_risc_decode(risc);
    451	}
    452	for (i = 0; i < 16; i += n) {
    453		risc = cx_read(ch->ctrl_start + 4 * i);
    454		dprintk0("  iq %x: ", i);
    455		n = cx88_risc_decode(risc);
    456		for (j = 1; j < n; j++) {
    457			risc = cx_read(ch->ctrl_start + 4 * (i + j));
    458			pr_cont("  iq %x: 0x%08x [ arg #%d ]\n",
    459				i + j, risc, j);
    460		}
    461	}
    462
    463	dprintk0("fifo: 0x%08x -> 0x%x\n",
    464		 ch->fifo_start, ch->fifo_start + ch->fifo_size);
    465	dprintk0("ctrl: 0x%08x -> 0x%x\n",
    466		 ch->ctrl_start, ch->ctrl_start + 6 * 16);
    467	dprintk0("  ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
    468	dprintk0("  ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
    469	dprintk0("  cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
    470	dprintk0("  cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
    471}
    472EXPORT_SYMBOL(cx88_sram_channel_dump);
    473
    474static const char *cx88_pci_irqs[32] = {
    475	"vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
    476	"src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
    477	"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
    478	"i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
    479};
    480
    481void cx88_print_irqbits(const char *tag, const char *strings[],
    482			int len, u32 bits, u32 mask)
    483{
    484	unsigned int i;
    485
    486	dprintk0("%s [0x%x]", tag, bits);
    487	for (i = 0; i < len; i++) {
    488		if (!(bits & (1 << i)))
    489			continue;
    490		if (strings[i])
    491			pr_cont(" %s", strings[i]);
    492		else
    493			pr_cont(" %d", i);
    494		if (!(mask & (1 << i)))
    495			continue;
    496		pr_cont("*");
    497	}
    498	pr_cont("\n");
    499}
    500EXPORT_SYMBOL(cx88_print_irqbits);
    501
    502/* ------------------------------------------------------------------ */
    503
    504int cx88_core_irq(struct cx88_core *core, u32 status)
    505{
    506	int handled = 0;
    507
    508	if (status & PCI_INT_IR_SMPINT) {
    509		cx88_ir_irq(core);
    510		handled++;
    511	}
    512	if (!handled)
    513		cx88_print_irqbits("irq pci",
    514				   cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
    515				   status, core->pci_irqmask);
    516	return handled;
    517}
    518EXPORT_SYMBOL(cx88_core_irq);
    519
    520void cx88_wakeup(struct cx88_core *core,
    521		 struct cx88_dmaqueue *q, u32 count)
    522{
    523	struct cx88_buffer *buf;
    524
    525	buf = list_entry(q->active.next,
    526			 struct cx88_buffer, list);
    527	buf->vb.vb2_buf.timestamp = ktime_get_ns();
    528	buf->vb.field = core->field;
    529	buf->vb.sequence = q->count++;
    530	list_del(&buf->list);
    531	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
    532}
    533EXPORT_SYMBOL(cx88_wakeup);
    534
    535void cx88_shutdown(struct cx88_core *core)
    536{
    537	/* disable RISC controller + IRQs */
    538	cx_write(MO_DEV_CNTRL2, 0);
    539
    540	/* stop dma transfers */
    541	cx_write(MO_VID_DMACNTRL, 0x0);
    542	cx_write(MO_AUD_DMACNTRL, 0x0);
    543	cx_write(MO_TS_DMACNTRL, 0x0);
    544	cx_write(MO_VIP_DMACNTRL, 0x0);
    545	cx_write(MO_GPHST_DMACNTRL, 0x0);
    546
    547	/* stop interrupts */
    548	cx_write(MO_PCI_INTMSK, 0x0);
    549	cx_write(MO_VID_INTMSK, 0x0);
    550	cx_write(MO_AUD_INTMSK, 0x0);
    551	cx_write(MO_TS_INTMSK, 0x0);
    552	cx_write(MO_VIP_INTMSK, 0x0);
    553	cx_write(MO_GPHST_INTMSK, 0x0);
    554
    555	/* stop capturing */
    556	cx_write(VID_CAPTURE_CONTROL, 0);
    557}
    558EXPORT_SYMBOL(cx88_shutdown);
    559
    560int cx88_reset(struct cx88_core *core)
    561{
    562	dprintk(1, "");
    563	cx88_shutdown(core);
    564
    565	/* clear irq status */
    566	cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
    567	cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
    568	cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int
    569
    570	/* wait a bit */
    571	msleep(100);
    572
    573	/* init sram */
    574	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
    575				720 * 4, 0);
    576	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
    577	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
    578	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
    579	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
    580	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
    581	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
    582				188 * 4, 0);
    583	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
    584
    585	/* misc init ... */
    586	cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
    587				   (1 << 12) |   // agc gain
    588				   (1 << 11) |   // adaptibe agc
    589				   (0 << 10) |   // chroma agc
    590				   (0 <<  9) |   // ckillen
    591				   (7)));
    592
    593	/* setup image format */
    594	cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
    595
    596	/* setup FIFO Thresholds */
    597	cx_write(MO_PDMA_STHRSH,   0x0807);
    598	cx_write(MO_PDMA_DTHRSH,   0x0807);
    599
    600	/* fixes flashing of image */
    601	cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
    602	cx_write(MO_AGC_BACK_VBI,  0x00E00555);
    603
    604	cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int
    605	cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int
    606	cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int
    607
    608	/* Reset on-board parts */
    609	cx_write(MO_SRST_IO, 0);
    610	usleep_range(10000, 20000);
    611	cx_write(MO_SRST_IO, 1);
    612
    613	return 0;
    614}
    615EXPORT_SYMBOL(cx88_reset);
    616
    617/* ------------------------------------------------------------------ */
    618
    619static inline unsigned int norm_swidth(v4l2_std_id norm)
    620{
    621	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
    622}
    623
    624static inline unsigned int norm_hdelay(v4l2_std_id norm)
    625{
    626	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
    627}
    628
    629static inline unsigned int norm_vdelay(v4l2_std_id norm)
    630{
    631	return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
    632}
    633
    634static inline unsigned int norm_fsc8(v4l2_std_id norm)
    635{
    636	if (norm & V4L2_STD_PAL_M)
    637		return 28604892;      // 3.575611 MHz
    638
    639	if (norm & (V4L2_STD_PAL_Nc))
    640		return 28656448;      // 3.582056 MHz
    641
    642	if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
    643		return 28636360;      // 3.57954545 MHz +/- 10 Hz
    644
    645	/*
    646	 * SECAM have also different sub carrier for chroma,
    647	 * but step_db and step_dr, at cx88_set_tvnorm already handles that.
    648	 *
    649	 * The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
    650	 */
    651
    652	return 35468950;      // 4.43361875 MHz +/- 5 Hz
    653}
    654
    655static inline unsigned int norm_htotal(v4l2_std_id norm)
    656{
    657	unsigned int fsc4 = norm_fsc8(norm) / 2;
    658
    659	/* returns 4*FSC / vtotal / frames per seconds */
    660	return (norm & V4L2_STD_625_50) ?
    661				((fsc4 + 312) / 625 + 12) / 25 :
    662				((fsc4 + 262) / 525 * 1001 + 15000) / 30000;
    663}
    664
    665static inline unsigned int norm_vbipack(v4l2_std_id norm)
    666{
    667	return (norm & V4L2_STD_625_50) ? 511 : 400;
    668}
    669
    670int cx88_set_scale(struct cx88_core *core, unsigned int width,
    671		   unsigned int height, enum v4l2_field field)
    672{
    673	unsigned int swidth  = norm_swidth(core->tvnorm);
    674	unsigned int sheight = norm_maxh(core->tvnorm);
    675	u32 value;
    676
    677	dprintk(1, "set_scale: %dx%d [%s%s,%s]\n", width, height,
    678		V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
    679		V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
    680		v4l2_norm_to_name(core->tvnorm));
    681	if (!V4L2_FIELD_HAS_BOTH(field))
    682		height *= 2;
    683
    684	// recalc H delay and scale registers
    685	value = (width * norm_hdelay(core->tvnorm)) / swidth;
    686	value &= 0x3fe;
    687	cx_write(MO_HDELAY_EVEN,  value);
    688	cx_write(MO_HDELAY_ODD,   value);
    689	dprintk(1, "set_scale: hdelay  0x%04x (width %d)\n", value, swidth);
    690
    691	value = (swidth * 4096 / width) - 4096;
    692	cx_write(MO_HSCALE_EVEN,  value);
    693	cx_write(MO_HSCALE_ODD,   value);
    694	dprintk(1, "set_scale: hscale  0x%04x\n", value);
    695
    696	cx_write(MO_HACTIVE_EVEN, width);
    697	cx_write(MO_HACTIVE_ODD,  width);
    698	dprintk(1, "set_scale: hactive 0x%04x\n", width);
    699
    700	// recalc V scale Register (delay is constant)
    701	cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
    702	cx_write(MO_VDELAY_ODD,  norm_vdelay(core->tvnorm));
    703	dprintk(1, "set_scale: vdelay  0x%04x\n", norm_vdelay(core->tvnorm));
    704
    705	value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
    706	cx_write(MO_VSCALE_EVEN,  value);
    707	cx_write(MO_VSCALE_ODD,   value);
    708	dprintk(1, "set_scale: vscale  0x%04x\n", value);
    709
    710	cx_write(MO_VACTIVE_EVEN, sheight);
    711	cx_write(MO_VACTIVE_ODD,  sheight);
    712	dprintk(1, "set_scale: vactive 0x%04x\n", sheight);
    713
    714	// setup filters
    715	value = 0;
    716	value |= (1 << 19);        // CFILT (default)
    717	if (core->tvnorm & V4L2_STD_SECAM) {
    718		value |= (1 << 15);
    719		value |= (1 << 16);
    720	}
    721	if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
    722		value |= (1 << 13) | (1 << 5);
    723	if (field == V4L2_FIELD_INTERLACED)
    724		value |= (1 << 3); // VINT (interlaced vertical scaling)
    725	if (width < 385)
    726		value |= (1 << 0); // 3-tap interpolation
    727	if (width < 193)
    728		value |= (1 << 1); // 5-tap interpolation
    729	if (nocomb)
    730		value |= (3 << 5); // disable comb filter
    731
    732	cx_andor(MO_FILTER_EVEN,  0x7ffc7f, value); /* preserve PEAKEN, PSEL */
    733	cx_andor(MO_FILTER_ODD,   0x7ffc7f, value);
    734	dprintk(1, "set_scale: filter  0x%04x\n", value);
    735
    736	return 0;
    737}
    738EXPORT_SYMBOL(cx88_set_scale);
    739
    740static const u32 xtal = 28636363;
    741
    742static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
    743{
    744	static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
    745	u64 pll;
    746	u32 reg;
    747	int i;
    748
    749	if (prescale < 2)
    750		prescale = 2;
    751	if (prescale > 5)
    752		prescale = 5;
    753
    754	pll = ofreq * 8 * prescale * (u64)(1 << 20);
    755	do_div(pll, xtal);
    756	reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
    757	if (((reg >> 20) & 0x3f) < 14) {
    758		pr_err("pll out of range\n");
    759		return -1;
    760	}
    761
    762	dprintk(1, "set_pll:    MO_PLL_REG       0x%08x [old=0x%08x,freq=%d]\n",
    763		reg, cx_read(MO_PLL_REG), ofreq);
    764	cx_write(MO_PLL_REG, reg);
    765	for (i = 0; i < 100; i++) {
    766		reg = cx_read(MO_DEVICE_STATUS);
    767		if (reg & (1 << 2)) {
    768			dprintk(1, "pll locked [pre=%d,ofreq=%d]\n",
    769				prescale, ofreq);
    770			return 0;
    771		}
    772		dprintk(1, "pll not locked yet, waiting ...\n");
    773		usleep_range(10000, 20000);
    774	}
    775	dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq);
    776	return -1;
    777}
    778
    779int cx88_start_audio_dma(struct cx88_core *core)
    780{
    781	/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
    782	int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
    783
    784	int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size / AUD_RDS_LINES;
    785
    786	/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
    787	if (cx_read(MO_AUD_DMACNTRL) & 0x10)
    788		return 0;
    789
    790	/* setup fifo + format */
    791	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
    792	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
    793	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
    794				rds_bpl, 0);
    795
    796	cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
    797	cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
    798
    799	/* enable Up, Down and Audio RDS fifo */
    800	cx_write(MO_AUD_DMACNTRL, 0x0007);
    801
    802	return 0;
    803}
    804
    805int cx88_stop_audio_dma(struct cx88_core *core)
    806{
    807	/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
    808	if (cx_read(MO_AUD_DMACNTRL) & 0x10)
    809		return 0;
    810
    811	/* stop dma */
    812	cx_write(MO_AUD_DMACNTRL, 0x0000);
    813
    814	return 0;
    815}
    816
    817static int set_tvaudio(struct cx88_core *core)
    818{
    819	v4l2_std_id norm = core->tvnorm;
    820
    821	if (INPUT(core->input).type != CX88_VMUX_TELEVISION &&
    822	    INPUT(core->input).type != CX88_VMUX_CABLE)
    823		return 0;
    824
    825	if (V4L2_STD_PAL_BG & norm) {
    826		core->tvaudio = WW_BG;
    827
    828	} else if (V4L2_STD_PAL_DK & norm) {
    829		core->tvaudio = WW_DK;
    830
    831	} else if (V4L2_STD_PAL_I & norm) {
    832		core->tvaudio = WW_I;
    833
    834	} else if (V4L2_STD_SECAM_L & norm) {
    835		core->tvaudio = WW_L;
    836
    837	} else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) &
    838		   norm) {
    839		core->tvaudio = WW_BG;
    840
    841	} else if (V4L2_STD_SECAM_DK & norm) {
    842		core->tvaudio = WW_DK;
    843
    844	} else if ((V4L2_STD_NTSC_M & norm) ||
    845		   (V4L2_STD_PAL_M  & norm)) {
    846		core->tvaudio = WW_BTSC;
    847
    848	} else if (V4L2_STD_NTSC_M_JP & norm) {
    849		core->tvaudio = WW_EIAJ;
    850
    851	} else {
    852		pr_info("tvaudio support needs work for this tv norm [%s], sorry\n",
    853			v4l2_norm_to_name(core->tvnorm));
    854		core->tvaudio = WW_NONE;
    855		return 0;
    856	}
    857
    858	cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
    859	cx88_set_tvaudio(core);
    860	/* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
    861
    862/*
    863 * This should be needed only on cx88-alsa. It seems that some cx88 chips have
    864 * bugs and does require DMA enabled for it to work.
    865 */
    866	cx88_start_audio_dma(core);
    867	return 0;
    868}
    869
    870int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
    871{
    872	u32 fsc8;
    873	u32 adc_clock;
    874	u32 vdec_clock;
    875	u32 step_db, step_dr;
    876	u64 tmp64;
    877	u32 bdelay, agcdelay, htotal;
    878	u32 cxiformat, cxoformat;
    879
    880	if (norm == core->tvnorm)
    881		return 0;
    882	if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
    883			     vb2_is_busy(&core->v4ldev->vb2_vbiq)))
    884		return -EBUSY;
    885	if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq))
    886		return -EBUSY;
    887	core->tvnorm = norm;
    888	fsc8       = norm_fsc8(norm);
    889	adc_clock  = xtal;
    890	vdec_clock = fsc8;
    891	step_db    = fsc8;
    892	step_dr    = fsc8;
    893
    894	if (norm & V4L2_STD_NTSC_M_JP) {
    895		cxiformat = VideoFormatNTSCJapan;
    896		cxoformat = 0x181f0008;
    897	} else if (norm & V4L2_STD_NTSC_443) {
    898		cxiformat = VideoFormatNTSC443;
    899		cxoformat = 0x181f0008;
    900	} else if (norm & V4L2_STD_PAL_M) {
    901		cxiformat = VideoFormatPALM;
    902		cxoformat = 0x1c1f0008;
    903	} else if (norm & V4L2_STD_PAL_N) {
    904		cxiformat = VideoFormatPALN;
    905		cxoformat = 0x1c1f0008;
    906	} else if (norm & V4L2_STD_PAL_Nc) {
    907		cxiformat = VideoFormatPALNC;
    908		cxoformat = 0x1c1f0008;
    909	} else if (norm & V4L2_STD_PAL_60) {
    910		cxiformat = VideoFormatPAL60;
    911		cxoformat = 0x181f0008;
    912	} else if (norm & V4L2_STD_NTSC) {
    913		cxiformat = VideoFormatNTSC;
    914		cxoformat = 0x181f0008;
    915	} else if (norm & V4L2_STD_SECAM) {
    916		step_db = 4250000 * 8;
    917		step_dr = 4406250 * 8;
    918
    919		cxiformat = VideoFormatSECAM;
    920		cxoformat = 0x181f0008;
    921	} else { /* PAL */
    922		cxiformat = VideoFormatPAL;
    923		cxoformat = 0x181f0008;
    924	}
    925
    926	dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
    927		v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
    928		step_db, step_dr);
    929	set_pll(core, 2, vdec_clock);
    930
    931	dprintk(1, "set_tvnorm: MO_INPUT_FORMAT  0x%08x [old=0x%08x]\n",
    932		cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
    933	/*
    934	 * Chroma AGC must be disabled if SECAM is used, we enable it
    935	 * by default on PAL and NTSC
    936	 */
    937	cx_andor(MO_INPUT_FORMAT, 0x40f,
    938		 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
    939
    940	// FIXME: as-is from DScaler
    941	dprintk(1, "set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
    942		cxoformat, cx_read(MO_OUTPUT_FORMAT));
    943	cx_write(MO_OUTPUT_FORMAT, cxoformat);
    944
    945	// MO_SCONV_REG = adc clock / video dec clock * 2^17
    946	tmp64  = adc_clock * (u64)(1 << 17);
    947	do_div(tmp64, vdec_clock);
    948	dprintk(1, "set_tvnorm: MO_SCONV_REG     0x%08x [old=0x%08x]\n",
    949		(u32)tmp64, cx_read(MO_SCONV_REG));
    950	cx_write(MO_SCONV_REG, (u32)tmp64);
    951
    952	// MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
    953	tmp64  = step_db * (u64)(1 << 22);
    954	do_div(tmp64, vdec_clock);
    955	dprintk(1, "set_tvnorm: MO_SUB_STEP      0x%08x [old=0x%08x]\n",
    956		(u32)tmp64, cx_read(MO_SUB_STEP));
    957	cx_write(MO_SUB_STEP, (u32)tmp64);
    958
    959	// MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
    960	tmp64  = step_dr * (u64)(1 << 22);
    961	do_div(tmp64, vdec_clock);
    962	dprintk(1, "set_tvnorm: MO_SUB_STEP_DR   0x%08x [old=0x%08x]\n",
    963		(u32)tmp64, cx_read(MO_SUB_STEP_DR));
    964	cx_write(MO_SUB_STEP_DR, (u32)tmp64);
    965
    966	// bdelay + agcdelay
    967	bdelay   = vdec_clock * 65 / 20000000 + 21;
    968	agcdelay = vdec_clock * 68 / 20000000 + 15;
    969	dprintk(1,
    970		"set_tvnorm: MO_AGC_BURST     0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
    971		(bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST),
    972		bdelay, agcdelay);
    973	cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
    974
    975	// htotal
    976	tmp64 = norm_htotal(norm) * (u64)vdec_clock;
    977	do_div(tmp64, fsc8);
    978	htotal = (u32)tmp64;
    979	dprintk(1,
    980		"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
    981		htotal, cx_read(MO_HTOTAL), (u32)tmp64);
    982	cx_andor(MO_HTOTAL, 0x07ff, htotal);
    983
    984	// vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
    985	// the effective vbi offset ~244 samples, the same as the Bt8x8
    986	cx_write(MO_VBI_PACKET, (10 << 11) | norm_vbipack(norm));
    987
    988	// this is needed as well to set all tvnorm parameter
    989	cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
    990
    991	// audio
    992	set_tvaudio(core);
    993
    994	// tell i2c chips
    995	call_all(core, video, s_std, norm);
    996
    997	/*
    998	 * The chroma_agc control should be inaccessible
    999	 * if the video format is SECAM
   1000	 */
   1001	v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
   1002
   1003	// done
   1004	return 0;
   1005}
   1006EXPORT_SYMBOL(cx88_set_tvnorm);
   1007
   1008/* ------------------------------------------------------------------ */
   1009
   1010void cx88_vdev_init(struct cx88_core *core,
   1011		    struct pci_dev *pci,
   1012		    struct video_device *vfd,
   1013		    const struct video_device *template_,
   1014		    const char *type)
   1015{
   1016	*vfd = *template_;
   1017
   1018	/*
   1019	 * The dev pointer of v4l2_device is NULL, instead we set the
   1020	 * video_device dev_parent pointer to the correct PCI bus device.
   1021	 * This driver is a rare example where there is one v4l2_device,
   1022	 * but the video nodes have different parent (PCI) devices.
   1023	 */
   1024	vfd->v4l2_dev = &core->v4l2_dev;
   1025	vfd->dev_parent = &pci->dev;
   1026	vfd->release = video_device_release_empty;
   1027	vfd->lock = &core->lock;
   1028	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
   1029		 core->name, type, core->board.name);
   1030}
   1031EXPORT_SYMBOL(cx88_vdev_init);
   1032
   1033struct cx88_core *cx88_core_get(struct pci_dev *pci)
   1034{
   1035	struct cx88_core *core;
   1036
   1037	mutex_lock(&devlist);
   1038	list_for_each_entry(core, &cx88_devlist, devlist) {
   1039		if (pci->bus->number != core->pci_bus)
   1040			continue;
   1041		if (PCI_SLOT(pci->devfn) != core->pci_slot)
   1042			continue;
   1043
   1044		if (cx88_get_resources(core, pci) != 0) {
   1045			mutex_unlock(&devlist);
   1046			return NULL;
   1047		}
   1048		refcount_inc(&core->refcount);
   1049		mutex_unlock(&devlist);
   1050		return core;
   1051	}
   1052
   1053	core = cx88_core_create(pci, cx88_devcount);
   1054	if (core) {
   1055		cx88_devcount++;
   1056		list_add_tail(&core->devlist, &cx88_devlist);
   1057	}
   1058
   1059	mutex_unlock(&devlist);
   1060	return core;
   1061}
   1062EXPORT_SYMBOL(cx88_core_get);
   1063
   1064void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
   1065{
   1066	release_mem_region(pci_resource_start(pci, 0),
   1067			   pci_resource_len(pci, 0));
   1068
   1069	if (!refcount_dec_and_test(&core->refcount))
   1070		return;
   1071
   1072	mutex_lock(&devlist);
   1073	cx88_ir_fini(core);
   1074	if (core->i2c_rc == 0) {
   1075		i2c_unregister_device(core->i2c_rtc);
   1076		i2c_del_adapter(&core->i2c_adap);
   1077	}
   1078	list_del(&core->devlist);
   1079	iounmap(core->lmmio);
   1080	cx88_devcount--;
   1081	mutex_unlock(&devlist);
   1082	v4l2_ctrl_handler_free(&core->video_hdl);
   1083	v4l2_ctrl_handler_free(&core->audio_hdl);
   1084	v4l2_device_unregister(&core->v4l2_dev);
   1085	kfree(core);
   1086}
   1087EXPORT_SYMBOL(cx88_core_put);