root/drivers/media/pci/bt8xx/bttv-risc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bttv_risc_packed
  2. bttv_risc_planar
  3. bttv_risc_overlay
  4. bttv_calc_geo_old
  5. bttv_calc_geo
  6. bttv_apply_geo
  7. bttv_set_dma
  8. bttv_risc_init_main
  9. bttv_risc_hook
  10. bttv_dma_free
  11. bttv_buffer_activate_vbi
  12. bttv_buffer_activate_video
  13. bttv_buffer_risc
  14. bttv_overlay_risc

   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 <asm/page.h>
  24 #include <asm/pgtable.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 }

/* [<][>][^][v][top][bottom][index][help] */