btcx-risc.c 5.9 KB

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