btcx-risc.c 6.4 KB

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