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