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