root/drivers/media/pci/bt8xx/btcx-risc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. btcx_riscmem_free
  2. btcx_riscmem_alloc
  3. btcx_screen_clips
  4. btcx_align
  5. btcx_sort_clips
  6. btcx_calc_skips

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 
   4     btcx-risc.c
   5 
   6     bt848/bt878/cx2388x risc code generator.
   7 
   8     (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   9 
  10 
  11 */
  12 
  13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14 
  15 #include <linux/module.h>
  16 #include <linux/init.h>
  17 #include <linux/pci.h>
  18 #include <linux/interrupt.h>
  19 #include <linux/videodev2.h>
  20 #include <asm/page.h>
  21 #include <asm/pgtable.h>
  22 
  23 #include "btcx-risc.h"
  24 
  25 static unsigned int btcx_debug;
  26 module_param(btcx_debug, int, 0644);
  27 MODULE_PARM_DESC(btcx_debug,"debug messages, default is 0 (no)");
  28 
  29 #define dprintk(fmt, arg...) do {                               \
  30         if (btcx_debug)                                         \
  31                 printk(KERN_DEBUG pr_fmt("%s: " fmt),           \
  32                        __func__, ##arg);                        \
  33 } while (0)
  34 
  35 
  36 /* ---------------------------------------------------------- */
  37 /* allocate/free risc memory                                  */
  38 
  39 static int memcnt;
  40 
  41 void btcx_riscmem_free(struct pci_dev *pci,
  42                        struct btcx_riscmem *risc)
  43 {
  44         if (NULL == risc->cpu)
  45                 return;
  46 
  47         memcnt--;
  48         dprintk("btcx: riscmem free [%d] dma=%lx\n",
  49                 memcnt, (unsigned long)risc->dma);
  50 
  51         pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
  52         memset(risc,0,sizeof(*risc));
  53 }
  54 
  55 int btcx_riscmem_alloc(struct pci_dev *pci,
  56                        struct btcx_riscmem *risc,
  57                        unsigned int size)
  58 {
  59         __le32 *cpu;
  60         dma_addr_t dma = 0;
  61 
  62         if (NULL != risc->cpu && risc->size < size)
  63                 btcx_riscmem_free(pci,risc);
  64         if (NULL == risc->cpu) {
  65                 cpu = pci_alloc_consistent(pci, size, &dma);
  66                 if (NULL == cpu)
  67                         return -ENOMEM;
  68                 risc->cpu  = cpu;
  69                 risc->dma  = dma;
  70                 risc->size = size;
  71 
  72                 memcnt++;
  73                 dprintk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
  74                         memcnt, (unsigned long)dma, cpu, size);
  75         }
  76         memset(risc->cpu,0,risc->size);
  77         return 0;
  78 }
  79 
  80 /* ---------------------------------------------------------- */
  81 /* screen overlay helpers                                     */
  82 
  83 int
  84 btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
  85                   struct v4l2_clip *clips, unsigned int n)
  86 {
  87         if (win->left < 0) {
  88                 /* left */
  89                 clips[n].c.left = 0;
  90                 clips[n].c.top = 0;
  91                 clips[n].c.width  = -win->left;
  92                 clips[n].c.height = win->height;
  93                 n++;
  94         }
  95         if (win->left + win->width > swidth) {
  96                 /* right */
  97                 clips[n].c.left   = swidth - win->left;
  98                 clips[n].c.top    = 0;
  99                 clips[n].c.width  = win->width - clips[n].c.left;
 100                 clips[n].c.height = win->height;
 101                 n++;
 102         }
 103         if (win->top < 0) {
 104                 /* top */
 105                 clips[n].c.left = 0;
 106                 clips[n].c.top = 0;
 107                 clips[n].c.width  = win->width;
 108                 clips[n].c.height = -win->top;
 109                 n++;
 110         }
 111         if (win->top + win->height > sheight) {
 112                 /* bottom */
 113                 clips[n].c.left = 0;
 114                 clips[n].c.top = sheight - win->top;
 115                 clips[n].c.width  = win->width;
 116                 clips[n].c.height = win->height - clips[n].c.top;
 117                 n++;
 118         }
 119         return n;
 120 }
 121 
 122 int
 123 btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
 124 {
 125         s32 nx,nw,dx;
 126         unsigned int i;
 127 
 128         /* fixup window */
 129         nx = (win->left + mask) & ~mask;
 130         nw = (win->width) & ~mask;
 131         if (nx + nw > win->left + win->width)
 132                 nw -= mask+1;
 133         dx = nx - win->left;
 134         win->left  = nx;
 135         win->width = nw;
 136         dprintk("btcx: window align %dx%d+%d+%d [dx=%d]\n",
 137                win->width, win->height, win->left, win->top, dx);
 138 
 139         /* fixup clips */
 140         for (i = 0; i < n; i++) {
 141                 nx = (clips[i].c.left-dx) & ~mask;
 142                 nw = (clips[i].c.width) & ~mask;
 143                 if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
 144                         nw += mask+1;
 145                 clips[i].c.left  = nx;
 146                 clips[i].c.width = nw;
 147                 dprintk("btcx:   clip align %dx%d+%d+%d\n",
 148                        clips[i].c.width, clips[i].c.height,
 149                        clips[i].c.left, clips[i].c.top);
 150         }
 151         return 0;
 152 }
 153 
 154 void
 155 btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
 156 {
 157         int i,j,n;
 158 
 159         if (nclips < 2)
 160                 return;
 161         for (i = nclips-2; i >= 0; i--) {
 162                 for (n = 0, j = 0; j <= i; j++) {
 163                         if (clips[j].c.left > clips[j+1].c.left) {
 164                                 swap(clips[j], clips[j + 1]);
 165                                 n++;
 166                         }
 167                 }
 168                 if (0 == n)
 169                         break;
 170         }
 171 }
 172 
 173 void
 174 btcx_calc_skips(int line, int width, int *maxy,
 175                 struct btcx_skiplist *skips, unsigned int *nskips,
 176                 const struct v4l2_clip *clips, unsigned int nclips)
 177 {
 178         unsigned int clip,skip;
 179         int end, maxline;
 180 
 181         skip=0;
 182         maxline = 9999;
 183         for (clip = 0; clip < nclips; clip++) {
 184 
 185                 /* sanity checks */
 186                 if (clips[clip].c.left + clips[clip].c.width <= 0)
 187                         continue;
 188                 if (clips[clip].c.left > (signed)width)
 189                         break;
 190 
 191                 /* vertical range */
 192                 if (line > clips[clip].c.top+clips[clip].c.height-1)
 193                         continue;
 194                 if (line < clips[clip].c.top) {
 195                         if (maxline > clips[clip].c.top-1)
 196                                 maxline = clips[clip].c.top-1;
 197                         continue;
 198                 }
 199                 if (maxline > clips[clip].c.top+clips[clip].c.height-1)
 200                         maxline = clips[clip].c.top+clips[clip].c.height-1;
 201 
 202                 /* horizontal range */
 203                 if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
 204                         /* new one */
 205                         skips[skip].start = clips[clip].c.left;
 206                         if (skips[skip].start < 0)
 207                                 skips[skip].start = 0;
 208                         skips[skip].end = clips[clip].c.left + clips[clip].c.width;
 209                         if (skips[skip].end > width)
 210                                 skips[skip].end = width;
 211                         skip++;
 212                 } else {
 213                         /* overlaps -- expand last one */
 214                         end = clips[clip].c.left + clips[clip].c.width;
 215                         if (skips[skip-1].end < end)
 216                                 skips[skip-1].end = end;
 217                         if (skips[skip-1].end > width)
 218                                 skips[skip-1].end = width;
 219                 }
 220         }
 221         *nskips = skip;
 222         *maxy = maxline;
 223 
 224         if (btcx_debug) {
 225                 dprintk("btcx: skips line %d-%d:", line, maxline);
 226                 for (skip = 0; skip < *nskips; skip++) {
 227                         pr_cont(" %d-%d", skips[skip].start, skips[skip].end);
 228                 }
 229                 pr_cont("\n");
 230         }
 231 }

/* [<][>][^][v][top][bottom][index][help] */