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