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 ((line >= (store_lines - VCR_HACK_LINES)) && 71 btv->opt_vcr_hack) 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 WARN_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 WARN_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 static void bttv_set_risc_status(struct bttv *btv) 364 { 365 unsigned long cmd = BT848_RISC_JUMP; 366 if (btv->loop_irq) { 367 cmd |= BT848_RISC_IRQ; 368 cmd |= (btv->loop_irq & 0x0f) << 16; 369 cmd |= (~btv->loop_irq & 0x0f) << 20; 370 } 371 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 372 } 373 374 static void bttv_set_irq_timer(struct bttv *btv) 375 { 376 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) 377 mod_timer(&btv->timeout, jiffies + BTTV_TIMEOUT); 378 else 379 del_timer(&btv->timeout); 380 } 381 382 static int bttv_set_capture_control(struct bttv *btv, int start_capture) 383 { 384 int capctl = 0; 385 386 if (btv->curr.top || btv->curr.bottom) 387 capctl = BT848_CAP_CTL_CAPTURE_ODD | 388 BT848_CAP_CTL_CAPTURE_EVEN; 389 390 if (btv->cvbi) 391 capctl |= BT848_CAP_CTL_CAPTURE_VBI_ODD | 392 BT848_CAP_CTL_CAPTURE_VBI_EVEN; 393 394 capctl |= start_capture; 395 396 btaor(capctl, ~0x0f, BT848_CAP_CTL); 397 398 return capctl; 399 } 400 401 static void bttv_start_dma(struct bttv *btv) 402 { 403 if (btv->dma_on) 404 return; 405 btwrite(btv->main.dma, BT848_RISC_STRT_ADD); 406 btor(BT848_GPIO_DMA_CTL_RISC_ENABLE | BT848_GPIO_DMA_CTL_FIFO_ENABLE, 407 BT848_GPIO_DMA_CTL); 408 btv->dma_on = 1; 409 } 410 411 static void bttv_stop_dma(struct bttv *btv) 412 { 413 if (!btv->dma_on) 414 return; 415 btand(~(BT848_GPIO_DMA_CTL_RISC_ENABLE | 416 BT848_GPIO_DMA_CTL_FIFO_ENABLE), BT848_GPIO_DMA_CTL); 417 btv->dma_on = 0; 418 } 419 420 void bttv_set_dma(struct bttv *btv, int start_capture) 421 { 422 int capctl = 0; 423 424 bttv_set_risc_status(btv); 425 bttv_set_irq_timer(btv); 426 capctl = bttv_set_capture_control(btv, start_capture); 427 428 if (capctl) 429 bttv_start_dma(btv); 430 else 431 bttv_stop_dma(btv); 432 433 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n", 434 btv->c.nr,capctl,btv->loop_irq, 435 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, 436 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, 437 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0, 438 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); 439 } 440 441 int 442 bttv_risc_init_main(struct bttv *btv) 443 { 444 int rc; 445 446 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0) 447 return rc; 448 dprintk("%d: risc main @ %08llx\n", 449 btv->c.nr, (unsigned long long)btv->main.dma); 450 451 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 452 BT848_FIFO_STATUS_VRE); 453 btv->main.cpu[1] = cpu_to_le32(0); 454 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP); 455 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2)); 456 457 /* top field */ 458 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP); 459 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2)); 460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 462 463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 464 BT848_FIFO_STATUS_VRO); 465 btv->main.cpu[9] = cpu_to_le32(0); 466 467 /* bottom field */ 468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 472 473 /* jump back to top field */ 474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 476 477 return 0; 478 } 479 480 int 481 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, 482 int irqflags) 483 { 484 unsigned long cmd; 485 unsigned long next = btv->main.dma + ((slot+2) << 2); 486 487 if (NULL == risc) { 488 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot); 489 btv->main.cpu[slot+1] = cpu_to_le32(next); 490 } else { 491 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n", 492 btv->c.nr, risc, slot, 493 (unsigned long long)risc->dma, irqflags); 494 cmd = BT848_RISC_JUMP; 495 if (irqflags) { 496 cmd |= BT848_RISC_IRQ; 497 cmd |= (irqflags & 0x0f) << 16; 498 cmd |= (~irqflags & 0x0f) << 20; 499 } 500 risc->jmp[0] = cpu_to_le32(cmd); 501 risc->jmp[1] = cpu_to_le32(next); 502 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma); 503 } 504 return 0; 505 } 506 507 int bttv_buffer_risc_vbi(struct bttv *btv, struct bttv_buffer *buf) 508 { 509 int r = 0; 510 unsigned int offset; 511 unsigned int bpl = 2044; /* max. vbipack */ 512 unsigned int padding = VBI_BPL - bpl; 513 unsigned int skip_lines0 = 0; 514 unsigned int skip_lines1 = 0; 515 unsigned int min_vdelay = MIN_VDELAY; 516 517 const struct bttv_tvnorm *tvnorm = btv->vbi_fmt.tvnorm; 518 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vbuf.vb2_buf, 0); 519 struct scatterlist *list = sgt->sgl; 520 521 if (btv->vbi_fmt.fmt.count[0] > 0) 522 skip_lines0 = max(0, (btv->vbi_fmt.fmt.start[0] - 523 tvnorm->vbistart[0])); 524 if (btv->vbi_fmt.fmt.count[1] > 0) 525 skip_lines1 = max(0, (btv->vbi_fmt.fmt.start[1] - 526 tvnorm->vbistart[1])); 527 528 if (btv->vbi_fmt.fmt.count[0] > 0) { 529 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, padding, 530 skip_lines0, btv->vbi_fmt.fmt.count[0]); 531 if (r) 532 return r; 533 } 534 535 if (btv->vbi_fmt.fmt.count[1] > 0) { 536 offset = btv->vbi_fmt.fmt.count[0] * VBI_BPL; 537 r = bttv_risc_packed(btv, &buf->bottom, list, offset, bpl, 538 padding, skip_lines1, 539 btv->vbi_fmt.fmt.count[1]); 540 if (r) 541 return r; 542 } 543 544 if (btv->vbi_fmt.end >= tvnorm->cropcap.bounds.top) 545 min_vdelay += btv->vbi_fmt.end - tvnorm->cropcap.bounds.top; 546 547 /* For bttv_buffer_activate_vbi(). */ 548 buf->geo.vdelay = min_vdelay; 549 550 return r; 551 } 552 553 int 554 bttv_buffer_activate_vbi(struct bttv *btv, 555 struct bttv_buffer *vbi) 556 { 557 struct btcx_riscmem *top; 558 struct btcx_riscmem *bottom; 559 int top_irq_flags; 560 int bottom_irq_flags; 561 562 top = NULL; 563 bottom = NULL; 564 top_irq_flags = 0; 565 bottom_irq_flags = 0; 566 567 if (vbi) { 568 unsigned int crop, vdelay; 569 570 list_del(&vbi->list); 571 572 /* VDELAY is start of video, end of VBI capturing. */ 573 crop = btread(BT848_E_CROP); 574 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2); 575 576 if (vbi->geo.vdelay > vdelay) { 577 vdelay = vbi->geo.vdelay & 0xfe; 578 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0); 579 580 btwrite(vdelay, BT848_E_VDELAY_LO); 581 btwrite(crop, BT848_E_CROP); 582 btwrite(vdelay, BT848_O_VDELAY_LO); 583 btwrite(crop, BT848_O_CROP); 584 } 585 586 if (btv->vbi_count[0] > 0) { 587 top = &vbi->top; 588 top_irq_flags = 4; 589 } 590 591 if (btv->vbi_count[1] > 0) { 592 top_irq_flags = 0; 593 bottom = &vbi->bottom; 594 bottom_irq_flags = 4; 595 } 596 } 597 598 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags); 599 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags); 600 601 return 0; 602 } 603 604 int 605 bttv_buffer_activate_video(struct bttv *btv, 606 struct bttv_buffer_set *set) 607 { 608 /* video capture */ 609 if (NULL != set->top && NULL != set->bottom) { 610 if (set->top == set->bottom) { 611 if (set->top->list.next) 612 list_del(&set->top->list); 613 } else { 614 if (set->top->list.next) 615 list_del(&set->top->list); 616 if (set->bottom->list.next) 617 list_del(&set->bottom->list); 618 } 619 bttv_apply_geo(btv, &set->top->geo, 1); 620 bttv_apply_geo(btv, &set->bottom->geo,0); 621 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 622 set->top_irq); 623 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 624 set->frame_irq); 625 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f), 626 ~0xff, BT848_COLOR_FMT); 627 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05), 628 ~0x0f, BT848_COLOR_CTL); 629 } else if (NULL != set->top) { 630 if (set->top->list.next) 631 list_del(&set->top->list); 632 bttv_apply_geo(btv, &set->top->geo,1); 633 bttv_apply_geo(btv, &set->top->geo,0); 634 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 635 set->frame_irq); 636 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 637 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 638 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 639 } else if (NULL != set->bottom) { 640 if (set->bottom->list.next) 641 list_del(&set->bottom->list); 642 bttv_apply_geo(btv, &set->bottom->geo,1); 643 bttv_apply_geo(btv, &set->bottom->geo,0); 644 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 645 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 646 set->frame_irq); 647 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT); 648 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL); 649 } else { 650 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); 651 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0); 652 } 653 return 0; 654 } 655 656 /* ---------------------------------------------------------- */ 657 658 /* calculate geometry, build risc code */ 659 int 660 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) 661 { 662 int r = 0; 663 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + btv->tvnorm; 664 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vbuf.vb2_buf, 0); 665 struct scatterlist *list = sgt->sgl; 666 unsigned long size = (btv->fmt->depth * btv->width * btv->height) >> 3; 667 668 /* packed pixel modes */ 669 if (btv->fmt->flags & FORMAT_FLAGS_PACKED) { 670 int bpl = (btv->fmt->depth >> 3) * btv->width; 671 int bpf = bpl * (btv->height >> 1); 672 673 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height, 674 V4L2_FIELD_HAS_BOTH(buf->vbuf.field), tvnorm, 675 &btv->crop[!!btv->do_crop].rect); 676 switch (buf->vbuf.field) { 677 case V4L2_FIELD_TOP: 678 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, 0, 679 0, btv->height); 680 break; 681 case V4L2_FIELD_BOTTOM: 682 r = bttv_risc_packed(btv, &buf->bottom, list, 0, bpl, 683 0, 0, btv->height); 684 break; 685 case V4L2_FIELD_INTERLACED: 686 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, 687 bpl, 0, btv->height >> 1); 688 r = bttv_risc_packed(btv, &buf->bottom, list, bpl, 689 bpl, bpl, 0, btv->height >> 1); 690 break; 691 case V4L2_FIELD_SEQ_TB: 692 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, 0, 693 0, btv->height >> 1); 694 r = bttv_risc_packed(btv, &buf->bottom, list, bpf, 695 bpl, 0, 0, btv->height >> 1); 696 break; 697 default: 698 WARN_ON(1); 699 return -EINVAL; 700 } 701 } 702 /* planar modes */ 703 if (btv->fmt->flags & FORMAT_FLAGS_PLANAR) { 704 int uoffset, voffset; 705 int ypadding, cpadding, lines; 706 707 /* calculate chroma offsets */ 708 uoffset = btv->width * btv->height; 709 voffset = btv->width * btv->height; 710 if (btv->fmt->flags & FORMAT_FLAGS_CrCb) { 711 /* Y-Cr-Cb plane order */ 712 uoffset >>= btv->fmt->hshift; 713 uoffset >>= btv->fmt->vshift; 714 uoffset += voffset; 715 } else { 716 /* Y-Cb-Cr plane order */ 717 voffset >>= btv->fmt->hshift; 718 voffset >>= btv->fmt->vshift; 719 voffset += uoffset; 720 } 721 switch (buf->vbuf.field) { 722 case V4L2_FIELD_TOP: 723 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height, 724 0, tvnorm, 725 &btv->crop[!!btv->do_crop].rect); 726 r = bttv_risc_planar(btv, &buf->top, list, 0, 727 btv->width, 0, btv->height, 728 uoffset, voffset, 729 btv->fmt->hshift, 730 btv->fmt->vshift, 0); 731 break; 732 case V4L2_FIELD_BOTTOM: 733 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height, 734 0, tvnorm, 735 &btv->crop[!!btv->do_crop].rect); 736 r = bttv_risc_planar(btv, &buf->bottom, list, 0, 737 btv->width, 0, btv->height, 738 uoffset, voffset, 739 btv->fmt->hshift, 740 btv->fmt->vshift, 0); 741 break; 742 case V4L2_FIELD_INTERLACED: 743 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height, 744 1, tvnorm, 745 &btv->crop[!!btv->do_crop].rect); 746 lines = btv->height >> 1; 747 ypadding = btv->width; 748 cpadding = btv->width >> btv->fmt->hshift; 749 r = bttv_risc_planar(btv, &buf->top, list, 0, 750 btv->width, ypadding, lines, 751 uoffset, voffset, 752 btv->fmt->hshift, 753 btv->fmt->vshift, cpadding); 754 755 r = bttv_risc_planar(btv, &buf->bottom, list, 756 ypadding, btv->width, ypadding, 757 lines, uoffset + cpadding, 758 voffset + cpadding, 759 btv->fmt->hshift, 760 btv->fmt->vshift, cpadding); 761 break; 762 case V4L2_FIELD_SEQ_TB: 763 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height, 764 1, tvnorm, 765 &btv->crop[!!btv->do_crop].rect); 766 lines = btv->height >> 1; 767 ypadding = btv->width; 768 cpadding = btv->width >> btv->fmt->hshift; 769 r = bttv_risc_planar(btv, &buf->top, list, 0, 770 btv->width, 0, lines, 771 uoffset >> 1, voffset >> 1, 772 btv->fmt->hshift, 773 btv->fmt->vshift, 0); 774 r = bttv_risc_planar(btv, &buf->bottom, list, 775 lines * ypadding, 776 btv->width, 0, lines, 777 lines * ypadding + (uoffset >> 1), 778 lines * ypadding + (voffset >> 1), 779 btv->fmt->hshift, 780 btv->fmt->vshift, 0); 781 break; 782 default: 783 WARN_ON(1); 784 return -EINVAL; 785 } 786 } 787 /* raw data */ 788 if (btv->fmt->flags & FORMAT_FLAGS_RAW) { 789 /* build risc code */ 790 buf->vbuf.field = V4L2_FIELD_SEQ_TB; 791 bttv_calc_geo(btv, &buf->geo, tvnorm->swidth, tvnorm->sheight, 792 1, tvnorm, &btv->crop[!!btv->do_crop].rect); 793 r = bttv_risc_packed(btv, &buf->top, list, 0, RAW_BPL, 0, 0, 794 RAW_LINES); 795 r = bttv_risc_packed(btv, &buf->bottom, list, size / 2, 796 RAW_BPL, 0, 0, RAW_LINES); 797 } 798 799 /* copy format info */ 800 buf->btformat = btv->fmt->btformat; 801 buf->btswap = btv->fmt->btswap; 802 803 return r; 804 } 805