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 /* ---------------------------------------------------------- */ 235 236 static void 237 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, 238 int width, int height, int interleaved, 239 const struct bttv_tvnorm *tvnorm) 240 { 241 u32 xsf, sr; 242 int vdelay; 243 244 int swidth = tvnorm->swidth; 245 int totalwidth = tvnorm->totalwidth; 246 int scaledtwidth = tvnorm->scaledtwidth; 247 248 if (btv->input == btv->dig) { 249 swidth = 720; 250 totalwidth = 858; 251 scaledtwidth = 858; 252 } 253 254 vdelay = tvnorm->vdelay; 255 256 xsf = (width*scaledtwidth)/swidth; 257 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 258 geo->hdelay = tvnorm->hdelayx1; 259 geo->hdelay = (geo->hdelay*width)/swidth; 260 geo->hdelay &= 0x3fe; 261 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 262 geo->vscale = (0x10000UL-sr) & 0x1fff; 263 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 264 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 265 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 266 geo->vdelay = vdelay; 267 geo->width = width; 268 geo->sheight = tvnorm->sheight; 269 geo->vtotal = tvnorm->vtotal; 270 271 if (btv->opt_combfilter) { 272 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 273 geo->comb = (width < 769) ? 1 : 0; 274 } else { 275 geo->vtc = 0; 276 geo->comb = 0; 277 } 278 } 279 280 static void 281 bttv_calc_geo (struct bttv * btv, 282 struct bttv_geometry * geo, 283 unsigned int width, 284 unsigned int height, 285 int both_fields, 286 const struct bttv_tvnorm * tvnorm, 287 const struct v4l2_rect * crop) 288 { 289 unsigned int c_width; 290 unsigned int c_height; 291 u32 sr; 292 293 if ((crop->left == tvnorm->cropcap.defrect.left 294 && crop->top == tvnorm->cropcap.defrect.top 295 && crop->width == tvnorm->cropcap.defrect.width 296 && crop->height == tvnorm->cropcap.defrect.height 297 && width <= tvnorm->swidth /* see PAL-Nc et al */) 298 || btv->input == btv->dig) { 299 bttv_calc_geo_old(btv, geo, width, height, 300 both_fields, tvnorm); 301 return; 302 } 303 304 /* For bug compatibility the image size checks permit scale 305 factors > 16. See bttv_crop_calc_limits(). */ 306 c_width = min((unsigned int) crop->width, width * 16); 307 c_height = min((unsigned int) crop->height, height * 16); 308 309 geo->width = width; 310 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096; 311 /* Even to store Cb first, odd for Cr. */ 312 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1; 313 314 geo->sheight = c_height; 315 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY; 316 sr = c_height >> !both_fields; 317 sr = (sr * 512U + (height >> 1)) / height - 512; 318 geo->vscale = (0x10000UL - sr) & 0x1fff; 319 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0; 320 geo->vtotal = tvnorm->vtotal; 321 322 geo->crop = (((geo->width >> 8) & 0x03) | 323 ((geo->hdelay >> 6) & 0x0c) | 324 ((geo->sheight >> 4) & 0x30) | 325 ((geo->vdelay >> 2) & 0xc0)); 326 327 if (btv->opt_combfilter) { 328 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 329 geo->comb = (width < 769) ? 1 : 0; 330 } else { 331 geo->vtc = 0; 332 geo->comb = 0; 333 } 334 } 335 336 static void 337 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 338 { 339 int off = odd ? 0x80 : 0x00; 340 341 if (geo->comb) 342 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 343 else 344 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 345 346 btwrite(geo->vtc, BT848_E_VTC+off); 347 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 348 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 349 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 350 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 351 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 352 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 353 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 354 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 355 btwrite(geo->crop, BT848_E_CROP+off); 356 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 357 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 358 } 359 360 /* ---------------------------------------------------------- */ 361 /* risc group / risc main loop / dma management */ 362 363 void 364 bttv_set_dma(struct bttv *btv, int override) 365 { 366 unsigned long cmd; 367 int capctl; 368 369 btv->cap_ctl = 0; 370 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02; 371 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01; 372 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c; 373 374 capctl = 0; 375 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */ 376 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */ 377 capctl |= override; 378 379 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n", 380 btv->c.nr,capctl,btv->loop_irq, 381 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, 382 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, 383 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, 384 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); 385 386 cmd = BT848_RISC_JUMP; 387 if (btv->loop_irq) { 388 cmd |= BT848_RISC_IRQ; 389 cmd |= (btv->loop_irq & 0x0f) << 16; 390 cmd |= (~btv->loop_irq & 0x0f) << 20; 391 } 392 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) { 393 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT); 394 } else { 395 del_timer(&btv->timeout); 396 } 397 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 398 399 btaor(capctl, ~0x0f, BT848_CAP_CTL); 400 if (capctl) { 401 if (btv->dma_on) 402 return; 403 btwrite(btv->main.dma, BT848_RISC_STRT_ADD); 404 btor(3, BT848_GPIO_DMA_CTL); 405 btv->dma_on = 1; 406 } else { 407 if (!btv->dma_on) 408 return; 409 btand(~3, BT848_GPIO_DMA_CTL); 410 btv->dma_on = 0; 411 } 412 return; 413 } 414 415 int 416 bttv_risc_init_main(struct bttv *btv) 417 { 418 int rc; 419 420 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0) 421 return rc; 422 dprintk("%d: risc main @ %08llx\n", 423 btv->c.nr, (unsigned long long)btv->main.dma); 424 425 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 426 BT848_FIFO_STATUS_VRE); 427 btv->main.cpu[1] = cpu_to_le32(0); 428 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP); 429 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2)); 430 431 /* top field */ 432 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP); 433 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2)); 434 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 435 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 436 437 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 438 BT848_FIFO_STATUS_VRO); 439 btv->main.cpu[9] = cpu_to_le32(0); 440 441 /* bottom field */ 442 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 443 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 444 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 445 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 446 447 /* jump back to top field */ 448 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 449 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 450 451 return 0; 452 } 453 454 int 455 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, 456 int irqflags) 457 { 458 unsigned long cmd; 459 unsigned long next = btv->main.dma + ((slot+2) << 2); 460 461 if (NULL == risc) { 462 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot); 463 btv->main.cpu[slot+1] = cpu_to_le32(next); 464 } else { 465 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n", 466 btv->c.nr, risc, slot, 467 (unsigned long long)risc->dma, irqflags); 468 cmd = BT848_RISC_JUMP; 469 if (irqflags) { 470 cmd |= BT848_RISC_IRQ; 471 cmd |= (irqflags & 0x0f) << 16; 472 cmd |= (~irqflags & 0x0f) << 20; 473 } 474 risc->jmp[0] = cpu_to_le32(cmd); 475 risc->jmp[1] = cpu_to_le32(next); 476 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma); 477 } 478 return 0; 479 } 480 481 void 482 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf) 483 { 484 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 485 486 videobuf_waiton(q, &buf->vb, 0, 0); 487 videobuf_dma_unmap(q->dev, dma); 488 videobuf_dma_free(dma); 489 btcx_riscmem_free(btv->c.pci,&buf->bottom); 490 btcx_riscmem_free(btv->c.pci,&buf->top); 491 buf->vb.state = VIDEOBUF_NEEDS_INIT; 492 } 493 494 int 495 bttv_buffer_activate_vbi(struct bttv *btv, 496 struct bttv_buffer *vbi) 497 { 498 struct btcx_riscmem *top; 499 struct btcx_riscmem *bottom; 500 int top_irq_flags; 501 int bottom_irq_flags; 502 503 top = NULL; 504 bottom = NULL; 505 top_irq_flags = 0; 506 bottom_irq_flags = 0; 507 508 if (vbi) { 509 unsigned int crop, vdelay; 510 511 vbi->vb.state = VIDEOBUF_ACTIVE; 512 list_del(&vbi->vb.queue); 513 514 /* VDELAY is start of video, end of VBI capturing. */ 515 crop = btread(BT848_E_CROP); 516 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2); 517 518 if (vbi->geo.vdelay > vdelay) { 519 vdelay = vbi->geo.vdelay & 0xfe; 520 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0); 521 522 btwrite(vdelay, BT848_E_VDELAY_LO); 523 btwrite(crop, BT848_E_CROP); 524 btwrite(vdelay, BT848_O_VDELAY_LO); 525 btwrite(crop, BT848_O_CROP); 526 } 527 528 if (vbi->vbi_count[0] > 0) { 529 top = &vbi->top; 530 top_irq_flags = 4; 531 } 532 533 if (vbi->vbi_count[1] > 0) { 534 top_irq_flags = 0; 535 bottom = &vbi->bottom; 536 bottom_irq_flags = 4; 537 } 538 } 539 540 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags); 541 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags); 542 543 return 0; 544 } 545 546 int 547 bttv_buffer_activate_video(struct bttv *btv, 548 struct bttv_buffer_set *set) 549 { 550 /* video capture */ 551 if (NULL != set->top && NULL != set->bottom) { 552 if (set->top == set->bottom) { 553 set->top->vb.state = VIDEOBUF_ACTIVE; 554 if (set->top->vb.queue.next) 555 list_del(&set->top->vb.queue); 556 } else { 557 set->top->vb.state = VIDEOBUF_ACTIVE; 558 set->bottom->vb.state = VIDEOBUF_ACTIVE; 559 if (set->top->vb.queue.next) 560 list_del(&set->top->vb.queue); 561 if (set->bottom->vb.queue.next) 562 list_del(&set->bottom->vb.queue); 563 } 564 bttv_apply_geo(btv, &set->top->geo, 1); 565 bttv_apply_geo(btv, &set->bottom->geo,0); 566 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 567 set->top_irq); 568 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 569 set->frame_irq); 570 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f), 571 ~0xff, BT848_COLOR_FMT); 572 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), 573 ~0x0f, BT848_COLOR_CTL); 574 } else if (NULL != set->top) { 575 set->top->vb.state = VIDEOBUF_ACTIVE; 576 if (set->top->vb.queue.next) 577 list_del(&set->top->vb.queue); 578 bttv_apply_geo(btv, &set->top->geo,1); 579 bttv_apply_geo(btv, &set->top->geo,0); 580 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 581 set->frame_irq); 582 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 583 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 584 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 585 } else if (NULL != set->bottom) { 586 set->bottom->vb.state = VIDEOBUF_ACTIVE; 587 if (set->bottom->vb.queue.next) 588 list_del(&set->bottom->vb.queue); 589 bttv_apply_geo(btv, &set->bottom->geo,1); 590 bttv_apply_geo(btv, &set->bottom->geo,0); 591 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 592 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 593 set->frame_irq); 594 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 595 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 596 } else { 597 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 598 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 599 } 600 return 0; 601 } 602 603 /* ---------------------------------------------------------- */ 604 605 /* calculate geometry, build risc code */ 606 int 607 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) 608 { 609 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm; 610 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 611 612 dprintk("%d: buffer field: %s format: 0x%08x size: %dx%d\n", 613 btv->c.nr, v4l2_field_names[buf->vb.field], 614 buf->fmt->fourcc, buf->vb.width, buf->vb.height); 615 616 /* packed pixel modes */ 617 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) { 618 int bpl = (buf->fmt->depth >> 3) * buf->vb.width; 619 int bpf = bpl * (buf->vb.height >> 1); 620 621 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, 622 V4L2_FIELD_HAS_BOTH(buf->vb.field), 623 tvnorm,&buf->crop); 624 625 switch (buf->vb.field) { 626 case V4L2_FIELD_TOP: 627 bttv_risc_packed(btv,&buf->top,dma->sglist, 628 /* offset */ 0,bpl, 629 /* padding */ 0,/* skip_lines */ 0, 630 buf->vb.height); 631 break; 632 case V4L2_FIELD_BOTTOM: 633 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 634 0,bpl,0,0,buf->vb.height); 635 break; 636 case V4L2_FIELD_INTERLACED: 637 bttv_risc_packed(btv,&buf->top,dma->sglist, 638 0,bpl,bpl,0,buf->vb.height >> 1); 639 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 640 bpl,bpl,bpl,0,buf->vb.height >> 1); 641 break; 642 case V4L2_FIELD_SEQ_TB: 643 bttv_risc_packed(btv,&buf->top,dma->sglist, 644 0,bpl,0,0,buf->vb.height >> 1); 645 bttv_risc_packed(btv,&buf->bottom,dma->sglist, 646 bpf,bpl,0,0,buf->vb.height >> 1); 647 break; 648 default: 649 BUG(); 650 } 651 } 652 653 /* planar modes */ 654 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) { 655 int uoffset, voffset; 656 int ypadding, cpadding, lines; 657 658 /* calculate chroma offsets */ 659 uoffset = buf->vb.width * buf->vb.height; 660 voffset = buf->vb.width * buf->vb.height; 661 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) { 662 /* Y-Cr-Cb plane order */ 663 uoffset >>= buf->fmt->hshift; 664 uoffset >>= buf->fmt->vshift; 665 uoffset += voffset; 666 } else { 667 /* Y-Cb-Cr plane order */ 668 voffset >>= buf->fmt->hshift; 669 voffset >>= buf->fmt->vshift; 670 voffset += uoffset; 671 } 672 673 switch (buf->vb.field) { 674 case V4L2_FIELD_TOP: 675 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 676 buf->vb.height,/* both_fields */ 0, 677 tvnorm,&buf->crop); 678 bttv_risc_planar(btv, &buf->top, dma->sglist, 679 0,buf->vb.width,0,buf->vb.height, 680 uoffset,voffset,buf->fmt->hshift, 681 buf->fmt->vshift,0); 682 break; 683 case V4L2_FIELD_BOTTOM: 684 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 685 buf->vb.height,0, 686 tvnorm,&buf->crop); 687 bttv_risc_planar(btv, &buf->bottom, dma->sglist, 688 0,buf->vb.width,0,buf->vb.height, 689 uoffset,voffset,buf->fmt->hshift, 690 buf->fmt->vshift,0); 691 break; 692 case V4L2_FIELD_INTERLACED: 693 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 694 buf->vb.height,1, 695 tvnorm,&buf->crop); 696 lines = buf->vb.height >> 1; 697 ypadding = buf->vb.width; 698 cpadding = buf->vb.width >> buf->fmt->hshift; 699 bttv_risc_planar(btv,&buf->top, 700 dma->sglist, 701 0,buf->vb.width,ypadding,lines, 702 uoffset,voffset, 703 buf->fmt->hshift, 704 buf->fmt->vshift, 705 cpadding); 706 bttv_risc_planar(btv,&buf->bottom, 707 dma->sglist, 708 ypadding,buf->vb.width,ypadding,lines, 709 uoffset+cpadding, 710 voffset+cpadding, 711 buf->fmt->hshift, 712 buf->fmt->vshift, 713 cpadding); 714 break; 715 case V4L2_FIELD_SEQ_TB: 716 bttv_calc_geo(btv,&buf->geo,buf->vb.width, 717 buf->vb.height,1, 718 tvnorm,&buf->crop); 719 lines = buf->vb.height >> 1; 720 ypadding = buf->vb.width; 721 cpadding = buf->vb.width >> buf->fmt->hshift; 722 bttv_risc_planar(btv,&buf->top, 723 dma->sglist, 724 0,buf->vb.width,0,lines, 725 uoffset >> 1, 726 voffset >> 1, 727 buf->fmt->hshift, 728 buf->fmt->vshift, 729 0); 730 bttv_risc_planar(btv,&buf->bottom, 731 dma->sglist, 732 lines * ypadding,buf->vb.width,0,lines, 733 lines * ypadding + (uoffset >> 1), 734 lines * ypadding + (voffset >> 1), 735 buf->fmt->hshift, 736 buf->fmt->vshift, 737 0); 738 break; 739 default: 740 BUG(); 741 } 742 } 743 744 /* raw data */ 745 if (buf->fmt->flags & FORMAT_FLAGS_RAW) { 746 /* build risc code */ 747 buf->vb.field = V4L2_FIELD_SEQ_TB; 748 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, 749 1,tvnorm,&buf->crop); 750 bttv_risc_packed(btv, &buf->top, dma->sglist, 751 /* offset */ 0, RAW_BPL, /* padding */ 0, 752 /* skip_lines */ 0, RAW_LINES); 753 bttv_risc_packed(btv, &buf->bottom, dma->sglist, 754 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES); 755 } 756 757 /* copy format info */ 758 buf->btformat = buf->fmt->btformat; 759 buf->btswap = buf->fmt->btswap; 760 return 0; 761 } 762