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