3 Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley, Greg Sharp
6 This file is part of the DT3155 Device Driver.
8 The DT3155 Device Driver is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 The DT3155 Device Driver is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the DT3155 Device Driver; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 Purpose: Buffer management routines, and other routines for the ISR
25 (the actual isr is in dt3155_drv.c)
29 Date Programmer Description of changes made
30 -------------------------------------------------------------------
32 02-Apr-2002 SS Mods to make work with separate allocator
33 module; Merged John Roll's mods to make work with
35 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow
36 buffers which span a 4MB boundary.
37 24-Jul-2002 SS GPL licence.
38 30-Jul-2002 NJC Added support for buffer loop.
39 31-Jul-2002 NJC Complete rewrite of buffer management
40 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning).
41 Also, allocator_init() now returns allocator_max
42 so cleaned up allocate_buffers() accordingly.
43 08-Aug-2005 SS port to 2.6 kernel.
47 #include <asm/system.h>
48 #include <linux/gfp.h>
49 #include <linux/sched.h>
50 #include <linux/types.h>
53 #include "dt3155_drv.h"
54 #include "dt3155_io.h"
55 #include "dt3155_isr.h"
56 #include "allocator.h"
58 #define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/
59 #define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/
62 /******************************************************************************
63 * Simple array based que struct
65 * Some handy functions using the buffering structure.
66 *****************************************************************************/
68 /***************************
70 ***************************/
71 bool are_empty_buffers(struct dt3155_fbuffer
*fb
)
76 /**************************
79 * This is slightly confusing. The number empty_len is the literal #
80 * of empty buffers. After calling, empty_len-1 is the index into the
81 * empty buffer stack. So, if empty_len == 1, there is one empty buffer,
82 * given by fb->empty_buffers[0].
83 * empty_buffers should never fill up, though this is not checked.
84 **************************/
85 void push_empty(struct dt3155_fbuffer
*fb
, int index
)
87 fb
->empty_buffers
[fb
->empty_len
] = index
;
91 /**************************
93 **************************/
94 int pop_empty(struct dt3155_fbuffer
*fb
)
97 return fb
->empty_buffers
[fb
->empty_len
];
100 /*************************
102 *************************/
103 bool is_ready_buf_empty(struct dt3155_fbuffer
*fb
)
105 return fb
->ready_len
== 0;
108 /*************************
111 * this should *never* be true if there are any active, locked or empty
112 * buffers, since it corresponds to nbuffers ready buffers!!
113 * 7/31/02: total rewrite. --NJC
114 *************************/
115 bool is_ready_buf_full(struct dt3155_fbuffer
*fb
)
117 return fb
->ready_len
== fb
->nbuffers
;
120 /*****************************************************
122 *****************************************************/
123 void push_ready(struct dt3155_fbuffer
*fb
, int index
)
125 int head
= fb
->ready_head
;
127 fb
->ready_que
[head
] = index
;
128 fb
->ready_head
= (head
+ 1) % fb
->nbuffers
;
132 /*****************************************************
135 * Simply comptutes the tail given the head and the length.
136 *****************************************************/
137 static int get_tail(struct dt3155_fbuffer
*fb
)
139 return (fb
->ready_head
- fb
->ready_len
+ fb
->nbuffers
) % fb
->nbuffers
;
142 /*****************************************************
145 * This assumes that there is a ready buffer ready... should
146 * be checked (e.g. with is_ready_buf_empty() prior to call.
147 *****************************************************/
148 int pop_ready(struct dt3155_fbuffer
*fb
)
150 int tail
= get_tail(fb
);
153 return fb
->ready_que
[tail
];
156 /*****************************************************
158 *****************************************************/
159 void printques(struct dt3155_fbuffer
*fb
)
163 printk(KERN_INFO
"\n R:");
164 for (i
= get_tail(fb
); i
!= fb
->ready_head
; i
++, i
%= fb
->nbuffers
)
165 printk(" %d ", fb
->ready_que
[i
]);
167 printk(KERN_INFO
"\n E:");
168 for (i
= 0; i
< fb
->empty_len
; i
++)
169 printk(" %d ", fb
->empty_buffers
[i
]);
171 printk(KERN_INFO
"\n A: %d", fb
->active_buf
);
173 printk(KERN_INFO
"\n L: %d\n", fb
->locked_buf
);
176 /*****************************************************
179 * If a buffer intersects the 4MB boundary, push
180 * the start address up to the beginning of the
181 * next 4MB chunk (assuming bufsize < 4MB).
182 *****************************************************/
183 u32
adjust_4MB(u32 buf_addr
, u32 bufsize
)
185 if (((buf_addr
+bufsize
) & UPPER_10_BITS
) != (buf_addr
& UPPER_10_BITS
))
186 return (buf_addr
+bufsize
) & UPPER_10_BITS
;
192 /*****************************************************
195 * Try to allocate enough memory for all requested
196 * buffers. If there is not enough free space
197 * try for less memory.
198 *****************************************************/
199 void allocate_buffers(u32
*buf_addr
, u32
* total_size_kbs
,
202 /* Compute the minimum amount of memory guaranteed to hold all
203 MAXBUFFERS such that no buffer crosses the 4MB boundary.
204 Store this value in the variable "full_size" */
207 u32 bufs_per_chunk
= (FOUR_MB
/ bufsize
);
208 u32 filled_chunks
= (MAXBUFFERS
-1) / bufs_per_chunk
;
209 u32 leftover_bufs
= MAXBUFFERS
- filled_chunks
* bufs_per_chunk
;
211 u32 full_size
= bufsize
/* possibly unusable part of 1st chunk */
212 + filled_chunks
* FOUR_MB
/* max # of completely filled 4mb chunks */
213 + leftover_bufs
* bufsize
; /* these buffs will be in a partly filled
214 chunk at beginning or end */
216 u32 full_size_kbs
= 1 + (full_size
-1) / 1024;
217 u32 min_size_kbs
= 2*ndevices
*bufsize
/ 1024;
220 /* Now, try to allocate full_size. If this fails, keep trying for
221 less & less memory until it succeeds. */
222 #ifndef STANDALONE_ALLOCATOR
223 /* initialize the allocator */
224 allocator_init(&allocator_max
);
226 size_kbs
= full_size_kbs
;
228 printk(KERN_INFO
"DT3155: We would like to get: %d KB\n", full_size_kbs
);
229 printk(KERN_INFO
"DT3155: ...but need at least: %d KB\n", min_size_kbs
);
230 printk(KERN_INFO
"DT3155: ...the allocator has: %d KB\n", allocator_max
);
231 size_kbs
= (full_size_kbs
<= allocator_max
? full_size_kbs
: allocator_max
);
232 if (size_kbs
> min_size_kbs
) {
233 *buf_addr
= allocator_allocate_dma(size_kbs
, GFP_KERNEL
);
234 if (*buf_addr
!= 0) {
235 printk(KERN_INFO
"DT3155: Managed to allocate: %d KB\n",
237 *total_size_kbs
= size_kbs
;
241 /* If we got here, the allocation failed */
242 printk(KERN_INFO
"DT3155: Allocator failed!\n");
250 /*****************************************************
251 * dt3155_setup_buffers
253 * setup_buffers just puts the buffering system into
254 * a consistent state before the start of interrupts
256 * JML : it looks like all the buffers need to be
257 * continuous. So I'm going to try and allocate one
260 * GCS : Fix DMA problems when buffer spans
261 * 4MB boundary. Also, add error checking. This
262 * function will return -ENOMEM when not enough memory.
263 *****************************************************/
264 u32
dt3155_setup_buffers(u32
*allocatorAddr
)
267 struct dt3155_fbuffer
*fb
;
269 u32 rambuff_addr
; /* start of allocation */
270 u32 rambuff_size
; /* total size allocated to driver */
271 u32 rambuff_acm
; /* accumlator, keep track of how much
272 is left after being split up*/
273 u32 rambuff_end
; /* end of rambuff */
274 u32 numbufs
; /* number of useful buffers allocated (per device) */
275 u32 bufsize
= DT3155_MAX_ROWS
* DT3155_MAX_COLS
;
278 /* zero the fbuffer status and address structure */
279 for (minor
= 0; minor
< ndevices
; minor
++) {
280 fb
= &dt3155_status
[minor
].fbuffer
;
281 memset(fb
, 0, sizeof(*fb
));
284 /* allocate a large contiguous chunk of RAM */
285 allocate_buffers(&rambuff_addr
, &rambuff_size
, bufsize
);
286 printk(KERN_INFO
"DT3155: mem info\n");
287 printk(KERN_INFO
" - rambuf_addr = 0x%x\n", rambuff_addr
);
288 printk(KERN_INFO
" - length (kb) = %u\n", rambuff_size
);
289 if (rambuff_addr
== 0) {
291 "DT3155: Error setup_buffers() allocator dma failed\n");
294 *allocatorAddr
= rambuff_addr
;
295 rambuff_end
= rambuff_addr
+ 1024 * rambuff_size
;
297 /* after allocation, we need to count how many useful buffers there
298 are so we can give an equal number to each device */
299 rambuff_acm
= rambuff_addr
;
300 for (index
= 0; index
< MAXBUFFERS
; index
++) {
301 /*avoid spanning 4MB bdry*/
302 rambuff_acm
= adjust_4MB(rambuff_acm
, bufsize
);
303 if (rambuff_acm
+ bufsize
> rambuff_end
)
305 rambuff_acm
+= bufsize
;
307 /* Following line is OK, will waste buffers if index
308 * not evenly divisible by ndevices -NJC*/
309 numbufs
= index
/ ndevices
;
310 printk(KERN_INFO
" - numbufs = %u\n", numbufs
);
313 "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n");
317 /* now that we have board memory we spit it up */
318 /* between the boards and the buffers */
319 rambuff_acm
= rambuff_addr
;
320 for (minor
= 0; minor
< ndevices
; minor
++) {
321 fb
= &dt3155_status
[minor
].fbuffer
;
322 rambuff_acm
= adjust_4MB(rambuff_acm
, bufsize
);
324 /* Save the start of this boards buffer space (for mmap). */
325 dt3155_status
[minor
].mem_addr
= rambuff_acm
;
327 for (index
= 0; index
< numbufs
; index
++) {
328 rambuff_acm
= adjust_4MB(rambuff_acm
, bufsize
);
329 if (rambuff_acm
+ bufsize
> rambuff_end
) {
330 /* Should never happen */
331 printk(KERN_INFO
"DT3155 PROGRAM ERROR (GCS)\n"
332 "Error distributing allocated buffers\n");
336 fb
->frame_info
[index
].addr
= rambuff_acm
;
337 push_empty(fb
, index
);
338 /* printk(" - Buffer : %lx\n", fb->frame_info[index].addr); */
340 rambuff_acm
+= bufsize
;
343 /* Make sure there is an active buffer there. */
344 fb
->active_buf
= pop_empty(fb
);
345 fb
->even_happened
= 0;
346 fb
->even_stopped
= 0;
348 /* make sure there is no locked_buf JML 2/28/00 */
351 dt3155_status
[minor
].mem_size
= rambuff_acm
-
352 dt3155_status
[minor
].mem_addr
;
354 /* setup the ready queue */
357 printk(KERN_INFO
"Available buffers for device %d: %d\n",
358 minor
, fb
->nbuffers
);
364 /*****************************************************
365 * internal_release_locked_buffer
367 * The internal function for releasing a locked buffer.
368 * It assumes interrupts are turned off.
369 *****************************************************/
370 static void internal_release_locked_buffer(struct dt3155_fbuffer
*fb
)
372 if (fb
->locked_buf
>= 0) {
373 push_empty(fb
, fb
->locked_buf
);
378 /*****************************************************
379 * dt3155_release_locked_buffer
381 * The user function of the above.
382 *****************************************************/
383 void dt3155_release_locked_buffer(struct dt3155_fbuffer
*fb
)
385 unsigned long int flags
;
387 local_save_flags(flags
);
389 internal_release_locked_buffer(fb
);
390 local_irq_restore(flags
);
393 /*****************************************************
395 *****************************************************/
396 int dt3155_flush(struct dt3155_fbuffer
*fb
)
398 unsigned long int flags
;
401 local_save_flags(flags
);
404 internal_release_locked_buffer(fb
);
407 for (index
= 0; index
< fb
->nbuffers
; index
++)
408 push_empty(fb
, index
);
410 /* Make sure there is an active buffer there. */
411 fb
->active_buf
= pop_empty(fb
);
413 fb
->even_happened
= 0;
414 fb
->even_stopped
= 0;
416 /* setup the ready queue */
420 local_irq_restore(flags
);
425 /*****************************************************
426 * dt3155_get_ready_buffer
428 * get_ready_buffer will grab the next chunk of data
429 * if it is already there, otherwise it returns 0.
430 * If the user has a buffer locked it will unlock
431 * that buffer before returning the new one.
432 *****************************************************/
433 int dt3155_get_ready_buffer(struct dt3155_fbuffer
*fb
)
435 unsigned long int flags
;
438 local_save_flags(flags
);
445 internal_release_locked_buffer(fb
);
447 if (is_ready_buf_empty(fb
)) {
450 frame_index
= pop_ready(fb
);
451 fb
->locked_buf
= frame_index
;
458 local_irq_restore(flags
);