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 split */ 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 skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL); 260 if (NULL == skips) 261 return -ENOMEM; 262 263 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions 264 + sync + jump (all 2 dwords) */ 265 dwords = (3 * ov->nclips + 2) * 266 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); 267 dwords += 4; 268 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { 269 kfree(skips); 270 return rc; 271 } 272 273 /* sync instruction */ 274 rp = risc->cpu; 275 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); 276 *(rp++) = cpu_to_le32(0); 277 278 addr = (unsigned long)btv->fbuf.base; 279 addr += btv->fbuf.fmt.bytesperline * ov->w.top; 280 addr += (fmt->depth >> 3) * ov->w.left; 281 282 /* scan lines */ 283 for (maxy = -1, line = 0; line < ov->w.height; 284 line++, addr += btv->fbuf.fmt.bytesperline) { 285 if ((btv->opt_vcr_hack) && 286 (line >= (ov->w.height - VCR_HACK_LINES))) 287 continue; 288 if ((line%2) == 0 && skip_even) 289 continue; 290 if ((line%2) == 1 && skip_odd) 291 continue; 292 293 /* calculate clipping */ 294 if (line > maxy) 295 btcx_calc_skips(line, ov->w.width, &maxy, 296 skips, &nskips, ov->clips, ov->nclips); 297 298 /* write out risc code */ 299 for (start = 0, skip = 0; start < ov->w.width; start = end) { 300 if (skip >= nskips) { 301 ri = BT848_RISC_WRITE; 302 end = ov->w.width; 303 } else if (start < skips[skip].start) { 304 ri = BT848_RISC_WRITE; 305 end = skips[skip].start; 306 } else { 307 ri = BT848_RISC_SKIP; 308 end = skips[skip].end; 309 skip++; 310 } 311 if (BT848_RISC_WRITE == ri) 312 ra = addr + (fmt->depth>>3)*start; 313 else 314 ra = 0; 315 316 if (0 == start) 317 ri |= BT848_RISC_SOL; 318 if (ov->w.width == end) 319 ri |= BT848_RISC_EOL; 320 ri |= (fmt->depth>>3) * (end-start); 321 322 *(rp++)=cpu_to_le32(ri); 323 if (0 != ra) 324 *(rp++)=cpu_to_le32(ra); 325 } 326 } 327 328 /* save pointer to jmp instruction address */ 329 risc->jmp = rp; 330 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); 331 kfree(skips); 332 return 0; 333 } 334 335 /* ---------------------------------------------------------- */ 336 337 static void 338 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, 339 int width, int height, int interleaved, 340 const struct bttv_tvnorm *tvnorm) 341 { 342 u32 xsf, sr; 343 int vdelay; 344 345 int swidth = tvnorm->swidth; 346 int totalwidth = tvnorm->totalwidth; 347 int scaledtwidth = tvnorm->scaledtwidth; 348 349 if (btv->input == btv->dig) { 350 swidth = 720; 351 totalwidth = 858; 352 scaledtwidth = 858; 353 } 354 355 vdelay = tvnorm->vdelay; 356 357 xsf = (width*scaledtwidth)/swidth; 358 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 359 geo->hdelay = tvnorm->hdelayx1; 360 geo->hdelay = (geo->hdelay*width)/swidth; 361 geo->hdelay &= 0x3fe; 362 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 363 geo->vscale = (0x10000UL-sr) & 0x1fff; 364 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 365 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 366 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 367 geo->vdelay = vdelay; 368 geo->width = width; 369 geo->sheight = tvnorm->sheight; 370 geo->vtotal = tvnorm->vtotal; 371 372 if (btv->opt_combfilter) { 373 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 374 geo->comb = (width < 769) ? 1 : 0; 375 } else { 376 geo->vtc = 0; 377 geo->comb = 0; 378 } 379 } 380 381 static void 382 bttv_calc_geo (struct bttv * btv, 383 struct bttv_geometry * geo, 384 unsigned int width, 385 unsigned int height, 386 int both_fields, 387 const struct bttv_tvnorm * tvnorm, 388 const struct v4l2_rect * crop) 389 { 390 unsigned int c_width; 391 unsigned int c_height; 392 u32 sr; 393 394 if ((crop->left == tvnorm->cropcap.defrect.left 395 && crop->top == tvnorm->cropcap.defrect.top 396 && crop->width == tvnorm->cropcap.defrect.width 397 && crop->height == tvnorm->cropcap.defrect.height 398 && width <= tvnorm->swidth /* see PAL-Nc et al */) 399 || btv->input == btv->dig) { 400 bttv_calc_geo_old(btv, geo, width, height, 401 both_fields, tvnorm); 402 return; 403 } 404 405 /* For bug compatibility the image size checks permit scale 406 factors > 16. See bttv_crop_calc_limits(). */ 407 c_width = min((unsigned int) crop->width, width * 16); 408 c_height = min((unsigned int) crop->height, height * 16); 409 410 geo->width = width; 411 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096; 412 /* Even to store Cb first, odd for Cr. */ 413 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1; 414 415 geo->sheight = c_height; 416 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY; 417 sr = c_height >> !both_fields; 418 sr = (sr * 512U + (height >> 1)) / height - 512; 419 geo->vscale = (0x10000UL - sr) & 0x1fff; 420 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0; 421 geo->vtotal = tvnorm->vtotal; 422 423 geo->crop = (((geo->width >> 8) & 0x03) | 424 ((geo->hdelay >> 6) & 0x0c) | 425 ((geo->sheight >> 4) & 0x30) | 426 ((geo->vdelay >> 2) & 0xc0)); 427 428 if (btv->opt_combfilter) { 429 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 430 geo->comb = (width < 769) ? 1 : 0; 431 } else { 432 geo->vtc = 0; 433 geo->comb = 0; 434 } 435 } 436 437 static void 438 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 439 { 440 int off = odd ? 0x80 : 0x00; 441 442 if (geo->comb) 443 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 444 else 445 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 446 447 btwrite(geo->vtc, BT848_E_VTC+off); 448 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 449 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 450 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 451 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 452 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 453 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 454 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 455 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 456 btwrite(geo->crop, BT848_E_CROP+off); 457 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 458 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 459 } 460 461 /* ---------------------------------------------------------- */ 462 /* risc group / risc main loop / dma management */ 463 464 void 465 bttv_set_dma(struct bttv *btv, int override) 466 { 467 unsigned long cmd; 468 int capctl; 469 470 btv->cap_ctl = 0; 471 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02; 472 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01; 473 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c; 474 475 capctl = 0; 476 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */ 477 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */ 478 capctl |= override; 479 480 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n", 481 btv->c.nr,capctl,btv->loop_irq, 482 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, 483 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, 484 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, 485 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); 486 487 cmd = BT848_RISC_JUMP; 488 if (btv->loop_irq) { 489 cmd |= BT848_RISC_IRQ; 490 cmd |= (btv->loop_irq & 0x0f) << 16; 491 cmd |= (~btv->loop_irq & 0x0f) << 20; 492 } 493 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) { 494 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT); 495 } else { 496 del_timer(&btv->timeout); 497 } 498 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 499 500 btaor(capctl, ~0x0f, BT848_CAP_CTL); 501 if (capctl) { 502 if (btv->dma_on) 503 return; 504 btwrite(btv->main.dma, BT848_RISC_STRT_ADD); 505 btor(3, BT848_GPIO_DMA_CTL); 506 btv->dma_on = 1; 507 } else { 508 if (!btv->dma_on) 509 return; 510 btand(~3, BT848_GPIO_DMA_CTL); 511 btv->dma_on = 0; 512 } 513 return; 514 } 515 516 int 517 bttv_risc_init_main(struct bttv *btv) 518 { 519 int rc; 520 521 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0) 522 return rc; 523 dprintk("%d: risc main @ %08llx\n", 524 btv->c.nr, (unsigned long long)btv->main.dma); 525 526 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 527 BT848_FIFO_STATUS_VRE); 528 btv->main.cpu[1] = cpu_to_le32(0); 529 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP); 530 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2)); 531 532 /* top field */ 533 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP); 534 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2)); 535 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 536 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 537 538 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 539 BT848_FIFO_STATUS_VRO); 540 btv->main.cpu[9] = cpu_to_le32(0); 541 542 /* bottom field */ 543 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 544 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 545 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 546 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 547 548 /* jump back to top field */ 549 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 550 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 551 552 return 0; 553 } 554 555 int 556 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, 557 int irqflags) 558 { 559 unsigned long cmd; 560 unsigned long next = btv->main.dma + ((slot+2) << 2); 561 562 if (NULL == risc) { 563 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot); 564 btv->main.cpu[slot+1] = cpu_to_le32(next); 565 } else { 566 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n", 567 btv->c.nr, risc, slot, 568 (unsigned long long)risc->dma, irqflags); 569 cmd = BT848_RISC_JUMP; 570 if (irqflags) { 571 cmd |= BT848_RISC_IRQ; 572 cmd |= (irqflags & 0x0f) << 16; 573 cmd |= (~irqflags & 0x0f) << 20; 574 } 575 risc->jmp[0] = cpu_to_le32(cmd); 576 risc->jmp[1] = cpu_to_le32(next); 577 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma); 578 } 579 return 0; 580 } 581 582 void 583 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf) 584 { 585 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 586 587 BUG_ON(in_interrupt()); 588 videobuf_waiton(q, &buf->vb, 0, 0); 589 videobuf_dma_unmap(q->dev, dma); 590 videobuf_dma_free(dma); 591 btcx_riscmem_free(btv->c.pci,&buf->bottom); 592 btcx_riscmem_free(btv->c.pci,&buf->top); 593 buf->vb.state = VIDEOBUF_NEEDS_INIT; 594 } 595 596 int 597 bttv_buffer_activate_vbi(struct bttv *btv, 598 struct bttv_buffer *vbi) 599 { 600 struct btcx_riscmem *top; 601 struct btcx_riscmem *bottom; 602 int top_irq_flags; 603 int bottom_irq_flags; 604 605 top = NULL; 606 bottom = NULL; 607 top_irq_flags = 0; 608 bottom_irq_flags = 0; 609 610 if (vbi) { 611 unsigned int crop, vdelay; 612 613 vbi->vb.state = VIDEOBUF_ACTIVE; 614 list_del(&vbi->vb.queue); 615 616 /* VDELAY is start of video, end of VBI capturing. */ 617 crop = btread(BT848_E_CROP); 618 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2); 619 620 if (vbi->geo.vdelay > vdelay) { 621 vdelay = vbi->geo.vdelay & 0xfe; 622 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0); 623 624 btwrite(vdelay, BT848_E_VDELAY_LO); 625 btwrite(crop, BT848_E_CROP); 626 btwrite(vdelay, BT848_O_VDELAY_LO); 627 btwrite(crop, BT848_O_CROP); 628 } 629 630 if (vbi->vbi_count[0] > 0) { 631 top = &vbi->top; 632 top_irq_flags = 4; 633 } 634 635 if (vbi->vbi_count[1] > 0) { 636 top_irq_flags = 0; 637 bottom = &vbi->bottom; 638 bottom_irq_flags = 4; 639 } 640 } 641 642 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags); 643 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags); 644 645 return 0; 646 } 647 648 int 649 bttv_buffer_activate_video(struct bttv *btv, 650 struct bttv_buffer_set *set) 651 { 652 /* video capture */ 653 if (NULL != set->top && NULL != set->bottom) { 654 if (set->top == set->bottom) { 655 set->top->vb.state = VIDEOBUF_ACTIVE; 656 if (set->top->vb.queue.next) 657 list_del(&set->top->vb.queue); 658 } else { 659 set->top->vb.state = VIDEOBUF_ACTIVE; 660 set->bottom->vb.state = VIDEOBUF_ACTIVE; 661 if (set->top->vb.queue.next) 662 list_del(&set->top->vb.queue); 663 if (set->bottom->vb.queue.next) 664 list_del(&set->bottom->vb.queue); 665 } 666 bttv_apply_geo(btv, &set->top->geo, 1); 667 bttv_apply_geo(btv, &set->bottom->geo,0); 668 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 669 set->top_irq); 670 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 671 set->frame_irq); 672 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f), 673 ~0xff, BT848_COLOR_FMT); 674 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), 675 ~0x0f, BT848_COLOR_CTL); 676 } else if (NULL != set->top) { 677 set->top->vb.state = VIDEOBUF_ACTIVE; 678 if (set->top->vb.queue.next) 679 list_del(&set->top->vb.queue); 680 bttv_apply_geo(btv, &set->top->geo,1); 681 bttv_apply_geo(btv, &set->top->geo,0); 682 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 683 set->frame_irq); 684 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 685 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 686 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 687 } else if (NULL != set->bottom) { 688 set->bottom->vb.state = VIDEOBUF_ACTIVE; 689 if (set->bottom->vb.queue.next) 690 list_del(&set->bottom->vb.queue); 691 bttv_apply_geo(btv, &set->bottom->geo,1); 692 bttv_apply_geo(btv, &set->bottom->geo,0); 693 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 694 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 695 set->frame_irq); 696 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 697 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 698 } else { 699 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 700 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 701 } 702 return 0; 703 } 704 705 /* ---------------------------------------------------------- */ 706 707 /* calculate geometry, build risc code */ 708 int 709 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) 710 { 711 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm; 712 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 713 714 dprintk("%d: buffer field: %s format: %s size: %dx%d\n", 715 btv->c.nr, v4l2_field_names[buf->vb.field], 716 buf->fmt->name, buf->vb.width, buf->vb.height); 717 718 /* packed pixel modes */ 719 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) { 720 int bpl = (buf->fmt->depth >> 3) * buf->vb.width; 721 int bpf = bpl * (buf->vb.height >> 1); 722 723 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, 724 V4L2_FIELD_HAS_BOTH(buf->vb.field), 725 tvnorm,&buf->crop); 726 727 switch (buf->vb.field) { 728 case V4L2_FIELD_TOP: 729 bttv_risc_packed(btv,&buf->top,dma->sglist, 730 /* offset */ 0,bpl, 731 /* padding */ 0,/* skip_lines */ 0, 732 buf->vb.height); 733 break; 734 case V4L2_FIELD_BOTTOM: 735 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 736 0,bpl,0,0,buf->vb.height); 737 break; 738 case V4L2_FIELD_INTERLACED: 739 bttv_risc_packed(btv,&buf->top,dma->sglist, 740 0,bpl,bpl,0,buf->vb.height >> 1); 741 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 742 bpl,bpl,bpl,0,buf->vb.height >> 1); 743 break; 744 case V4L2_FIELD_SEQ_TB: 745 bttv_risc_packed(btv,&buf->top,dma->sglist, 746 0,bpl,0,0,buf->vb.height >> 1); 747 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 748 bpf,bpl,0,0,buf->vb.height >> 1); 749 break; 750 default: 751 BUG(); 752 } 753 } 754 755 /* planar modes */ 756 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) { 757 int uoffset, voffset; 758 int ypadding, cpadding, lines; 759 760 /* calculate chroma offsets */ 761 uoffset = buf->vb.width * buf->vb.height; 762 voffset = buf->vb.width * buf->vb.height; 763 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) { 764 /* Y-Cr-Cb plane order */ 765 uoffset >>= buf->fmt->hshift; 766 uoffset >>= buf->fmt->vshift; 767 uoffset += voffset; 768 } else { 769 /* Y-Cb-Cr plane order */ 770 voffset >>= buf->fmt->hshift; 771 voffset >>= buf->fmt->vshift; 772 voffset += uoffset; 773 } 774 775 switch (buf->vb.field) { 776 case V4L2_FIELD_TOP: 777 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 778 buf->vb.height,/* both_fields */ 0, 779 tvnorm,&buf->crop); 780 bttv_risc_planar(btv, &buf->top, dma->sglist, 781 0,buf->vb.width,0,buf->vb.height, 782 uoffset,voffset,buf->fmt->hshift, 783 buf->fmt->vshift,0); 784 break; 785 case V4L2_FIELD_BOTTOM: 786 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 787 buf->vb.height,0, 788 tvnorm,&buf->crop); 789 bttv_risc_planar(btv, &buf->bottom, dma->sglist, 790 0,buf->vb.width,0,buf->vb.height, 791 uoffset,voffset,buf->fmt->hshift, 792 buf->fmt->vshift,0); 793 break; 794 case V4L2_FIELD_INTERLACED: 795 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 796 buf->vb.height,1, 797 tvnorm,&buf->crop); 798 lines = buf->vb.height >> 1; 799 ypadding = buf->vb.width; 800 cpadding = buf->vb.width >> buf->fmt->hshift; 801 bttv_risc_planar(btv,&buf->top, 802 dma->sglist, 803 0,buf->vb.width,ypadding,lines, 804 uoffset,voffset, 805 buf->fmt->hshift, 806 buf->fmt->vshift, 807 cpadding); 808 bttv_risc_planar(btv,&buf->bottom, 809 dma->sglist, 810 ypadding,buf->vb.width,ypadding,lines, 811 uoffset+cpadding, 812 voffset+cpadding, 813 buf->fmt->hshift, 814 buf->fmt->vshift, 815 cpadding); 816 break; 817 case V4L2_FIELD_SEQ_TB: 818 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 819 buf->vb.height,1, 820 tvnorm,&buf->crop); 821 lines = buf->vb.height >> 1; 822 ypadding = buf->vb.width; 823 cpadding = buf->vb.width >> buf->fmt->hshift; 824 bttv_risc_planar(btv,&buf->top, 825 dma->sglist, 826 0,buf->vb.width,0,lines, 827 uoffset >> 1, 828 voffset >> 1, 829 buf->fmt->hshift, 830 buf->fmt->vshift, 831 0); 832 bttv_risc_planar(btv,&buf->bottom, 833 dma->sglist, 834 lines * ypadding,buf->vb.width,0,lines, 835 lines * ypadding + (uoffset >> 1), 836 lines * ypadding + (voffset >> 1), 837 buf->fmt->hshift, 838 buf->fmt->vshift, 839 0); 840 break; 841 default: 842 BUG(); 843 } 844 } 845 846 /* raw data */ 847 if (buf->fmt->flags & FORMAT_FLAGS_RAW) { 848 /* build risc code */ 849 buf->vb.field = V4L2_FIELD_SEQ_TB; 850 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, 851 1,tvnorm,&buf->crop); 852 bttv_risc_packed(btv, &buf->top, dma->sglist, 853 /* offset */ 0, RAW_BPL, /* padding */ 0, 854 /* skip_lines */ 0, RAW_LINES); 855 bttv_risc_packed(btv, &buf->bottom, dma->sglist, 856 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES); 857 } 858 859 /* copy format info */ 860 buf->btformat = buf->fmt->btformat; 861 buf->btswap = buf->fmt->btswap; 862 return 0; 863 } 864 865 /* ---------------------------------------------------------- */ 866 867 /* calculate geometry, build risc code */ 868 int 869 bttv_overlay_risc(struct bttv *btv, 870 struct bttv_overlay *ov, 871 const struct bttv_format *fmt, 872 struct bttv_buffer *buf) 873 { 874 /* check interleave, bottom+top fields */ 875 dprintk("%d: overlay fields: %s format: %s size: %dx%d\n", 876 btv->c.nr, v4l2_field_names[buf->vb.field], 877 fmt->name, ov->w.width, ov->w.height); 878 879 /* calculate geometry */ 880 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, 881 V4L2_FIELD_HAS_BOTH(ov->field), 882 &bttv_tvnorms[ov->tvnorm],&buf->crop); 883 884 /* build risc code */ 885 switch (ov->field) { 886 case V4L2_FIELD_TOP: 887 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0); 888 break; 889 case V4L2_FIELD_BOTTOM: 890 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0); 891 break; 892 case V4L2_FIELD_INTERLACED: 893 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1); 894 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0); 895 break; 896 default: 897 BUG(); 898 } 899 900 /* copy format info */ 901 buf->btformat = fmt->btformat; 902 buf->btswap = fmt->btswap; 903 buf->vb.field = ov->field; 904 return 0; 905 } 906