linux/drivers/media/common/btcx-risc.c
<<
>>
Prefs
   1/*
   2
   3    btcx-risc.c
   4
   5    bt848/bt878/cx2388x risc code generator.
   6
   7    (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   8
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 2 of the License, or
  12    (at your option) any later version.
  13
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18
  19    You should have received a copy of the GNU General Public License
  20    along with this program; if not, write to the Free Software
  21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22
  23*/
  24
  25#include <linux/module.h>
  26#include <linux/init.h>
  27#include <linux/pci.h>
  28#include <linux/interrupt.h>
  29#include <linux/videodev2.h>
  30#include <asm/page.h>
  31#include <asm/pgtable.h>
  32
  33#include "btcx-risc.h"
  34
  35MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
  36MODULE_AUTHOR("Gerd Knorr");
  37MODULE_LICENSE("GPL");
  38
  39static unsigned int debug;
  40module_param(debug, int, 0644);
  41MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
  42
  43/* ---------------------------------------------------------- */
  44/* allocate/free risc memory                                  */
  45
  46static int memcnt;
  47
  48void btcx_riscmem_free(struct pci_dev *pci,
  49                       struct btcx_riscmem *risc)
  50{
  51        if (NULL == risc->cpu)
  52                return;
  53        if (debug) {
  54                memcnt--;
  55                printk("btcx: riscmem free [%d] dma=%lx\n",
  56                       memcnt, (unsigned long)risc->dma);
  57        }
  58        pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
  59        memset(risc,0,sizeof(*risc));
  60}
  61
  62int btcx_riscmem_alloc(struct pci_dev *pci,
  63                       struct btcx_riscmem *risc,
  64                       unsigned int size)
  65{
  66        __le32 *cpu;
  67        dma_addr_t dma = 0;
  68
  69        if (NULL != risc->cpu && risc->size < size)
  70                btcx_riscmem_free(pci,risc);
  71        if (NULL == risc->cpu) {
  72                cpu = pci_alloc_consistent(pci, size, &dma);
  73                if (NULL == cpu)
  74                        return -ENOMEM;
  75                risc->cpu  = cpu;
  76                risc->dma  = dma;
  77                risc->size = size;
  78                if (debug) {
  79                        memcnt++;
  80                        printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
  81                               memcnt, (unsigned long)dma, cpu, size);
  82                }
  83        }
  84        memset(risc->cpu,0,risc->size);
  85        return 0;
  86}
  87
  88/* ---------------------------------------------------------- */
  89/* screen overlay helpers                                     */
  90
  91int
  92btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
  93                  struct v4l2_clip *clips, unsigned int n)
  94{
  95        if (win->left < 0) {
  96                /* left */
  97                clips[n].c.left = 0;
  98                clips[n].c.top = 0;
  99                clips[n].c.width  = -win->left;
 100                clips[n].c.height = win->height;
 101                n++;
 102        }
 103        if (win->left + win->width > swidth) {
 104                /* right */
 105                clips[n].c.left   = swidth - win->left;
 106                clips[n].c.top    = 0;
 107                clips[n].c.width  = win->width - clips[n].c.left;
 108                clips[n].c.height = win->height;
 109                n++;
 110        }
 111        if (win->top < 0) {
 112                /* top */
 113                clips[n].c.left = 0;
 114                clips[n].c.top = 0;
 115                clips[n].c.width  = win->width;
 116                clips[n].c.height = -win->top;
 117                n++;
 118        }
 119        if (win->top + win->height > sheight) {
 120                /* bottom */
 121                clips[n].c.left = 0;
 122                clips[n].c.top = sheight - win->top;
 123                clips[n].c.width  = win->width;
 124                clips[n].c.height = win->height - clips[n].c.top;
 125                n++;
 126        }
 127        return n;
 128}
 129
 130int
 131btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
 132{
 133        s32 nx,nw,dx;
 134        unsigned int i;
 135
 136        /* fixup window */
 137        nx = (win->left + mask) & ~mask;
 138        nw = (win->width) & ~mask;
 139        if (nx + nw > win->left + win->width)
 140                nw -= mask+1;
 141        dx = nx - win->left;
 142        win->left  = nx;
 143        win->width = nw;
 144        if (debug)
 145                printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
 146                       win->width, win->height, win->left, win->top, dx);
 147
 148        /* fixup clips */
 149        for (i = 0; i < n; i++) {
 150                nx = (clips[i].c.left-dx) & ~mask;
 151                nw = (clips[i].c.width) & ~mask;
 152                if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
 153                        nw += mask+1;
 154                clips[i].c.left  = nx;
 155                clips[i].c.width = nw;
 156                if (debug)
 157                        printk(KERN_DEBUG "btcx:   clip align %dx%d+%d+%d\n",
 158                               clips[i].c.width, clips[i].c.height,
 159                               clips[i].c.left, clips[i].c.top);
 160        }
 161        return 0;
 162}
 163
 164void
 165btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
 166{
 167        struct v4l2_clip swap;
 168        int i,j,n;
 169
 170        if (nclips < 2)
 171                return;
 172        for (i = nclips-2; i >= 0; i--) {
 173                for (n = 0, j = 0; j <= i; j++) {
 174                        if (clips[j].c.left > clips[j+1].c.left) {
 175                                gmb();
 176                                swap = clips[j];
 177                                clips[j] = clips[j+1];
 178                                clips[j+1] = swap;
 179                                n++;
 180                        }
 181                }
 182                if (0 == n)
 183                        break;
 184        }
 185}
 186
 187void
 188btcx_calc_skips(int line, int width, int *maxy,
 189                struct btcx_skiplist *skips, unsigned int *nskips,
 190                const struct v4l2_clip *clips, unsigned int nclips)
 191{
 192        unsigned int clip,skip;
 193        int end, maxline;
 194
 195        skip=0;
 196        maxline = 9999;
 197        for (clip = 0; clip < nclips; clip++) {
 198
 199                /* sanity checks */
 200                if (clips[clip].c.left + clips[clip].c.width <= 0)
 201                        continue;
 202                if (clips[clip].c.left > (signed)width)
 203                        break;
 204
 205                /* vertical range */
 206                if (line > clips[clip].c.top+clips[clip].c.height-1)
 207                        continue;
 208                if (line < clips[clip].c.top) {
 209                        if (maxline > clips[clip].c.top-1)
 210                                maxline = clips[clip].c.top-1;
 211                        continue;
 212                }
 213                if (maxline > clips[clip].c.top+clips[clip].c.height-1)
 214                        maxline = clips[clip].c.top+clips[clip].c.height-1;
 215
 216                /* horizontal range */
 217                if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
 218                        /* new one */
 219                        skips[skip].start = clips[clip].c.left;
 220                        if (skips[skip].start < 0)
 221                                skips[skip].start = 0;
 222                        skips[skip].end = clips[clip].c.left + clips[clip].c.width;
 223                        if (skips[skip].end > width)
 224                                skips[skip].end = width;
 225                        skip++;
 226                } else {
 227                        /* overlaps -- expand last one */
 228                        end = clips[clip].c.left + clips[clip].c.width;
 229                        if (skips[skip-1].end < end)
 230                                skips[skip-1].end = end;
 231                        if (skips[skip-1].end > width)
 232                                skips[skip-1].end = width;
 233                }
 234        }
 235        *nskips = skip;
 236        *maxy = maxline;
 237
 238        if (debug) {
 239                printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
 240                for (skip = 0; skip < *nskips; skip++) {
 241                        printk(" %d-%d",skips[skip].start,skips[skip].end);
 242                }
 243                printk("\n");
 244        }
 245}
 246
 247/* ---------------------------------------------------------- */
 248
 249EXPORT_SYMBOL(btcx_riscmem_alloc);
 250EXPORT_SYMBOL(btcx_riscmem_free);
 251
 252EXPORT_SYMBOL(btcx_screen_clips);
 253EXPORT_SYMBOL(btcx_align);
 254EXPORT_SYMBOL(btcx_sort_clips);
 255EXPORT_SYMBOL(btcx_calc_skips);
 256
 257/*
 258 * Local variables:
 259 * c-basic-offset: 8
 260 * End:
 261 */
 262