Merge branch 'pmtimer-overflow' into release
[pandora-kernel.git] / drivers / media / dvb / b2c2 / flexcop-pci.c
1 /*
2  * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
3  *
4  * flexcop-pci.c - covers the PCI part including DMA transfers.
5  *
6  * see flexcop.c for copyright information.
7  */
8
9 #define FC_LOG_PREFIX "flexcop-pci"
10 #include "flexcop-common.h"
11
12 static int enable_pid_filtering = 1;
13 module_param(enable_pid_filtering, int, 0444);
14 MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
15
16 static int irq_chk_intv = 100;
17 module_param(irq_chk_intv, int, 0644);
18 MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
19
20 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
21 #define dprintk(level,args...) \
22         do { if ((debug & level)) printk(args); } while (0)
23 #define DEBSTATUS ""
24 #else
25 #define dprintk(level,args...)
26 #define DEBSTATUS " (debugging is not enabled)"
27 #endif
28
29 #define deb_info(args...)  dprintk(0x01,args)
30 #define deb_reg(args...)   dprintk(0x02,args)
31 #define deb_ts(args...)    dprintk(0x04,args)
32 #define deb_irq(args...)   dprintk(0x08,args)
33 #define deb_chk(args...)   dprintk(0x10,args)
34
35 static int debug;
36 module_param(debug, int, 0644);
37 MODULE_PARM_DESC(debug,
38         "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
39          DEBSTATUS);
40
41 #define DRIVER_VERSION "0.1"
42 #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
43 #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
44
45 struct flexcop_pci {
46         struct pci_dev *pdev;
47
48 #define FC_PCI_INIT     0x01
49 #define FC_PCI_DMA_INIT 0x02
50         int init_state;
51
52         void __iomem *io_mem;
53         u32 irq;
54 /* buffersize (at least for DMA1, need to be % 188 == 0,
55  * this logic is required */
56 #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
57 #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
58         struct flexcop_dma dma[2];
59
60         int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
61         u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
62         int count;
63         int count_prev;
64         int stream_problem;
65
66         spinlock_t irq_lock;
67
68         unsigned long last_irq;
69
70         struct delayed_work irq_check_work;
71
72         struct flexcop_device *fc_dev;
73 };
74
75 static int lastwreg,lastwval,lastrreg,lastrval;
76
77 static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
78 {
79         struct flexcop_pci *fc_pci = fc->bus_specific;
80         flexcop_ibi_value v;
81         v.raw = readl(fc_pci->io_mem + r);
82
83         if (lastrreg != r || lastrval != v.raw) {
84                 lastrreg = r; lastrval = v.raw;
85                 deb_reg("new rd: %3x: %08x\n",r,v.raw);
86         }
87
88         return v;
89 }
90
91 static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
92 {
93         struct flexcop_pci *fc_pci = fc->bus_specific;
94
95         if (lastwreg != r || lastwval != v.raw) {
96                 lastwreg = r; lastwval = v.raw;
97                 deb_reg("new wr: %3x: %08x\n",r,v.raw);
98         }
99
100         writel(v.raw, fc_pci->io_mem + r);
101         return 0;
102 }
103
104 static void flexcop_pci_irq_check_work(struct work_struct *work)
105 {
106         struct flexcop_pci *fc_pci =
107                 container_of(work, struct flexcop_pci, irq_check_work.work);
108         struct flexcop_device *fc = fc_pci->fc_dev;
109
110         if (fc->feedcount) {
111
112                 if (fc_pci->count == fc_pci->count_prev) {
113                         deb_chk("no IRQ since the last check\n");
114                         if (fc_pci->stream_problem++ == 3) {
115                                 struct dvb_demux_feed *feed;
116
117                                 spin_lock_irq(&fc->demux.lock);
118                                 list_for_each_entry(feed, &fc->demux.feed_list,
119                                         list_head) {
120                                         flexcop_pid_feed_control(fc, feed, 0);
121                                 }
122
123                                 list_for_each_entry(feed, &fc->demux.feed_list,
124                                         list_head) {
125                                         flexcop_pid_feed_control(fc, feed, 1);
126                                 }
127                                 spin_unlock_irq(&fc->demux.lock);
128
129                                 fc_pci->stream_problem = 0;
130                         }
131                 } else {
132                         fc_pci->stream_problem = 0;
133                         fc_pci->count_prev = fc_pci->count;
134                 }
135         }
136
137         schedule_delayed_work(&fc_pci->irq_check_work,
138                         msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
139 }
140
141 /* When PID filtering is turned on, we use the timer IRQ, because small amounts
142  * of data need to be passed to the user space instantly as well. When PID
143  * filtering is turned off, we use the page-change-IRQ */
144 static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
145 {
146         struct flexcop_pci *fc_pci = dev_id;
147         struct flexcop_device *fc = fc_pci->fc_dev;
148         unsigned long flags;
149         flexcop_ibi_value v;
150         irqreturn_t ret = IRQ_HANDLED;
151
152         spin_lock_irqsave(&fc_pci->irq_lock,flags);
153
154         v = fc->read_ibi_reg(fc,irq_20c);
155
156    /* errors */
157         if (v.irq_20c.Data_receiver_error)
158                 deb_chk("data receiver error\n");
159         if (v.irq_20c.Continuity_error_flag)
160                 deb_chk("Contunuity error flag is set\n");
161         if (v.irq_20c.LLC_SNAP_FLAG_set)
162                 deb_chk("LLC_SNAP_FLAG_set is set\n");
163         if (v.irq_20c.Transport_Error)
164                 deb_chk("Transport error\n");
165
166         if ((fc_pci->count % 1000) == 0)
167                 deb_chk("%d valid irq took place so far\n",fc_pci->count);
168
169         if (v.irq_20c.DMA1_IRQ_Status == 1) {
170                 if (fc_pci->active_dma1_addr == 0)
171                         flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
172                 else
173                         flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
174
175                 deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
176                 fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
177         } else if (v.irq_20c.DMA1_Timer_Status == 1) {
178                 /* for the timer IRQ we only can use buffer dmx feeding, because we don't have
179                  * complete TS packets when reading from the DMA memory */
180                 dma_addr_t cur_addr =
181                         fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
182                 u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
183
184                 deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
185                                 jiffies_to_usecs(jiffies - fc_pci->last_irq),
186                                 v.raw, (unsigned long long)cur_addr, cur_pos,
187                                 fc_pci->last_dma1_cur_pos);
188                 fc_pci->last_irq = jiffies;
189
190                 /* buffer end was reached, restarted from the beginning
191                  * pass the data from last_cur_pos to the buffer end to the demux
192                  */
193                 if (cur_pos < fc_pci->last_dma1_cur_pos) {
194                         deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
195                         flexcop_pass_dmx_data(fc_pci->fc_dev,
196                                         fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
197                                         (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
198                         fc_pci->last_dma1_cur_pos = 0;
199                 }
200
201                 if (cur_pos > fc_pci->last_dma1_cur_pos) {
202                         deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
203                         flexcop_pass_dmx_data(fc_pci->fc_dev,
204                                         fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
205                                         cur_pos - fc_pci->last_dma1_cur_pos);
206                 }
207                 deb_irq("\n");
208
209                 fc_pci->last_dma1_cur_pos = cur_pos;
210                 fc_pci->count++;
211         } else {
212                 deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
213                 ret = IRQ_NONE;
214         }
215
216         spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
217
218         return ret;
219 }
220
221 static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
222 {
223         struct flexcop_pci *fc_pci = fc->bus_specific;
224         if (onoff) {
225                 flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
226                 flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
227
228                 flexcop_dma_config_timer(fc,FC_DMA_1,0);
229
230                 flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
231                 deb_irq("DMA xfer enabled\n");
232
233                 fc_pci->last_dma1_cur_pos = 0;
234                 flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
235                 deb_irq("IRQ enabled\n");
236
237                 fc_pci->count_prev = fc_pci->count;
238
239 //              fc_pci->active_dma1_addr = 0;
240 //              flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
241
242         } else {
243                 flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
244                 deb_irq("IRQ disabled\n");
245
246 //              flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
247
248                 flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
249                 deb_irq("DMA xfer disabled\n");
250         }
251
252         return 0;
253 }
254
255 static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
256 {
257         int ret;
258         if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
259                 return ret;
260
261         if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
262                 flexcop_dma_free(&fc_pci->dma[0]);
263                 return ret;
264         }
265
266         flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
267         flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO   | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
268
269         fc_pci->init_state |= FC_PCI_DMA_INIT;
270
271         return ret;
272 }
273
274 static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
275 {
276         if (fc_pci->init_state & FC_PCI_DMA_INIT) {
277                 flexcop_dma_free(&fc_pci->dma[0]);
278                 flexcop_dma_free(&fc_pci->dma[1]);
279         }
280         fc_pci->init_state &= ~FC_PCI_DMA_INIT;
281 }
282
283 static int flexcop_pci_init(struct flexcop_pci *fc_pci)
284 {
285         int ret;
286         u8 card_rev;
287
288         pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev);
289         info("card revision %x", card_rev);
290
291         if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
292                 return ret;
293
294         pci_set_master(fc_pci->pdev);
295
296         /* enable interrupts */
297         // pci_write_config_dword(pdev, 0x6c, 0x8000);
298
299         if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
300                 goto err_pci_disable_device;
301
302         fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);
303
304         if (!fc_pci->io_mem) {
305                 err("cannot map io memory\n");
306                 ret = -EIO;
307                 goto err_pci_release_regions;
308         }
309
310         pci_set_drvdata(fc_pci->pdev, fc_pci);
311         spin_lock_init(&fc_pci->irq_lock);
312         if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
313                                         IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
314                 goto err_pci_iounmap;
315
316         fc_pci->init_state |= FC_PCI_INIT;
317         return ret;
318
319 err_pci_iounmap:
320         pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
321         pci_set_drvdata(fc_pci->pdev, NULL);
322 err_pci_release_regions:
323         pci_release_regions(fc_pci->pdev);
324 err_pci_disable_device:
325         pci_disable_device(fc_pci->pdev);
326         return ret;
327 }
328
329 static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
330 {
331         if (fc_pci->init_state & FC_PCI_INIT) {
332                 free_irq(fc_pci->pdev->irq, fc_pci);
333                 pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
334                 pci_set_drvdata(fc_pci->pdev, NULL);
335                 pci_release_regions(fc_pci->pdev);
336                 pci_disable_device(fc_pci->pdev);
337         }
338         fc_pci->init_state &= ~FC_PCI_INIT;
339 }
340
341
342 static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
343 {
344         struct flexcop_device *fc;
345         struct flexcop_pci *fc_pci;
346         int ret = -ENOMEM;
347
348         if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) {
349                 err("out of memory\n");
350                 return -ENOMEM;
351         }
352
353 /* general flexcop init */
354         fc_pci = fc->bus_specific;
355         fc_pci->fc_dev = fc;
356
357         fc->read_ibi_reg = flexcop_pci_read_ibi_reg;
358         fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
359         fc->i2c_request = flexcop_i2c_request;
360         fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
361
362         fc->stream_control = flexcop_pci_stream_control;
363
364         if (enable_pid_filtering)
365                 info("will use the HW PID filter.");
366         else
367                 info("will pass the complete TS to the demuxer.");
368
369         fc->pid_filtering = enable_pid_filtering;
370         fc->bus_type = FC_PCI;
371
372         fc->dev = &pdev->dev;
373         fc->owner = THIS_MODULE;
374
375 /* bus specific part */
376         fc_pci->pdev = pdev;
377         if ((ret = flexcop_pci_init(fc_pci)) != 0)
378                 goto err_kfree;
379
380 /* init flexcop */
381         if ((ret = flexcop_device_initialize(fc)) != 0)
382                 goto err_pci_exit;
383
384 /* init dma */
385         if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
386                 goto err_fc_exit;
387
388         INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
389
390                 if (irq_chk_intv > 0)
391                         schedule_delayed_work(&fc_pci->irq_check_work,
392                 msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
393
394         return ret;
395
396 err_fc_exit:
397         flexcop_device_exit(fc);
398 err_pci_exit:
399         flexcop_pci_exit(fc_pci);
400 err_kfree:
401         flexcop_device_kfree(fc);
402         return ret;
403 }
404
405 /* in theory every _exit function should be called exactly two times,
406  * here and in the bail-out-part of the _init-function
407  */
408 static void flexcop_pci_remove(struct pci_dev *pdev)
409 {
410         struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
411
412         if (irq_chk_intv > 0)
413                 cancel_delayed_work(&fc_pci->irq_check_work);
414
415         flexcop_pci_dma_exit(fc_pci);
416         flexcop_device_exit(fc_pci->fc_dev);
417         flexcop_pci_exit(fc_pci);
418         flexcop_device_kfree(fc_pci->fc_dev);
419 }
420
421 static struct pci_device_id flexcop_pci_tbl[] = {
422         { PCI_DEVICE(0x13d0, 0x2103) },
423 /*      { PCI_DEVICE(0x13d0, 0x2200) }, ? */
424         { },
425 };
426
427 MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
428
429 static struct pci_driver flexcop_pci_driver = {
430         .name     = "b2c2_flexcop_pci",
431         .id_table = flexcop_pci_tbl,
432         .probe    = flexcop_pci_probe,
433         .remove   = flexcop_pci_remove,
434 };
435
436 static int __init flexcop_pci_module_init(void)
437 {
438         return pci_register_driver(&flexcop_pci_driver);
439 }
440
441 static void __exit flexcop_pci_module_exit(void)
442 {
443         pci_unregister_driver(&flexcop_pci_driver);
444 }
445
446 module_init(flexcop_pci_module_init);
447 module_exit(flexcop_pci_module_exit);
448
449 MODULE_AUTHOR(DRIVER_AUTHOR);
450 MODULE_DESCRIPTION(DRIVER_NAME);
451 MODULE_LICENSE("GPL");