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