media: cx25821: use generic power management
[linux-2.6-block.git] / drivers / media / pci / cx25821 / cx25821-core.c
CommitLineData
c942fddf 1// SPDX-License-Identifier: GPL-2.0-or-later
02b20b0b
MCC
2/*
3 * Driver for the Conexant CX25821 PCIe bridge
4 *
bb4c9a74 5 * Copyright (C) 2009 Conexant Systems Inc.
02b20b0b
MCC
6 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
7 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
02b20b0b
MCC
8 */
9
36d89f7d
JP
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
02b20b0b 12#include <linux/i2c.h>
5a0e3ad6 13#include <linux/slab.h>
02b20b0b
MCC
14#include "cx25821.h"
15#include "cx25821-sram.h"
16#include "cx25821-video.h"
17
18MODULE_DESCRIPTION("Driver for Athena cards");
19MODULE_AUTHOR("Shu Lin - Hiep Huynh");
20MODULE_LICENSE("GPL");
21
02b20b0b
MCC
22static unsigned int debug;
23module_param(debug, int, 0644);
24MODULE_PARM_DESC(debug, "enable debug messages");
25
53e712d0 26static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
1a9fc855 27module_param_array(card, int, NULL, 0444);
02b20b0b
MCC
28MODULE_PARM_DESC(card, "card type");
29
bfef0d35 30const struct sram_channel cx25821_sram_channels[] = {
1a9fc855 31 [SRAM_CH00] = {
1c2b5520
LF
32 .i = SRAM_CH00,
33 .name = "VID A",
34 .cmds_start = VID_A_DOWN_CMDS,
35 .ctrl_start = VID_A_IQ,
36 .cdt = VID_A_CDT,
37 .fifo_start = VID_A_DOWN_CLUSTER_1,
38 .fifo_size = (VID_CLUSTER_SIZE << 2),
39 .ptr1_reg = DMA1_PTR1,
40 .ptr2_reg = DMA1_PTR2,
41 .cnt1_reg = DMA1_CNT1,
42 .cnt2_reg = DMA1_CNT2,
43 .int_msk = VID_A_INT_MSK,
44 .int_stat = VID_A_INT_STAT,
45 .int_mstat = VID_A_INT_MSTAT,
46 .dma_ctl = VID_DST_A_DMA_CTL,
47 .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
48 .gpcnt = VID_DST_A_GPCNT,
49 .vip_ctl = VID_DST_A_VIP_CTL,
50 .pix_frmt = VID_DST_A_PIX_FRMT,
51 },
1a9fc855
MCC
52
53 [SRAM_CH01] = {
1c2b5520
LF
54 .i = SRAM_CH01,
55 .name = "VID B",
56 .cmds_start = VID_B_DOWN_CMDS,
57 .ctrl_start = VID_B_IQ,
58 .cdt = VID_B_CDT,
59 .fifo_start = VID_B_DOWN_CLUSTER_1,
60 .fifo_size = (VID_CLUSTER_SIZE << 2),
61 .ptr1_reg = DMA2_PTR1,
62 .ptr2_reg = DMA2_PTR2,
63 .cnt1_reg = DMA2_CNT1,
64 .cnt2_reg = DMA2_CNT2,
65 .int_msk = VID_B_INT_MSK,
66 .int_stat = VID_B_INT_STAT,
67 .int_mstat = VID_B_INT_MSTAT,
68 .dma_ctl = VID_DST_B_DMA_CTL,
69 .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
70 .gpcnt = VID_DST_B_GPCNT,
71 .vip_ctl = VID_DST_B_VIP_CTL,
72 .pix_frmt = VID_DST_B_PIX_FRMT,
73 },
1a9fc855
MCC
74
75 [SRAM_CH02] = {
1c2b5520
LF
76 .i = SRAM_CH02,
77 .name = "VID C",
78 .cmds_start = VID_C_DOWN_CMDS,
79 .ctrl_start = VID_C_IQ,
80 .cdt = VID_C_CDT,
81 .fifo_start = VID_C_DOWN_CLUSTER_1,
82 .fifo_size = (VID_CLUSTER_SIZE << 2),
83 .ptr1_reg = DMA3_PTR1,
84 .ptr2_reg = DMA3_PTR2,
85 .cnt1_reg = DMA3_CNT1,
86 .cnt2_reg = DMA3_CNT2,
87 .int_msk = VID_C_INT_MSK,
88 .int_stat = VID_C_INT_STAT,
89 .int_mstat = VID_C_INT_MSTAT,
90 .dma_ctl = VID_DST_C_DMA_CTL,
91 .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
92 .gpcnt = VID_DST_C_GPCNT,
93 .vip_ctl = VID_DST_C_VIP_CTL,
94 .pix_frmt = VID_DST_C_PIX_FRMT,
95 },
1a9fc855
MCC
96
97 [SRAM_CH03] = {
1c2b5520
LF
98 .i = SRAM_CH03,
99 .name = "VID D",
100 .cmds_start = VID_D_DOWN_CMDS,
101 .ctrl_start = VID_D_IQ,
102 .cdt = VID_D_CDT,
103 .fifo_start = VID_D_DOWN_CLUSTER_1,
104 .fifo_size = (VID_CLUSTER_SIZE << 2),
105 .ptr1_reg = DMA4_PTR1,
106 .ptr2_reg = DMA4_PTR2,
107 .cnt1_reg = DMA4_CNT1,
108 .cnt2_reg = DMA4_CNT2,
109 .int_msk = VID_D_INT_MSK,
110 .int_stat = VID_D_INT_STAT,
111 .int_mstat = VID_D_INT_MSTAT,
112 .dma_ctl = VID_DST_D_DMA_CTL,
113 .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
114 .gpcnt = VID_DST_D_GPCNT,
115 .vip_ctl = VID_DST_D_VIP_CTL,
116 .pix_frmt = VID_DST_D_PIX_FRMT,
117 },
1a9fc855
MCC
118
119 [SRAM_CH04] = {
1c2b5520
LF
120 .i = SRAM_CH04,
121 .name = "VID E",
122 .cmds_start = VID_E_DOWN_CMDS,
123 .ctrl_start = VID_E_IQ,
124 .cdt = VID_E_CDT,
125 .fifo_start = VID_E_DOWN_CLUSTER_1,
126 .fifo_size = (VID_CLUSTER_SIZE << 2),
127 .ptr1_reg = DMA5_PTR1,
128 .ptr2_reg = DMA5_PTR2,
129 .cnt1_reg = DMA5_CNT1,
130 .cnt2_reg = DMA5_CNT2,
131 .int_msk = VID_E_INT_MSK,
132 .int_stat = VID_E_INT_STAT,
133 .int_mstat = VID_E_INT_MSTAT,
134 .dma_ctl = VID_DST_E_DMA_CTL,
135 .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
136 .gpcnt = VID_DST_E_GPCNT,
137 .vip_ctl = VID_DST_E_VIP_CTL,
138 .pix_frmt = VID_DST_E_PIX_FRMT,
139 },
1a9fc855
MCC
140
141 [SRAM_CH05] = {
1c2b5520
LF
142 .i = SRAM_CH05,
143 .name = "VID F",
144 .cmds_start = VID_F_DOWN_CMDS,
145 .ctrl_start = VID_F_IQ,
146 .cdt = VID_F_CDT,
147 .fifo_start = VID_F_DOWN_CLUSTER_1,
148 .fifo_size = (VID_CLUSTER_SIZE << 2),
149 .ptr1_reg = DMA6_PTR1,
150 .ptr2_reg = DMA6_PTR2,
151 .cnt1_reg = DMA6_CNT1,
152 .cnt2_reg = DMA6_CNT2,
153 .int_msk = VID_F_INT_MSK,
154 .int_stat = VID_F_INT_STAT,
155 .int_mstat = VID_F_INT_MSTAT,
156 .dma_ctl = VID_DST_F_DMA_CTL,
157 .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
158 .gpcnt = VID_DST_F_GPCNT,
159 .vip_ctl = VID_DST_F_VIP_CTL,
160 .pix_frmt = VID_DST_F_PIX_FRMT,
161 },
1a9fc855
MCC
162
163 [SRAM_CH06] = {
1c2b5520
LF
164 .i = SRAM_CH06,
165 .name = "VID G",
166 .cmds_start = VID_G_DOWN_CMDS,
167 .ctrl_start = VID_G_IQ,
168 .cdt = VID_G_CDT,
169 .fifo_start = VID_G_DOWN_CLUSTER_1,
170 .fifo_size = (VID_CLUSTER_SIZE << 2),
171 .ptr1_reg = DMA7_PTR1,
172 .ptr2_reg = DMA7_PTR2,
173 .cnt1_reg = DMA7_CNT1,
174 .cnt2_reg = DMA7_CNT2,
175 .int_msk = VID_G_INT_MSK,
176 .int_stat = VID_G_INT_STAT,
177 .int_mstat = VID_G_INT_MSTAT,
178 .dma_ctl = VID_DST_G_DMA_CTL,
179 .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
180 .gpcnt = VID_DST_G_GPCNT,
181 .vip_ctl = VID_DST_G_VIP_CTL,
182 .pix_frmt = VID_DST_G_PIX_FRMT,
183 },
1a9fc855
MCC
184
185 [SRAM_CH07] = {
1c2b5520
LF
186 .i = SRAM_CH07,
187 .name = "VID H",
188 .cmds_start = VID_H_DOWN_CMDS,
189 .ctrl_start = VID_H_IQ,
190 .cdt = VID_H_CDT,
191 .fifo_start = VID_H_DOWN_CLUSTER_1,
192 .fifo_size = (VID_CLUSTER_SIZE << 2),
193 .ptr1_reg = DMA8_PTR1,
194 .ptr2_reg = DMA8_PTR2,
195 .cnt1_reg = DMA8_CNT1,
196 .cnt2_reg = DMA8_CNT2,
197 .int_msk = VID_H_INT_MSK,
198 .int_stat = VID_H_INT_STAT,
199 .int_mstat = VID_H_INT_MSTAT,
200 .dma_ctl = VID_DST_H_DMA_CTL,
201 .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
202 .gpcnt = VID_DST_H_GPCNT,
203 .vip_ctl = VID_DST_H_VIP_CTL,
204 .pix_frmt = VID_DST_H_PIX_FRMT,
205 },
1a9fc855
MCC
206
207 [SRAM_CH08] = {
1c2b5520
LF
208 .name = "audio from",
209 .cmds_start = AUD_A_DOWN_CMDS,
210 .ctrl_start = AUD_A_IQ,
211 .cdt = AUD_A_CDT,
212 .fifo_start = AUD_A_DOWN_CLUSTER_1,
213 .fifo_size = AUDIO_CLUSTER_SIZE * 3,
214 .ptr1_reg = DMA17_PTR1,
215 .ptr2_reg = DMA17_PTR2,
216 .cnt1_reg = DMA17_CNT1,
217 .cnt2_reg = DMA17_CNT2,
218 },
1a9fc855
MCC
219
220 [SRAM_CH09] = {
1c2b5520
LF
221 .i = SRAM_CH09,
222 .name = "VID Upstream I",
223 .cmds_start = VID_I_UP_CMDS,
224 .ctrl_start = VID_I_IQ,
225 .cdt = VID_I_CDT,
226 .fifo_start = VID_I_UP_CLUSTER_1,
227 .fifo_size = (VID_CLUSTER_SIZE << 2),
228 .ptr1_reg = DMA15_PTR1,
229 .ptr2_reg = DMA15_PTR2,
230 .cnt1_reg = DMA15_CNT1,
231 .cnt2_reg = DMA15_CNT2,
232 .int_msk = VID_I_INT_MSK,
233 .int_stat = VID_I_INT_STAT,
234 .int_mstat = VID_I_INT_MSTAT,
235 .dma_ctl = VID_SRC_I_DMA_CTL,
236 .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
237 .gpcnt = VID_SRC_I_GPCNT,
238
239 .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
240 .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
241 .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
242 .vid_cdt_size = VID_SRC_I_CDT_SZ,
243 .irq_bit = 8,
244 },
1a9fc855
MCC
245
246 [SRAM_CH10] = {
1c2b5520
LF
247 .i = SRAM_CH10,
248 .name = "VID Upstream J",
249 .cmds_start = VID_J_UP_CMDS,
250 .ctrl_start = VID_J_IQ,
251 .cdt = VID_J_CDT,
252 .fifo_start = VID_J_UP_CLUSTER_1,
253 .fifo_size = (VID_CLUSTER_SIZE << 2),
254 .ptr1_reg = DMA16_PTR1,
255 .ptr2_reg = DMA16_PTR2,
256 .cnt1_reg = DMA16_CNT1,
257 .cnt2_reg = DMA16_CNT2,
258 .int_msk = VID_J_INT_MSK,
259 .int_stat = VID_J_INT_STAT,
260 .int_mstat = VID_J_INT_MSTAT,
261 .dma_ctl = VID_SRC_J_DMA_CTL,
262 .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
263 .gpcnt = VID_SRC_J_GPCNT,
264
265 .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
266 .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
267 .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
268 .vid_cdt_size = VID_SRC_J_CDT_SZ,
269 .irq_bit = 9,
270 },
1a9fc855
MCC
271
272 [SRAM_CH11] = {
1c2b5520
LF
273 .i = SRAM_CH11,
274 .name = "Audio Upstream Channel B",
275 .cmds_start = AUD_B_UP_CMDS,
276 .ctrl_start = AUD_B_IQ,
277 .cdt = AUD_B_CDT,
278 .fifo_start = AUD_B_UP_CLUSTER_1,
279 .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
280 .ptr1_reg = DMA22_PTR1,
281 .ptr2_reg = DMA22_PTR2,
282 .cnt1_reg = DMA22_CNT1,
283 .cnt2_reg = DMA22_CNT2,
284 .int_msk = AUD_B_INT_MSK,
285 .int_stat = AUD_B_INT_STAT,
286 .int_mstat = AUD_B_INT_MSTAT,
287 .dma_ctl = AUD_INT_DMA_CTL,
288 .gpcnt_ctl = AUD_B_GPCNT_CTL,
289 .gpcnt = AUD_B_GPCNT,
290 .aud_length = AUD_B_LNGTH,
291 .aud_cfg = AUD_B_CFG,
292 .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
293 .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
294 .irq_bit = 11,
295 },
02b20b0b 296};
de2c4349 297EXPORT_SYMBOL(cx25821_sram_channels);
02b20b0b 298
02b20b0b
MCC
299static int cx25821_risc_decode(u32 risc)
300{
36d89f7d 301 static const char * const instr[16] = {
1a9fc855
MCC
302 [RISC_SYNC >> 28] = "sync",
303 [RISC_WRITE >> 28] = "write",
304 [RISC_WRITEC >> 28] = "writec",
305 [RISC_READ >> 28] = "read",
306 [RISC_READC >> 28] = "readc",
307 [RISC_JUMP >> 28] = "jump",
308 [RISC_SKIP >> 28] = "skip",
309 [RISC_WRITERM >> 28] = "writerm",
310 [RISC_WRITECM >> 28] = "writecm",
311 [RISC_WRITECR >> 28] = "writecr",
312 };
36d89f7d 313 static const int incr[16] = {
1a9fc855
MCC
314 [RISC_WRITE >> 28] = 3,
315 [RISC_JUMP >> 28] = 3,
316 [RISC_SKIP >> 28] = 1,
317 [RISC_SYNC >> 28] = 1,
318 [RISC_WRITERM >> 28] = 3,
319 [RISC_WRITECM >> 28] = 3,
320 [RISC_WRITECR >> 28] = 4,
321 };
36d89f7d 322 static const char * const bits[] = {
1a9fc855
MCC
323 "12", "13", "14", "resync",
324 "cnt0", "cnt1", "18", "19",
325 "20", "21", "22", "23",
326 "irq1", "irq2", "eol", "sol",
327 };
328 int i;
329
36d89f7d
JP
330 pr_cont("0x%08x [ %s",
331 risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
1a9fc855
MCC
332 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
333 if (risc & (1 << (i + 12)))
36d89f7d 334 pr_cont(" %s", bits[i]);
bb4c9a74 335 }
36d89f7d 336 pr_cont(" count=%d ]\n", risc & 0xfff);
1a9fc855 337 return incr[risc >> 28] ? incr[risc >> 28] : 1;
02b20b0b
MCC
338}
339
340static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
341{
1a9fc855
MCC
342 struct cx25821_i2c *bus = i2c_adap->algo_data;
343 struct cx25821_dev *dev = bus->dev;
344 return cx_read(bus->reg_stat) & 0x01;
02b20b0b
MCC
345}
346
02b20b0b
MCC
347static void cx25821_registers_init(struct cx25821_dev *dev)
348{
1a9fc855 349 u32 tmp;
bb4c9a74 350
de2c4349 351 /* enable RUN_RISC in Pecos */
1a9fc855 352 cx_write(DEV_CNTRL2, 0x20);
bb4c9a74 353
de2c4349
OP
354 /* Set the master PCI interrupt masks to enable video, audio, MBIF,
355 * and GPIO interrupts
356 * I2C interrupt masking is handled by the I2C objects themselves. */
1a9fc855 357 cx_write(PCI_INT_MSK, 0x2001FFFF);
02b20b0b 358
1a9fc855 359 tmp = cx_read(RDR_TLCTL0);
de2c4349 360 tmp &= ~FLD_CFG_RCB_CK_EN; /* Clear the RCB_CK_EN bit */
1a9fc855 361 cx_write(RDR_TLCTL0, tmp);
02b20b0b 362
de2c4349 363 /* PLL-A setting for the Audio Master Clock */
1a9fc855 364 cx_write(PLL_A_INT_FRAC, 0x9807A58B);
02b20b0b 365
de2c4349 366 /* PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1 */
1a9fc855 367 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
bb4c9a74 368
de2c4349 369 /* clear reset bit [31] */
1a9fc855
MCC
370 tmp = cx_read(PLL_A_INT_FRAC);
371 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
02b20b0b 372
de2c4349 373 /* PLL-B setting for Mobilygen Host Bus Interface */
1a9fc855 374 cx_write(PLL_B_INT_FRAC, 0x9883A86F);
02b20b0b 375
de2c4349 376 /* PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0 */
1a9fc855 377 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
02b20b0b 378
de2c4349 379 /* clear reset bit [31] */
1a9fc855
MCC
380 tmp = cx_read(PLL_B_INT_FRAC);
381 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
02b20b0b 382
de2c4349 383 /* PLL-C setting for video upstream channel */
1a9fc855 384 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
02b20b0b 385
de2c4349 386 /* PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0 */
1a9fc855 387 cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
02b20b0b 388
de2c4349 389 /* clear reset bit [31] */
1a9fc855
MCC
390 tmp = cx_read(PLL_C_INT_FRAC);
391 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
02b20b0b 392
de2c4349 393 /* PLL-D setting for audio upstream channel */
1a9fc855 394 cx_write(PLL_D_INT_FRAC, 0x98757F5B);
02b20b0b 395
de2c4349 396 /* PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0 */
1a9fc855 397 cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
02b20b0b 398
de2c4349 399 /* clear reset bit [31] */
1a9fc855
MCC
400 tmp = cx_read(PLL_D_INT_FRAC);
401 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
02b20b0b 402
de2c4349
OP
403 /* This selects the PLL C clock source for the video upstream channel
404 * I and J */
1a9fc855
MCC
405 tmp = cx_read(VID_CH_CLK_SEL);
406 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
bb4c9a74 407
de2c4349
OP
408 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
409 * channel A-C
410 * select 656/VIP DST for downstream Channel A - C */
1a9fc855 411 tmp = cx_read(VID_CH_MODE_SEL);
de2c4349 412 /* cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF); */
1a9fc855 413 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
02b20b0b 414
de2c4349 415 /* enables 656 port I and J as output */
1a9fc855 416 tmp = cx_read(CLK_RST);
de2c4349
OP
417 /* use external ALT_PLL_REF pin as its reference clock instead */
418 tmp |= FLD_USE_ALT_PLL_REF;
1a9fc855 419 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
bb4c9a74 420
65155a9b 421 msleep(100);
1a9fc855 422}
02b20b0b 423
1a9fc855 424int cx25821_sram_channel_setup(struct cx25821_dev *dev,
bfef0d35 425 const struct sram_channel *ch,
1a9fc855
MCC
426 unsigned int bpl, u32 risc)
427{
428 unsigned int i, lines;
429 u32 cdt;
430
431 if (ch->cmds_start == 0) {
432 cx_write(ch->ptr1_reg, 0);
433 cx_write(ch->ptr2_reg, 0);
434 cx_write(ch->cnt2_reg, 0);
435 cx_write(ch->cnt1_reg, 0);
436 return 0;
437 }
bb4c9a74 438
1a9fc855
MCC
439 bpl = (bpl + 7) & ~7; /* alignment */
440 cdt = ch->cdt;
441 lines = ch->fifo_size / bpl;
bb4c9a74 442
de2c4349 443 if (lines > 4)
1a9fc855 444 lines = 4;
02b20b0b 445
1a9fc855
MCC
446 BUG_ON(lines < 2);
447
448 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
449 cx_write(8 + 4, 8);
450 cx_write(8 + 8, 0);
451
452 /* write CDT */
453 for (i = 0; i < lines; i++) {
454 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
455 cx_write(cdt + 16 * i + 4, 0);
456 cx_write(cdt + 16 * i + 8, 0);
457 cx_write(cdt + 16 * i + 12, 0);
458 }
459
de2c4349 460 /* init the first cdt buffer */
1a9fc855
MCC
461 for (i = 0; i < 128; i++)
462 cx_write(ch->fifo_start + 4 * i, i);
463
464 /* write CMDS */
de2c4349 465 if (ch->jumponly)
1a9fc855 466 cx_write(ch->cmds_start + 0, 8);
de2c4349 467 else
1a9fc855 468 cx_write(ch->cmds_start + 0, risc);
1a9fc855
MCC
469
470 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
471 cx_write(ch->cmds_start + 8, cdt);
472 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
473 cx_write(ch->cmds_start + 16, ch->ctrl_start);
474
475 if (ch->jumponly)
476 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
477 else
478 cx_write(ch->cmds_start + 20, 64 >> 2);
479
480 for (i = 24; i < 80; i += 4)
481 cx_write(ch->cmds_start + i, 0);
482
483 /* fill registers */
484 cx_write(ch->ptr1_reg, ch->fifo_start);
485 cx_write(ch->ptr2_reg, cdt);
486 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
487 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
02b20b0b 488
bb4c9a74 489 return 0;
02b20b0b
MCC
490}
491
492int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
bfef0d35 493 const struct sram_channel *ch,
1a9fc855 494 unsigned int bpl, u32 risc)
02b20b0b 495{
1a9fc855
MCC
496 unsigned int i, lines;
497 u32 cdt;
498
499 if (ch->cmds_start == 0) {
500 cx_write(ch->ptr1_reg, 0);
501 cx_write(ch->ptr2_reg, 0);
502 cx_write(ch->cnt2_reg, 0);
503 cx_write(ch->cnt1_reg, 0);
504 return 0;
505 }
506
507 bpl = (bpl + 7) & ~7; /* alignment */
508 cdt = ch->cdt;
509 lines = ch->fifo_size / bpl;
510
de2c4349
OP
511 if (lines > 3)
512 lines = 3; /* for AUDIO */
02b20b0b 513
1a9fc855
MCC
514 BUG_ON(lines < 2);
515
516 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
517 cx_write(8 + 4, 8);
518 cx_write(8 + 8, 0);
519
520 /* write CDT */
521 for (i = 0; i < lines; i++) {
522 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
523 cx_write(cdt + 16 * i + 4, 0);
524 cx_write(cdt + 16 * i + 8, 0);
525 cx_write(cdt + 16 * i + 12, 0);
526 }
527
528 /* write CMDS */
de2c4349 529 if (ch->jumponly)
1a9fc855 530 cx_write(ch->cmds_start + 0, 8);
de2c4349 531 else
1a9fc855 532 cx_write(ch->cmds_start + 0, risc);
1a9fc855
MCC
533
534 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
535 cx_write(ch->cmds_start + 8, cdt);
536 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
537 cx_write(ch->cmds_start + 16, ch->ctrl_start);
538
de2c4349
OP
539 /* IQ size */
540 if (ch->jumponly)
1a9fc855 541 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
de2c4349 542 else
1a9fc855 543 cx_write(ch->cmds_start + 20, 64 >> 2);
1a9fc855 544
de2c4349 545 /* zero out */
1a9fc855
MCC
546 for (i = 24; i < 80; i += 4)
547 cx_write(ch->cmds_start + i, 0);
548
549 /* fill registers */
550 cx_write(ch->ptr1_reg, ch->fifo_start);
551 cx_write(ch->ptr2_reg, cdt);
552 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
553 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
02b20b0b 554
bb4c9a74 555 return 0;
02b20b0b 556}
de2c4349 557EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
02b20b0b 558
bfef0d35 559void cx25821_sram_channel_dump(struct cx25821_dev *dev, const struct sram_channel *ch)
02b20b0b 560{
1a9fc855
MCC
561 static char *name[] = {
562 "init risc lo",
563 "init risc hi",
564 "cdt base",
565 "cdt size",
566 "iq base",
567 "iq size",
568 "risc pc lo",
569 "risc pc hi",
570 "iq wr ptr",
571 "iq rd ptr",
572 "cdt current",
573 "pci target lo",
574 "pci target hi",
575 "line / byte",
576 };
577 u32 risc;
578 unsigned int i, j, n;
579
36d89f7d 580 pr_warn("%s: %s - dma channel status dump\n", dev->name, ch->name);
1a9fc855 581 for (i = 0; i < ARRAY_SIZE(name); i++)
36d89f7d
JP
582 pr_warn("cmds + 0x%2x: %-15s: 0x%08x\n",
583 i * 4, name[i], cx_read(ch->cmds_start + 4 * i));
1a9fc855
MCC
584
585 j = i * 4;
586 for (i = 0; i < 4;) {
587 risc = cx_read(ch->cmds_start + 4 * (i + 14));
36d89f7d 588 pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
1a9fc855
MCC
589 i += cx25821_risc_decode(risc);
590 }
591
592 for (i = 0; i < (64 >> 2); i += n) {
593 risc = cx_read(ch->ctrl_start + 4 * i);
594 /* No consideration for bits 63-32 */
595
36d89f7d
JP
596 pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
597 i * 4, ch->ctrl_start + 4 * i, i);
1a9fc855
MCC
598 n = cx25821_risc_decode(risc);
599 for (j = 1; j < n; j++) {
600 risc = cx_read(ch->ctrl_start + 4 * (i + j));
36d89f7d
JP
601 pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
602 4 * (i + j), i + j, risc, j);
1a9fc855 603 }
bb4c9a74 604 }
1a9fc855 605
36d89f7d
JP
606 pr_warn(" : fifo: 0x%08x -> 0x%x\n",
607 ch->fifo_start, ch->fifo_start + ch->fifo_size);
608 pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
609 ch->ctrl_start, ch->ctrl_start + 6 * 16);
610 pr_warn(" : ptr1_reg: 0x%08x\n",
611 cx_read(ch->ptr1_reg));
612 pr_warn(" : ptr2_reg: 0x%08x\n",
613 cx_read(ch->ptr2_reg));
614 pr_warn(" : cnt1_reg: 0x%08x\n",
615 cx_read(ch->cnt1_reg));
616 pr_warn(" : cnt2_reg: 0x%08x\n",
617 cx_read(ch->cnt2_reg));
02b20b0b
MCC
618}
619
1a9fc855 620void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
bfef0d35 621 const struct sram_channel *ch)
02b20b0b 622{
36d89f7d 623 static const char * const name[] = {
1a9fc855
MCC
624 "init risc lo",
625 "init risc hi",
626 "cdt base",
627 "cdt size",
628 "iq base",
629 "iq size",
630 "risc pc lo",
631 "risc pc hi",
632 "iq wr ptr",
633 "iq rd ptr",
634 "cdt current",
635 "pci target lo",
636 "pci target hi",
637 "line / byte",
638 };
bb4c9a74
MCC
639
640 u32 risc, value, tmp;
1a9fc855 641 unsigned int i, j, n;
02b20b0b 642
36d89f7d
JP
643 pr_info("\n%s: %s - dma Audio channel status dump\n",
644 dev->name, ch->name);
02b20b0b 645
1a9fc855 646 for (i = 0; i < ARRAY_SIZE(name); i++)
36d89f7d
JP
647 pr_info("%s: cmds + 0x%2x: %-15s: 0x%08x\n",
648 dev->name, i * 4, name[i],
649 cx_read(ch->cmds_start + 4 * i));
bb4c9a74 650
1a9fc855
MCC
651 j = i * 4;
652 for (i = 0; i < 4;) {
653 risc = cx_read(ch->cmds_start + 4 * (i + 14));
36d89f7d 654 pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
1a9fc855
MCC
655 i += cx25821_risc_decode(risc);
656 }
02b20b0b 657
1a9fc855
MCC
658 for (i = 0; i < (64 >> 2); i += n) {
659 risc = cx_read(ch->ctrl_start + 4 * i);
660 /* No consideration for bits 63-32 */
02b20b0b 661
36d89f7d
JP
662 pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
663 i * 4, ch->ctrl_start + 4 * i, i);
1a9fc855 664 n = cx25821_risc_decode(risc);
bb4c9a74 665
1a9fc855
MCC
666 for (j = 1; j < n; j++) {
667 risc = cx_read(ch->ctrl_start + 4 * (i + j));
36d89f7d
JP
668 pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
669 4 * (i + j), i + j, risc, j);
1a9fc855
MCC
670 }
671 }
bb4c9a74 672
36d89f7d
JP
673 pr_warn(" : fifo: 0x%08x -> 0x%x\n",
674 ch->fifo_start, ch->fifo_start + ch->fifo_size);
675 pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
676 ch->ctrl_start, ch->ctrl_start + 6 * 16);
677 pr_warn(" : ptr1_reg: 0x%08x\n",
678 cx_read(ch->ptr1_reg));
679 pr_warn(" : ptr2_reg: 0x%08x\n",
680 cx_read(ch->ptr2_reg));
681 pr_warn(" : cnt1_reg: 0x%08x\n",
682 cx_read(ch->cnt1_reg));
683 pr_warn(" : cnt2_reg: 0x%08x\n",
684 cx_read(ch->cnt2_reg));
1a9fc855
MCC
685
686 for (i = 0; i < 4; i++) {
687 risc = cx_read(ch->cmds_start + 56 + (i * 4));
36d89f7d 688 pr_warn("instruction %d = 0x%x\n", i, risc);
1a9fc855 689 }
bb4c9a74 690
de2c4349 691 /* read data from the first cdt buffer */
1a9fc855 692 risc = cx_read(AUD_A_CDT);
36d89f7d 693 pr_warn("\nread cdt loc=0x%x\n", risc);
1a9fc855
MCC
694 for (i = 0; i < 8; i++) {
695 n = cx_read(risc + i * 4);
36d89f7d 696 pr_cont("0x%x ", n);
bb4c9a74 697 }
36d89f7d 698 pr_cont("\n\n");
1a9fc855
MCC
699
700 value = cx_read(CLK_RST);
de2c4349 701 CX25821_INFO(" CLK_RST = 0x%x\n\n", value);
1a9fc855
MCC
702
703 value = cx_read(PLL_A_POST_STAT_BIST);
de2c4349 704 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x\n\n", value);
1a9fc855 705 value = cx_read(PLL_A_INT_FRAC);
de2c4349 706 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x\n\n", value);
1a9fc855
MCC
707
708 value = cx_read(PLL_B_POST_STAT_BIST);
de2c4349 709 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x\n\n", value);
1a9fc855 710 value = cx_read(PLL_B_INT_FRAC);
de2c4349 711 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x\n\n", value);
1a9fc855
MCC
712
713 value = cx_read(PLL_C_POST_STAT_BIST);
de2c4349 714 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x\n\n", value);
1a9fc855 715 value = cx_read(PLL_C_INT_FRAC);
de2c4349 716 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x\n\n", value);
1a9fc855
MCC
717
718 value = cx_read(PLL_D_POST_STAT_BIST);
de2c4349 719 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x\n\n", value);
1a9fc855 720 value = cx_read(PLL_D_INT_FRAC);
de2c4349 721 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x\n\n", value);
1a9fc855
MCC
722
723 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
de2c4349 724 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x\n\n", value);
02b20b0b 725}
de2c4349 726EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
02b20b0b
MCC
727
728static void cx25821_shutdown(struct cx25821_dev *dev)
729{
1a9fc855 730 int i;
02b20b0b 731
1a9fc855
MCC
732 /* disable RISC controller */
733 cx_write(DEV_CNTRL2, 0);
02b20b0b 734
1a9fc855
MCC
735 /* Disable Video A/B activity */
736 for (i = 0; i < VID_CHANNEL_NUM; i++) {
e4115bb2
RP
737 cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
738 cx_write(dev->channels[i].sram_channels->int_msk, 0);
1a9fc855 739 }
02b20b0b 740
e4115bb2
RP
741 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
742 i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) {
743 cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
744 cx_write(dev->channels[i].sram_channels->int_msk, 0);
1a9fc855 745 }
bb4c9a74 746
1a9fc855
MCC
747 /* Disable Audio activity */
748 cx_write(AUD_INT_DMA_CTL, 0);
02b20b0b 749
1a9fc855
MCC
750 /* Disable Serial port */
751 cx_write(UART_CTL, 0);
02b20b0b 752
1a9fc855
MCC
753 /* Disable Interrupts */
754 cx_write(PCI_INT_MSK, 0);
755 cx_write(AUD_A_INT_MSK, 0);
02b20b0b
MCC
756}
757
1a9fc855
MCC
758void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
759 u32 format)
bb4c9a74 760{
1a9fc855 761 if (channel_select <= 7 && channel_select >= 0) {
3f0bfe5b
LF
762 cx_write(dev->channels[channel_select].sram_channels->pix_frmt,
763 format);
1a9fc855 764 }
ea3f7ac6 765 dev->channels[channel_select].pixel_formats = format;
02b20b0b
MCC
766}
767
1a9fc855 768static void cx25821_set_vip_mode(struct cx25821_dev *dev,
bfef0d35 769 const struct sram_channel *ch)
02b20b0b 770{
1a9fc855
MCC
771 cx_write(ch->pix_frmt, PIXEL_FRMT_422);
772 cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
02b20b0b
MCC
773}
774
775static void cx25821_initialize(struct cx25821_dev *dev)
776{
1a9fc855 777 int i;
bb4c9a74 778
1a9fc855 779 dprintk(1, "%s()\n", __func__);
bb4c9a74 780
1a9fc855
MCC
781 cx25821_shutdown(dev);
782 cx_write(PCI_INT_STAT, 0xffffffff);
02b20b0b 783
1a9fc855 784 for (i = 0; i < VID_CHANNEL_NUM; i++)
e4115bb2 785 cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff);
02b20b0b 786
1a9fc855
MCC
787 cx_write(AUD_A_INT_STAT, 0xffffffff);
788 cx_write(AUD_B_INT_STAT, 0xffffffff);
789 cx_write(AUD_C_INT_STAT, 0xffffffff);
790 cx_write(AUD_D_INT_STAT, 0xffffffff);
791 cx_write(AUD_E_INT_STAT, 0xffffffff);
02b20b0b 792
1a9fc855 793 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
de2c4349
OP
794 cx_write(PAD_CTRL, 0x12); /* for I2C */
795 cx25821_registers_init(dev); /* init Pecos registers */
65155a9b 796 msleep(100);
bb4c9a74 797
1a9fc855 798 for (i = 0; i < VID_CHANNEL_NUM; i++) {
e4115bb2
RP
799 cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
800 cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels,
801 1440, 0);
802 dev->channels[i].pixel_formats = PIXEL_FRMT_422;
bad1f29d 803 dev->channels[i].use_cif_resolution = 0;
1a9fc855 804 }
bb4c9a74 805
de2c4349 806 /* Probably only affect Downstream */
e4115bb2
RP
807 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
808 i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) {
ea3f7ac6 809 dev->channels[i].pixel_formats = PIXEL_FRMT_422;
e4115bb2 810 cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
1a9fc855 811 }
bb4c9a74 812
e4115bb2 813 cx25821_sram_channel_setup_audio(dev,
3f0bfe5b 814 dev->channels[SRAM_CH08].sram_channels, 128, 0);
02b20b0b 815
1a9fc855 816 cx25821_gpio_init(dev);
02b20b0b
MCC
817}
818
f2466d63 819static int cx25821_get_resources(struct cx25821_dev *dev)
02b20b0b 820{
3f0bfe5b
LF
821 if (request_mem_region(pci_resource_start(dev->pci, 0),
822 pci_resource_len(dev->pci, 0), dev->name))
1a9fc855 823 return 0;
02b20b0b 824
36d89f7d 825 pr_err("%s: can't get MMIO memory @ 0x%llx\n",
c14ea5e5 826 dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
02b20b0b 827
1a9fc855 828 return -EBUSY;
02b20b0b
MCC
829}
830
02b20b0b
MCC
831static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
832{
1a9fc855 833 dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
02b20b0b 834
467870ca 835 pr_info("Hardware revision = 0x%02x\n", dev->hwrevision);
02b20b0b
MCC
836}
837
838static void cx25821_iounmap(struct cx25821_dev *dev)
839{
1a9fc855
MCC
840 if (dev == NULL)
841 return;
842
843 /* Releasing IO memory */
844 if (dev->lmmio != NULL) {
1a9fc855
MCC
845 iounmap(dev->lmmio);
846 dev->lmmio = NULL;
847 }
02b20b0b
MCC
848}
849
02b20b0b 850static int cx25821_dev_setup(struct cx25821_dev *dev)
bb4c9a74 851{
a8f35ce3 852 static unsigned int cx25821_devcount;
30fdf035 853 int i;
1a9fc855 854
1a9fc855
MCC
855 mutex_init(&dev->lock);
856
1a9fc855
MCC
857 dev->nr = ++cx25821_devcount;
858 sprintf(dev->name, "cx25821[%d]", dev->nr);
859
67300abd
CIK
860 if (dev->nr >= ARRAY_SIZE(card)) {
861 CX25821_INFO("dev->nr >= %zd", ARRAY_SIZE(card));
862 return -ENODEV;
863 }
1a9fc855 864 if (dev->pci->device != 0x8210) {
36d89f7d
JP
865 pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
866 __func__, dev->pci->device);
b671ae6b 867 return -ENODEV;
1a9fc855 868 }
b671ae6b 869 pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
02b20b0b 870
1a9fc855
MCC
871 /* Apply a sensible clock frequency for the PCIe bridge */
872 dev->clk_freq = 28000000;
f8d7ee70
HV
873 for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
874 dev->channels[i].dev = dev;
875 dev->channels[i].id = i;
e4115bb2 876 dev->channels[i].sram_channels = &cx25821_sram_channels[i];
f8d7ee70 877 }
02b20b0b 878
1a9fc855 879 /* board config */
de2c4349 880 dev->board = 1; /* card[dev->nr]; */
1a9fc855
MCC
881 dev->_max_num_decoders = MAX_DECODERS;
882
883 dev->pci_bus = dev->pci->bus->number;
884 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
885 dev->pci_irqmask = 0x001f00;
886
887 /* External Master 1 Bus */
888 dev->i2c_bus[0].nr = 0;
889 dev->i2c_bus[0].dev = dev;
890 dev->i2c_bus[0].reg_stat = I2C1_STAT;
891 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
892 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
893 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
894 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
895 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
896
f2466d63 897 if (cx25821_get_resources(dev) < 0) {
36d89f7d 898 pr_err("%s: No more PCIe resources for subsystem: %04x:%04x\n",
1a9fc855
MCC
899 dev->name, dev->pci->subsystem_vendor,
900 dev->pci->subsystem_device);
901
902 cx25821_devcount--;
c37c6d21 903 return -EBUSY;
1a9fc855 904 }
bb4c9a74 905
1a9fc855
MCC
906 /* PCIe stuff */
907 dev->base_io_addr = pci_resource_start(dev->pci, 0);
02b20b0b 908
1a9fc855
MCC
909 if (!dev->base_io_addr) {
910 CX25821_ERR("No PCI Memory resources, exiting!\n");
911 return -ENODEV;
912 }
bb4c9a74 913
1a9fc855 914 dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
02b20b0b 915
1a9fc855 916 if (!dev->lmmio) {
3f0bfe5b 917 CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
1a9fc855
MCC
918 cx25821_iounmap(dev);
919 return -ENOMEM;
920 }
921
922 dev->bmmio = (u8 __iomem *) dev->lmmio;
02b20b0b 923
36d89f7d
JP
924 pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
925 dev->name, dev->pci->subsystem_vendor,
926 dev->pci->subsystem_device, cx25821_boards[dev->board].name,
927 dev->board, card[dev->nr] == dev->board ?
928 "insmod option" : "autodetected");
02b20b0b 929
1a9fc855
MCC
930 /* init hardware */
931 cx25821_initialize(dev);
bb4c9a74 932
1a9fc855 933 cx25821_i2c_register(&dev->i2c_bus[0]);
de2c4349
OP
934/* cx25821_i2c_register(&dev->i2c_bus[1]);
935 * cx25821_i2c_register(&dev->i2c_bus[2]); */
02b20b0b 936
e4115bb2 937 if (medusa_video_init(dev) < 0)
36d89f7d 938 CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__);
bb4c9a74 939
e4115bb2 940 cx25821_video_register(dev);
bb4c9a74 941
1a9fc855 942 cx25821_dev_checkrevision(dev);
1a9fc855 943 return 0;
bb4c9a74 944}
02b20b0b 945
02b20b0b
MCC
946void cx25821_dev_unregister(struct cx25821_dev *dev)
947{
1a9fc855 948 int i;
bb4c9a74 949
1a9fc855
MCC
950 if (!dev->base_io_addr)
951 return;
bb4c9a74 952
1a9fc855 953 release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
02b20b0b 954
b6f21dc3 955 for (i = 0; i < MAX_VID_CAP_CHANNEL_NUM - 1; i++) {
31b32073
HV
956 if (i == SRAM_CH08) /* audio channel */
957 continue;
b6f21dc3
HV
958 /*
959 * TODO: enable when video output is properly
960 * supported.
7087d31b
HV
961 if (i == SRAM_CH09 || i == SRAM_CH10)
962 cx25821_free_mem_upstream(&dev->channels[i]);
b6f21dc3 963 */
1a9fc855
MCC
964 cx25821_video_unregister(dev, i);
965 }
bb4c9a74 966
1a9fc855
MCC
967 cx25821_i2c_unregister(&dev->i2c_bus[0]);
968 cx25821_iounmap(dev);
02b20b0b 969}
de2c4349 970EXPORT_SYMBOL(cx25821_dev_unregister);
02b20b0b 971
5ede94c7
HV
972int cx25821_riscmem_alloc(struct pci_dev *pci,
973 struct cx25821_riscmem *risc,
974 unsigned int size)
975{
976 __le32 *cpu;
977 dma_addr_t dma = 0;
978
979 if (NULL != risc->cpu && risc->size < size)
980 pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
981 if (NULL == risc->cpu) {
982 cpu = pci_zalloc_consistent(pci, size, &dma);
983 if (NULL == cpu)
984 return -ENOMEM;
985 risc->cpu = cpu;
986 risc->dma = dma;
987 risc->size = size;
988 }
989 return 0;
990}
991EXPORT_SYMBOL(cx25821_riscmem_alloc);
992
1a9fc855
MCC
993static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
994 unsigned int offset, u32 sync_line,
995 unsigned int bpl, unsigned int padding,
b671ae6b 996 unsigned int lines, bool jump)
02b20b0b 997{
1a9fc855
MCC
998 struct scatterlist *sg;
999 unsigned int line, todo;
1000
b671ae6b
HV
1001 if (jump) {
1002 *(rp++) = cpu_to_le32(RISC_JUMP);
1003 *(rp++) = cpu_to_le32(0);
1004 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1005 }
1006
1a9fc855 1007 /* sync instruction */
de2c4349 1008 if (sync_line != NO_SYNC_LINE)
1a9fc855 1009 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
bb4c9a74 1010
1a9fc855
MCC
1011 /* scan lines */
1012 sg = sglist;
1013 for (line = 0; line < lines; line++) {
1014 while (offset && offset >= sg_dma_len(sg)) {
1015 offset -= sg_dma_len(sg);
872dfcfe 1016 sg = sg_next(sg);
1a9fc855
MCC
1017 }
1018 if (bpl <= sg_dma_len(sg) - offset) {
1019 /* fits into current chunk */
3f0bfe5b
LF
1020 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL |
1021 bpl);
1a9fc855
MCC
1022 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1023 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1024 offset += bpl;
1025 } else {
1026 /* scanline needs to be split */
1027 todo = bpl;
3f0bfe5b 1028 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL |
1a9fc855
MCC
1029 (sg_dma_len(sg) - offset));
1030 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1031 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1032 todo -= (sg_dma_len(sg) - offset);
1033 offset = 0;
872dfcfe 1034 sg = sg_next(sg);
1a9fc855 1035 while (todo > sg_dma_len(sg)) {
3f0bfe5b
LF
1036 *(rp++) = cpu_to_le32(RISC_WRITE |
1037 sg_dma_len(sg));
1a9fc855
MCC
1038 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1039 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1040 todo -= sg_dma_len(sg);
872dfcfe 1041 sg = sg_next(sg);
1a9fc855
MCC
1042 }
1043 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1044 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1045 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1046 offset += todo;
1047 }
1048
1049 offset += padding;
1050 }
02b20b0b 1051
1a9fc855 1052 return rp;
02b20b0b
MCC
1053}
1054
5ede94c7 1055int cx25821_risc_buffer(struct pci_dev *pci, struct cx25821_riscmem *risc,
1a9fc855
MCC
1056 struct scatterlist *sglist, unsigned int top_offset,
1057 unsigned int bottom_offset, unsigned int bpl,
1058 unsigned int padding, unsigned int lines)
02b20b0b 1059{
1a9fc855
MCC
1060 u32 instructions;
1061 u32 fields;
1062 __le32 *rp;
1063 int rc;
1064
1065 fields = 0;
1066 if (UNSET != top_offset)
1067 fields++;
1068 if (UNSET != bottom_offset)
1069 fields++;
1070
1071 /* estimate risc mem: worst case is one write per page border +
b671ae6b 1072 one write per scan line + syncs + jump (all 3 dwords). Padding
1a9fc855
MCC
1073 can cause next bpl to start close to a page border. First DMA
1074 region may be smaller than PAGE_SIZE */
1075 /* write and jump need and extra dword */
3f0bfe5b
LF
1076 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE +
1077 lines);
b671ae6b 1078 instructions += 5;
5ede94c7 1079 rc = cx25821_riscmem_alloc(pci, risc, instructions * 12);
1a9fc855
MCC
1080
1081 if (rc < 0)
1082 return rc;
1083
1084 /* write risc instructions */
1085 rp = risc->cpu;
1086
1087 if (UNSET != top_offset) {
1088 rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
b671ae6b 1089 lines, true);
1a9fc855 1090 }
02b20b0b 1091
1a9fc855
MCC
1092 if (UNSET != bottom_offset) {
1093 rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
b671ae6b 1094 padding, lines, UNSET == top_offset);
bb4c9a74
MCC
1095 }
1096
1a9fc855
MCC
1097 /* save pointer to jmp instruction address */
1098 risc->jmp = rp;
b671ae6b 1099 BUG_ON((risc->jmp - risc->cpu + 3) * sizeof(*risc->cpu) > risc->size);
1a9fc855
MCC
1100
1101 return 0;
1102}
1103
1104static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
1105 unsigned int offset, u32 sync_line,
1106 unsigned int bpl, unsigned int padding,
1107 unsigned int lines, unsigned int lpi)
1108{
1109 struct scatterlist *sg;
1110 unsigned int line, todo, sol;
1111
1112 /* sync instruction */
1113 if (sync_line != NO_SYNC_LINE)
1114 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1115
1116 /* scan lines */
1117 sg = sglist;
1118 for (line = 0; line < lines; line++) {
1119 while (offset && offset >= sg_dma_len(sg)) {
1120 offset -= sg_dma_len(sg);
872dfcfe 1121 sg = sg_next(sg);
1a9fc855
MCC
1122 }
1123
1124 if (lpi && line > 0 && !(line % lpi))
1125 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
1126 else
1127 sol = RISC_SOL;
1128
1129 if (bpl <= sg_dma_len(sg) - offset) {
1130 /* fits into current chunk */
3f0bfe5b
LF
1131 *(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL |
1132 bpl);
1a9fc855
MCC
1133 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1134 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1135 offset += bpl;
1136 } else {
1137 /* scanline needs to be split */
1138 todo = bpl;
1139 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
c14ea5e5 1140 (sg_dma_len(sg) - offset));
1a9fc855
MCC
1141 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1142 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1143 todo -= (sg_dma_len(sg) - offset);
1144 offset = 0;
872dfcfe 1145 sg = sg_next(sg);
1a9fc855
MCC
1146 while (todo > sg_dma_len(sg)) {
1147 *(rp++) = cpu_to_le32(RISC_WRITE |
c14ea5e5 1148 sg_dma_len(sg));
1a9fc855
MCC
1149 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1150 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1151 todo -= sg_dma_len(sg);
872dfcfe 1152 sg = sg_next(sg);
1a9fc855
MCC
1153 }
1154 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1155 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1156 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1157 offset += todo;
1158 }
1159 offset += padding;
bb4c9a74 1160 }
02b20b0b 1161
1a9fc855 1162 return rp;
02b20b0b
MCC
1163}
1164
1165int cx25821_risc_databuffer_audio(struct pci_dev *pci,
5ede94c7 1166 struct cx25821_riscmem *risc,
1a9fc855
MCC
1167 struct scatterlist *sglist,
1168 unsigned int bpl,
1169 unsigned int lines, unsigned int lpi)
02b20b0b 1170{
1a9fc855
MCC
1171 u32 instructions;
1172 __le32 *rp;
1173 int rc;
1174
1175 /* estimate risc mem: worst case is one write per page border +
1176 one write per scan line + syncs + jump (all 2 dwords). Here
1177 there is no padding and no sync. First DMA region may be smaller
1178 than PAGE_SIZE */
1179 /* Jump and write need an extra dword */
1180 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1181 instructions += 1;
1182
5ede94c7 1183 rc = cx25821_riscmem_alloc(pci, risc, instructions * 12);
de2c4349 1184 if (rc < 0)
1a9fc855
MCC
1185 return rc;
1186
1187 /* write risc instructions */
1188 rp = risc->cpu;
1189 rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
1190 lines, lpi);
1191
1192 /* save pointer to jmp instruction address */
1193 risc->jmp = rp;
1194 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1195 return 0;
02b20b0b 1196}
de2c4349 1197EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
02b20b0b 1198
b671ae6b 1199void cx25821_free_buffer(struct cx25821_dev *dev, struct cx25821_buffer *buf)
02b20b0b 1200{
1a9fc855 1201 BUG_ON(in_interrupt());
b671ae6b
HV
1202 if (WARN_ON(buf->risc.size == 0))
1203 return;
1204 pci_free_consistent(dev->pci,
5ede94c7 1205 buf->risc.size, buf->risc.cpu, buf->risc.dma);
b671ae6b 1206 memset(&buf->risc, 0, sizeof(buf->risc));
02b20b0b
MCC
1207}
1208
02b20b0b
MCC
1209static irqreturn_t cx25821_irq(int irq, void *dev_id)
1210{
1a9fc855 1211 struct cx25821_dev *dev = dev_id;
30fdf035 1212 u32 pci_status;
1a9fc855
MCC
1213 u32 vid_status;
1214 int i, handled = 0;
1215 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
02b20b0b 1216
1a9fc855 1217 pci_status = cx_read(PCI_INT_STAT);
02b20b0b 1218
1a9fc855
MCC
1219 if (pci_status == 0)
1220 goto out;
bb4c9a74 1221
1a9fc855
MCC
1222 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1223 if (pci_status & mask[i]) {
e4115bb2
RP
1224 vid_status = cx_read(dev->channels[i].
1225 sram_channels->int_stat);
02b20b0b 1226
1a9fc855 1227 if (vid_status)
3f0bfe5b
LF
1228 handled += cx25821_video_irq(dev, i,
1229 vid_status);
02b20b0b 1230
1a9fc855
MCC
1231 cx_write(PCI_INT_STAT, mask[i]);
1232 }
bb4c9a74 1233 }
bb4c9a74 1234
de2c4349 1235out:
1a9fc855 1236 return IRQ_RETVAL(handled);
02b20b0b
MCC
1237}
1238
1239void cx25821_print_irqbits(char *name, char *tag, char **strings,
bb4c9a74 1240 int len, u32 bits, u32 mask)
02b20b0b 1241{
1a9fc855
MCC
1242 unsigned int i;
1243
36d89f7d 1244 printk(KERN_DEBUG pr_fmt("%s: %s [0x%x]"), name, tag, bits);
1a9fc855
MCC
1245
1246 for (i = 0; i < len; i++) {
1247 if (!(bits & (1 << i)))
1248 continue;
1249 if (strings[i])
36d89f7d 1250 pr_cont(" %s", strings[i]);
1a9fc855 1251 else
36d89f7d 1252 pr_cont(" %d", i);
1a9fc855
MCC
1253 if (!(mask & (1 << i)))
1254 continue;
36d89f7d 1255 pr_cont("*");
1a9fc855 1256 }
36d89f7d 1257 pr_cont("\n");
02b20b0b 1258}
de2c4349 1259EXPORT_SYMBOL(cx25821_print_irqbits);
02b20b0b 1260
1a9fc855 1261struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
02b20b0b 1262{
1a9fc855
MCC
1263 struct cx25821_dev *dev = pci_get_drvdata(pci);
1264 return dev;
02b20b0b 1265}
de2c4349 1266EXPORT_SYMBOL(cx25821_dev_get);
02b20b0b 1267
4c62e976
GKH
1268static int cx25821_initdev(struct pci_dev *pci_dev,
1269 const struct pci_device_id *pci_id)
02b20b0b 1270{
1a9fc855
MCC
1271 struct cx25821_dev *dev;
1272 int err = 0;
bb4c9a74 1273
1a9fc855
MCC
1274 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1275 if (NULL == dev)
1276 return -ENOMEM;
bb4c9a74 1277
1a9fc855
MCC
1278 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
1279 if (err < 0)
1280 goto fail_free;
02b20b0b 1281
1a9fc855
MCC
1282 /* pci init */
1283 dev->pci = pci_dev;
1284 if (pci_enable_device(pci_dev)) {
1285 err = -EIO;
02b20b0b 1286
36d89f7d 1287 pr_info("pci enable failed!\n");
02b20b0b 1288
1a9fc855
MCC
1289 goto fail_unregister_device;
1290 }
02b20b0b 1291
c37c6d21 1292 err = cx25821_dev_setup(dev);
b671ae6b 1293 if (err)
2bc46b3a 1294 goto fail_unregister_pci;
02b20b0b 1295
1a9fc855
MCC
1296 /* print pci info */
1297 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1298 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
36d89f7d
JP
1299 pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
1300 dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1301 dev->pci_lat, (unsigned long long)dev->base_io_addr);
1a9fc855
MCC
1302
1303 pci_set_master(pci_dev);
1a47de6e
CH
1304 err = pci_set_dma_mask(pci_dev, 0xffffffff);
1305 if (err) {
36d89f7d 1306 pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1a9fc855
MCC
1307 err = -EIO;
1308 goto fail_irq;
1309 }
02b20b0b 1310
3f0bfe5b
LF
1311 err = request_irq(pci_dev->irq, cx25821_irq,
1312 IRQF_SHARED, dev->name, dev);
02b20b0b 1313
1a9fc855 1314 if (err < 0) {
36d89f7d 1315 pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
1a9fc855
MCC
1316 goto fail_irq;
1317 }
02b20b0b 1318
1a9fc855 1319 return 0;
02b20b0b 1320
de2c4349 1321fail_irq:
36d89f7d 1322 pr_info("cx25821_initdev() can't get IRQ !\n");
1a9fc855 1323 cx25821_dev_unregister(dev);
bb4c9a74 1324
c37c6d21
KV
1325fail_unregister_pci:
1326 pci_disable_device(pci_dev);
de2c4349 1327fail_unregister_device:
1a9fc855 1328 v4l2_device_unregister(&dev->v4l2_dev);
bb4c9a74 1329
de2c4349 1330fail_free:
1a9fc855
MCC
1331 kfree(dev);
1332 return err;
02b20b0b
MCC
1333}
1334
4c62e976 1335static void cx25821_finidev(struct pci_dev *pci_dev)
02b20b0b 1336{
1a9fc855
MCC
1337 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1338 struct cx25821_dev *dev = get_cx25821(v4l2_dev);
bb4c9a74 1339
1a9fc855
MCC
1340 cx25821_shutdown(dev);
1341 pci_disable_device(pci_dev);
02b20b0b 1342
1a9fc855
MCC
1343 /* unregister stuff */
1344 if (pci_dev->irq)
1345 free_irq(pci_dev->irq, dev);
bb4c9a74 1346
1a9fc855
MCC
1347 cx25821_dev_unregister(dev);
1348 v4l2_device_unregister(v4l2_dev);
1349 kfree(dev);
02b20b0b
MCC
1350}
1351
f1b84d36 1352static const struct pci_device_id cx25821_pci_tbl[] = {
1a9fc855 1353 {
1c2b5520
LF
1354 /* CX25821 Athena */
1355 .vendor = 0x14f1,
1356 .device = 0x8210,
1357 .subvendor = 0x14f1,
1358 .subdevice = 0x0920,
632fba4d
SE
1359 }, {
1360 /* CX25821 No Brand */
1361 .vendor = 0x14f1,
1362 .device = 0x8210,
1363 .subvendor = 0x0000,
1364 .subdevice = 0x0000,
1365 }, {
1c2b5520
LF
1366 /* --- end of list --- */
1367 }
02b20b0b
MCC
1368};
1369
1370MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
1371
1a9fc855
MCC
1372static struct pci_driver cx25821_pci_driver = {
1373 .name = "cx25821",
1374 .id_table = cx25821_pci_tbl,
1375 .probe = cx25821_initdev,
4c62e976 1376 .remove = cx25821_finidev,
02b20b0b
MCC
1377};
1378
64ed2016 1379static int __init cx25821_init(void)
02b20b0b 1380{
d1044776 1381 pr_info("driver loaded\n");
1a9fc855 1382 return pci_register_driver(&cx25821_pci_driver);
02b20b0b
MCC
1383}
1384
64ed2016 1385static void __exit cx25821_fini(void)
02b20b0b 1386{
1a9fc855 1387 pci_unregister_driver(&cx25821_pci_driver);
02b20b0b
MCC
1388}
1389
02b20b0b
MCC
1390module_init(cx25821_init);
1391module_exit(cx25821_fini);