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