Subversion Repositories shark

Rev

Rev 614 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
428 giacomo 1
/*
2
    bttv-risc.c  --  interfaces to other kernel modules
3
 
4
    bttv risc code handling
5
        - memory management
6
        - generation
7
 
8
    (c) 2000 Gerd Knorr <kraxel@bytesex.org>
9
 
10
    This program is free software; you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation; either version 2 of the License, or
13
    (at your option) any later version.
14
 
15
    This program is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
 
20
    You should have received a copy of the GNU General Public License
21
    along with this program; if not, write to the Free Software
22
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
 
24
*/
25
 
26
#include <linuxcomp.h>
27
 
28
#include <linux/module.h>
29
#include <linux/init.h>
30
#include <linux/pci.h>
31
#include <linux/vmalloc.h>
32
#include <linux/interrupt.h>
33
#include <asm/page.h>
34
#include <asm/pgtable.h>
35
 
36
#include "drivers/bttvp.h"
37
 
38
#define VCR_HACK_LINES 4
39
 
40
/* ---------------------------------------------------------- */
41
/* risc code generators                                       */
42
 
43
int
44
bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
45
                 struct scatterlist *sglist,
46
                 unsigned int offset, unsigned int bpl,
47
                 unsigned int padding, unsigned int lines)
48
{
49
        u32 instructions,line,todo;
50
        struct scatterlist *sg;
51
        u32 *rp;
52
        int rc;
53
 
54
        /* estimate risc mem: worst case is one write per page border +
55
           one write per scan line + sync + jump (all 2 dwords) */
56
        instructions  = (bpl * lines) / PAGE_SIZE + lines;
57
        instructions += 2;
58
        if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0)
59
                return rc;
60
 
61
        /* sync instruction */
62
        rp = risc->cpu;
63
        *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
64
        *(rp++) = cpu_to_le32(0);
65
 
66
        /* scan lines */
67
        sg = sglist;
68
        for (line = 0; line < lines; line++) {
69
                if ((btv->opt_vcr_hack) &&
70
                    (line >= (lines - VCR_HACK_LINES)))
71
                        continue;
72
                while (offset >= sg_dma_len(sg)) {
73
                        offset -= sg_dma_len(sg);
74
                        sg++;
75
                }
76
                if (bpl <= sg_dma_len(sg)-offset) {
77
                        /* fits into current chunk */
78
                        *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
79
                                            BT848_RISC_EOL|bpl);
80
                        *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
81
                        offset+=bpl;
82
                } else {
83
                        /* scanline needs to be splitted */
84
                        todo = bpl;
85
                        *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
86
                                            (sg_dma_len(sg)-offset));
87
                        *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
88
                        todo -= (sg_dma_len(sg)-offset);
89
                        offset = 0;
90
                        sg++;
91
                        while (todo > sg_dma_len(sg)) {
92
                                *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
93
                                                    sg_dma_len(sg));
94
                                *(rp++)=cpu_to_le32(sg_dma_address(sg));
95
                                todo -= sg_dma_len(sg);
96
                                sg++;
97
                        }
98
                        *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
99
                                            todo);
100
                        *(rp++)=cpu_to_le32(sg_dma_address(sg));
101
                        offset += todo;
102
                }
103
                offset += padding;
104
        }
105
        dprintk("bttv%d: risc planar: %d sglist elems\n", btv->nr, (int)(sg-sglist));
106
 
107
        /* save pointer to jmp instruction address */
108
        risc->jmp = rp;
109
        return 0;
110
}
111
 
112
int
113
bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
114
                 struct scatterlist *sglist,
115
                 unsigned int yoffset,  unsigned int ybpl,
116
                 unsigned int ypadding, unsigned int ylines,
117
                 unsigned int uoffset,  unsigned int voffset,
118
                 unsigned int hshift,   unsigned int vshift,
119
                 unsigned int cpadding)
120
{
121
        unsigned int instructions,line,todo,ylen,chroma;
122
        u32 *rp,ri;
123
        struct scatterlist *ysg;
124
        struct scatterlist *usg;
125
        struct scatterlist *vsg;
126
        int rc;
127
 
128
        /* estimate risc mem: worst case is one write per page border +
129
           one write per scan line (5 dwords)
130
           plus sync + jump (2 dwords) */
131
        instructions  = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
132
        instructions += 2;
133
        if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*4*5)) < 0)
134
                return rc;
135
 
136
        /* sync instruction */
137
        rp = risc->cpu;
138
        *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
139
        *(rp++) = cpu_to_le32(0);
140
 
141
        /* scan lines */
142
        ysg = sglist;
143
        usg = sglist;
144
        vsg = sglist;
145
        for (line = 0; line < ylines; line++) {
146
                if ((btv->opt_vcr_hack) &&
147
                    (line >= (ylines - VCR_HACK_LINES)))
148
                        continue;
149
                switch (vshift) {
150
                case 0:  chroma = 1;           break;
151
                case 1:  chroma = !(line & 1); break;
152
                case 2:  chroma = !(line & 3); break;
153
                default: chroma = 0;
154
                }
155
                for (todo = ybpl; todo > 0; todo -= ylen) {
156
                        /* go to next sg entry if needed */
157
                        while (yoffset >= sg_dma_len(ysg)) {
158
                                yoffset -= sg_dma_len(ysg);
159
                                ysg++;
160
                        }
161
                        while (uoffset >= sg_dma_len(usg)) {
162
                                uoffset -= sg_dma_len(usg);
163
                                usg++;
164
                        }
165
                        while (voffset >= sg_dma_len(vsg)) {
166
                                voffset -= sg_dma_len(vsg);
167
                                vsg++;
168
                        }
169
 
170
                        /* calculate max number of bytes we can write */
171
                        ylen = todo;
172
                        if (yoffset + ylen > sg_dma_len(ysg))
173
                                ylen = sg_dma_len(ysg) - yoffset;
174
                        if (chroma) {
175
                                if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
176
                                        ylen = (sg_dma_len(usg) - uoffset) << hshift;
177
                                if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
178
                                        ylen = (sg_dma_len(vsg) - voffset) << hshift;
179
                                ri = BT848_RISC_WRITE123;
180
                        } else {
181
                                ri = BT848_RISC_WRITE1S23;
182
                        }
183
                        if (ybpl == todo)
184
                                ri |= BT848_RISC_SOL;
185
                        if (ylen == todo)
186
                                ri |= BT848_RISC_EOL;
187
 
188
                        /* write risc instruction */
189
                        *(rp++)=cpu_to_le32(ri | ylen);
190
                        *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
191
                                            (ylen >> hshift));
192
                        *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
193
                        yoffset += ylen;
194
                        if (chroma) {
195
                                *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
196
                                uoffset += ylen >> hshift;
197
                                *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
198
                                voffset += ylen >> hshift;
199
                        }
200
                }
201
                yoffset += ypadding;
202
                if (chroma) {
203
                        uoffset += cpadding;
204
                        voffset += cpadding;
205
                }
206
        }
207
 
208
        /* save pointer to jmp instruction address */
209
        risc->jmp = rp;
210
        return 0;
211
}
212
 
213
int
214
bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
215
                  const struct bttv_format *fmt, struct bttv_overlay *ov,
216
                  int skip_even, int skip_odd)
217
{
218
        int instructions,rc,line,maxy,start,end,skip,nskips;
219
        struct btcx_skiplist *skips;
220
        u32 *rp,ri,ra;
221
        u32 addr;
222
 
223
        /* skip list for window clipping */
224
        if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
225
                return -ENOMEM;
226
 
227
        /* estimate risc mem: worst case is (clip+1) * lines instructions
228
           + sync + jump (all 2 dwords) */
229
        instructions  = (ov->nclips + 1) *
230
                ((skip_even || skip_odd) ? ov->w.height>>1 :  ov->w.height);
231
        instructions += 2;
232
        if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0) {
233
                kfree(skips);
234
                return rc;
235
        }
236
 
237
        /* sync instruction */
238
        rp = risc->cpu;
239
        *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
240
        *(rp++) = cpu_to_le32(0);
241
 
242
        addr  = (unsigned long)btv->fbuf.base;
243
        addr += btv->fbuf.fmt.bytesperline * ov->w.top;
244
        addr += (fmt->depth >> 3)          * ov->w.left;
245
 
246
        /* scan lines */
247
        for (maxy = -1, line = 0; line < ov->w.height;
248
             line++, addr += btv->fbuf.fmt.bytesperline) {
249
                if ((btv->opt_vcr_hack) &&
250
                     (line >= (ov->w.height - VCR_HACK_LINES)))
251
                        continue;
252
                if ((line%2) == 0  &&  skip_even)
253
                        continue;
254
                if ((line%2) == 1  &&  skip_odd)
255
                if ((line%2) == 0  &&  skip_even)
256
                        continue;
257
                if ((line%2) == 1  &&  skip_odd)
258
                        continue;
259
 
260
                /* calculate clipping */
261
                if (line > maxy)
262
                        btcx_calc_skips(line, ov->w.width, &maxy,
263
                                        skips, &nskips, ov->clips, ov->nclips);
264
 
265
                /* write out risc code */
266
                for (start = 0, skip = 0; start < ov->w.width; start = end) {
267
                        if (skip >= nskips) {
268
                                ri  = BT848_RISC_WRITE;
269
                                end = ov->w.width;
270
                        } else if (start < skips[skip].start) {
271
                                ri  = BT848_RISC_WRITE;
272
                                end = skips[skip].start;
273
                        } else {
274
                                ri  = BT848_RISC_SKIP;
275
                                end = skips[skip].end;
276
                                skip++;
277
                        }
278
                        if (BT848_RISC_WRITE == ri)
279
                                ra = addr + (fmt->depth>>3)*start;
280
                        else
281
                                ra = 0;
282
 
283
                        if (0 == start)
284
                                ri |= BT848_RISC_SOL;
285
                        if (ov->w.width == end)
286
                                ri |= BT848_RISC_EOL;
287
                        ri |= (fmt->depth>>3) * (end-start);
288
 
289
                        *(rp++)=cpu_to_le32(ri);
290
                        if (0 != ra)
291
                                *(rp++)=cpu_to_le32(ra);
292
                }
293
        }
294
 
295
        /* save pointer to jmp instruction address */
296
        risc->jmp = rp;
297
        kfree(skips);
298
        return 0;
299
}
300
 
301
/* ---------------------------------------------------------- */
302
 
303
void
304
bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
305
              int width, int height, int interleaved, int norm)
306
{
307
        const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
308
        u32 xsf, sr;
309
        int vdelay;
310
 
311
        int swidth       = tvnorm->swidth;
312
        int totalwidth   = tvnorm->totalwidth;
313
        int scaledtwidth = tvnorm->scaledtwidth;
314
 
315
        if (bttv_tvcards[btv->type].muxsel[btv->input] < 0) {
316
                swidth       = 720;
317
                totalwidth   = 858;
318
                scaledtwidth = 858;
319
        }
320
 
321
        vdelay = tvnorm->vdelay;
322
#if 0 /* FIXME */
323
        if (vdelay < btv->vbi.lines*2)
324
                vdelay = btv->vbi.lines*2;
325
#endif
326
 
327
        xsf = (width*scaledtwidth)/swidth;
328
        geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
329
        geo->hdelay =  tvnorm->hdelayx1;
330
        geo->hdelay =  (geo->hdelay*width)/swidth;
331
        geo->hdelay &= 0x3fe;
332
        sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
333
        geo->vscale =  (0x10000UL-sr) & 0x1fff;
334
        geo->crop   =  ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
335
                ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
336
        geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
337
        geo->vdelay  =  vdelay;
338
        geo->width   =  width;
339
        geo->sheight =  tvnorm->sheight;
340
        geo->vtotal  =  tvnorm->vtotal;
341
 
342
        if (btv->opt_combfilter) {
343
                geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
344
                geo->comb = (width < 769) ? 1 : 0;
345
        } else {
346
                geo->vtc  = 0;
347
                geo->comb = 0;
348
        }
349
}
350
 
351
void
352
bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
353
{
354
        int off = odd ? 0x80 : 0x00;
355
 
356
        if (geo->comb)
357
                btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
358
        else
359
                btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
360
 
361
        btwrite(geo->vtc,             BT848_E_VTC+off);
362
        btwrite(geo->hscale >> 8,     BT848_E_HSCALE_HI+off);
363
        btwrite(geo->hscale & 0xff,   BT848_E_HSCALE_LO+off);
364
        btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
365
        btwrite(geo->vscale & 0xff,   BT848_E_VSCALE_LO+off);
366
        btwrite(geo->width & 0xff,    BT848_E_HACTIVE_LO+off);
367
        btwrite(geo->hdelay & 0xff,   BT848_E_HDELAY_LO+off);
368
        btwrite(geo->sheight & 0xff,  BT848_E_VACTIVE_LO+off);
369
        btwrite(geo->vdelay & 0xff,   BT848_E_VDELAY_LO+off);
370
        btwrite(geo->crop,            BT848_E_CROP+off);
371
        btwrite(geo->vtotal>>8,       BT848_VTOTAL_HI);
372
        btwrite(geo->vtotal & 0xff,   BT848_VTOTAL_LO);
373
}
374
 
375
/* ---------------------------------------------------------- */
376
/* risc group / risc main loop / dma management               */
377
 
378
void
379
bttv_set_dma(struct bttv *btv, int override, int irqflags)
380
{
381
        unsigned long cmd;
382
        int capctl;
383
 
384
        btv->cap_ctl = 0;
385
        if (NULL != btv->curr.top)      btv->cap_ctl |= 0x02;
386
        if (NULL != btv->curr.bottom)   btv->cap_ctl |= 0x01;
387
        if (NULL != btv->curr.vbi)      btv->cap_ctl |= 0x0c;
388
 
389
        capctl  = 0;
390
        capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;  /* capture  */
391
        capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00;  /* vbi data */
392
        capctl |= override;
393
 
394
        d2printk(KERN_DEBUG
395
                 "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
396
                 btv->nr,capctl,irqflags,
397
                 btv->curr.vbi     ? (unsigned long long)btv->curr.vbi->top.dma        : 0,
398
                 btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
399
                 btv->curr.vbi     ? (unsigned long long)btv->curr.vbi->bottom.dma     : 0,
400
                 btv->curr.bottom  ? (unsigned long long)btv->curr.bottom->bottom.dma  : 0);
401
 
402
        cmd = BT848_RISC_JUMP;
403
        if (irqflags) {
404
                cmd |= BT848_RISC_IRQ;
405
                cmd |= (irqflags  & 0x0f) << 16;
406
                cmd |= (~irqflags & 0x0f) << 20;
621 giacomo 407
                //mod_timer(&btv->timeout, jiffies26+BTTV_TIMEOUT);
428 giacomo 408
        } else {
621 giacomo 409
                //del_timer(&btv->timeout);
428 giacomo 410
        }
411
        btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
412
 
413
        btaor(capctl, ~0x0f, BT848_CAP_CTL);
414
        if (capctl) {
415
                if (btv->dma_on)
416
                        return;
417
                btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
418
                btor(3, BT848_GPIO_DMA_CTL);
419
                btv->dma_on = 1;
420
        } else {
421
                if (!btv->dma_on)
422
                        return;
423
                btand(~3, BT848_GPIO_DMA_CTL);
424
                btv->dma_on = 0;
425
        }
426
        return;
427
}
428
 
429
int
430
bttv_risc_init_main(struct bttv *btv)
431
{
432
        int rc;
433
 
434
        if ((rc = btcx_riscmem_alloc(btv->dev,&btv->main,PAGE_SIZE)) < 0)
435
                return rc;
436
        dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
437
                btv->nr,(unsigned long long)btv->main.dma);
438
 
439
        btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
440
                                       BT848_FIFO_STATUS_VRE);
441
        btv->main.cpu[1] = cpu_to_le32(0);
442
        btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
443
        btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
444
 
445
        /* top field */
446
        btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
447
        btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
448
        btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
449
        btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
450
 
451
        btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
452
                                       BT848_FIFO_STATUS_VRO);
453
        btv->main.cpu[9] = cpu_to_le32(0);
454
 
455
        /* bottom field */
456
        btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
457
        btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
458
        btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
459
        btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
460
 
461
        /* jump back to top field */
462
        btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
463
        btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
464
 
465
        return 0;
466
}
467
 
468
int
469
bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
470
               int irqflags)
471
{
472
        unsigned long cmd;
473
        unsigned long next = btv->main.dma + ((slot+2) << 2);
474
 
475
        if (NULL == risc) {
476
                d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
477
                         btv->nr,risc,slot);
478
                btv->main.cpu[slot+1] = cpu_to_le32(next);
479
        } else {
480
                d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
481
                         btv->nr,risc,slot,(unsigned long long)risc->dma,irqflags);
482
                cmd = BT848_RISC_JUMP;
483
                if (irqflags) {
484
                        cmd |= BT848_RISC_IRQ;
485
                        cmd |= (irqflags  & 0x0f) << 16;
486
                        cmd |= (~irqflags & 0x0f) << 20;
487
                }
488
                risc->jmp[0] = cpu_to_le32(cmd);
489
                risc->jmp[1] = cpu_to_le32(next);
490
                btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
491
        }
492
        return 0;
493
}
494
 
495
void
496
bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
497
{
614 giacomo 498
        //if (in_interrupt())
499
        //      BUG();
621 giacomo 500
        //videobuf_waiton(&buf->vb,0,0);
516 giacomo 501
        //videobuf_dma_pci_unmap(btv->dev, &buf->vb.dma);
502
        //videobuf_dma_free(&buf->vb.dma);
428 giacomo 503
        btcx_riscmem_free(btv->dev,&buf->bottom);
504
        btcx_riscmem_free(btv->dev,&buf->top);
505
        buf->vb.state = STATE_NEEDS_INIT;
506
}
507
 
508
int
509
bttv_buffer_set_activate(struct bttv *btv,
510
                         struct bttv_buffer_set *set)
511
{
512
        /* vbi capture */
513
        if (set->vbi) {
514
                set->vbi->vb.state = STATE_ACTIVE;
515
                list_del(&set->vbi->vb.queue);
516
                bttv_risc_hook(btv, RISC_SLOT_O_VBI, &set->vbi->top,    0);
517
                bttv_risc_hook(btv, RISC_SLOT_E_VBI, &set->vbi->bottom, 0);
518
        } else {
519
                bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
520
                bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
521
        }
522
 
523
        /* video capture */
524
        if (NULL != set->top  &&  NULL != set->bottom) {
525
                if (set->top == set->bottom) {
526
                        set->top->vb.state    = STATE_ACTIVE;
527
                        if (set->top->vb.queue.next)
528
                                list_del(&set->top->vb.queue);
529
                } else {
530
                        set->top->vb.state    = STATE_ACTIVE;
531
                        set->bottom->vb.state = STATE_ACTIVE;
532
                        if (set->top->vb.queue.next)
533
                                list_del(&set->top->vb.queue);
534
                        if (set->bottom->vb.queue.next)
535
                                list_del(&set->bottom->vb.queue);
536
                }
537
                bttv_apply_geo(btv, &set->top->geo, 1);
538
                bttv_apply_geo(btv, &set->bottom->geo,0);
539
                bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, set->topirq);
540
                bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
541
                btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
542
                      ~0xff, BT848_COLOR_FMT);
543
                btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
544
                      ~0x0f, BT848_COLOR_CTL);
545
        } else if (NULL != set->top) {
546
                set->top->vb.state  = STATE_ACTIVE;
547
                if (set->top->vb.queue.next)
548
                        list_del(&set->top->vb.queue);
549
                bttv_apply_geo(btv, &set->top->geo,1);
550
                bttv_apply_geo(btv, &set->top->geo,0);
551
                bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 0);
552
                bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
553
                btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
554
                btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
555
        } else if (NULL != set->bottom) {
556
                set->bottom->vb.state = STATE_ACTIVE;
557
                if (set->bottom->vb.queue.next)
558
                        list_del(&set->bottom->vb.queue);
559
                bttv_apply_geo(btv, &set->bottom->geo,1);
560
                bttv_apply_geo(btv, &set->bottom->geo,0);
561
                bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL,                 0);
562
                bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
563
                btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
564
                btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
565
        } else {
566
                bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
567
                bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
568
        }
569
        return 0;
570
}
571
 
572
/* ---------------------------------------------------------- */
573
 
574
/* calculate geometry, build risc code */
575
int
576
bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
577
{
578
        const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
579
 
516 giacomo 580
        //dprintk(KERN_DEBUG
581
        //      "bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
582
        //      btv->nr, v4l2_field_names[buf->vb.field],
583
        //      buf->fmt->name, buf->vb.width, buf->vb.height);
428 giacomo 584
 
585
        /* packed pixel modes */
586
        if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
587
                int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
588
                int bpf = bpl * (buf->vb.height >> 1);
589
 
590
                bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
591
                              V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
592
 
593
                switch (buf->vb.field) {
594
                case V4L2_FIELD_TOP:
595
                        bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
596
                                         0,bpl,0,buf->vb.height);
597
                        break;
598
                case V4L2_FIELD_BOTTOM:
599
                        bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
600
                                         0,bpl,0,buf->vb.height);
601
                        break;
602
                case V4L2_FIELD_INTERLACED:
603
                        bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
604
                                         0,bpl,bpl,buf->vb.height >> 1);
605
                        bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
606
                                         bpl,bpl,bpl,buf->vb.height >> 1);
607
                        break;
608
                case V4L2_FIELD_SEQ_TB:
609
                        bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
610
                                         0,bpl,0,buf->vb.height >> 1);
611
                        bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
612
                                         bpf,bpl,0,buf->vb.height >> 1);
613
                        break;
614
                default:
615
                        BUG();
616
                }
617
        }
618
 
619
        /* planar modes */
620
        if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
621
                int uoffset, voffset;
622
                int ypadding, cpadding, lines;
623
 
624
                /* calculate chroma offsets */
625
                uoffset = buf->vb.width * buf->vb.height;
626
                voffset = buf->vb.width * buf->vb.height;
627
                if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
628
                        /* Y-Cr-Cb plane order */
629
                        uoffset >>= buf->fmt->hshift;
630
                        uoffset >>= buf->fmt->vshift;
631
                        uoffset  += voffset;
632
                } else {
633
                        /* Y-Cb-Cr plane order */
634
                        voffset >>= buf->fmt->hshift;
635
                        voffset >>= buf->fmt->vshift;
636
                        voffset  += uoffset;
637
                }
638
 
639
                switch (buf->vb.field) {
640
                case V4L2_FIELD_TOP:
641
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
642
                                      buf->vb.height,0,buf->tvnorm);
643
                        bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
644
                                         0,buf->vb.width,0,buf->vb.height,
645
                                         uoffset,voffset,buf->fmt->hshift,
646
                                         buf->fmt->vshift,0);
647
                        break;
648
                case V4L2_FIELD_BOTTOM:
649
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
650
                                      buf->vb.height,0,buf->tvnorm);
651
                        bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
652
                                         0,buf->vb.width,0,buf->vb.height,
653
                                         uoffset,voffset,buf->fmt->hshift,
654
                                         buf->fmt->vshift,0);
655
                        break;
656
                case V4L2_FIELD_INTERLACED:
657
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
658
                                      buf->vb.height,1,buf->tvnorm);
659
                        lines    = buf->vb.height >> 1;
660
                        ypadding = buf->vb.width;
661
                        cpadding = buf->vb.width >> buf->fmt->hshift;
662
                        bttv_risc_planar(btv,&buf->top,
663
                                         buf->vb.dma.sglist,
664
                                         0,buf->vb.width,ypadding,lines,
665
                                         uoffset,voffset,
666
                                         buf->fmt->hshift,
667
                                         buf->fmt->vshift,
668
                                         cpadding);
669
                        bttv_risc_planar(btv,&buf->bottom,
670
                                         buf->vb.dma.sglist,
671
                                         ypadding,buf->vb.width,ypadding,lines,
672
                                         uoffset+cpadding,
673
                                         voffset+cpadding,
674
                                         buf->fmt->hshift,
675
                                         buf->fmt->vshift,
676
                                         cpadding);
677
                        break;
678
                case V4L2_FIELD_SEQ_TB:
679
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
680
                                      buf->vb.height,1,buf->tvnorm);
681
                        lines    = buf->vb.height >> 1;
682
                        ypadding = buf->vb.width;
683
                        cpadding = buf->vb.width >> buf->fmt->hshift;
684
                        bttv_risc_planar(btv,&buf->top,
685
                                         buf->vb.dma.sglist,
686
                                         0,buf->vb.width,0,lines,
687
                                         uoffset >> 1,
688
                                         voffset >> 1,
689
                                         buf->fmt->hshift,
690
                                         buf->fmt->vshift,
691
                                         0);
692
                        bttv_risc_planar(btv,&buf->bottom,
693
                                         buf->vb.dma.sglist,
694
                                         lines * ypadding,buf->vb.width,0,lines,
695
                                         lines * ypadding + (uoffset >> 1),
696
                                         lines * ypadding + (voffset >> 1),
697
                                         buf->fmt->hshift,
698
                                         buf->fmt->vshift,
699
                                         0);
700
                        break;
701
                default:
702
                        BUG();
703
                }
704
        }
705
 
706
        /* raw data */
707
        if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
708
                /* build risc code */
709
                buf->vb.field = V4L2_FIELD_SEQ_TB;
710
                bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
711
                              1,buf->tvnorm);
712
                bttv_risc_packed(btv, &buf->top,  buf->vb.dma.sglist,
713
                                 0, RAW_BPL, 0, RAW_LINES);
714
                bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
715
                                 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
716
        }
717
 
718
        /* copy format info */
719
        buf->btformat = buf->fmt->btformat;
720
        buf->btswap   = buf->fmt->btswap;
721
        return 0;
722
}
723
 
724
/* ---------------------------------------------------------- */
725
 
726
/* calculate geometry, build risc code */
727
int
728
bttv_overlay_risc(struct bttv *btv,
729
                  struct bttv_overlay *ov,
730
                  const struct bttv_format *fmt,
731
                  struct bttv_buffer *buf)
732
{
733
        /* check interleave, bottom+top fields */
516 giacomo 734
        //dprintk(KERN_DEBUG
735
        //      "bttv%d: overlay fields: %s format: %s  size: %dx%d\n",
736
        //      btv->nr, v4l2_field_names[buf->vb.field],
737
        //      fmt->name,ov->w.width,ov->w.height);
428 giacomo 738
 
739
        /* calculate geometry */
740
        bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
741
                      V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
742
 
743
        /* build risc code */
744
        switch (ov->field) {
745
        case V4L2_FIELD_TOP:
746
                bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
747
                break;
748
        case V4L2_FIELD_BOTTOM:
749
                bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
750
                break;
751
        case V4L2_FIELD_INTERLACED:
752
#if 0
753
                bttv_risc_overlay(btv, &buf->top,    fmt, ov, 1, 0);
754
                bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
755
#else
756
                bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
757
                bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
758
#endif
759
                break;
760
        default:
761
                BUG();
762
        }
763
 
764
        /* copy format info */
765
        buf->btformat = fmt->btformat;
766
        buf->btswap   = fmt->btswap;
767
        buf->vb.field = ov->field;
768
        return 0;
769
}
770
 
771
/*
772
 * Local variables:
773
 * c-basic-offset: 8
774
 * End:
775
 */