2 * drivers/media/platform/omap24xxcam-dma.c
4 * Copyright (C) 2004 MontaVista Software, Inc.
5 * Copyright (C) 2004 Texas Instruments.
6 * Copyright (C) 2007 Nokia Corporation.
8 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
10 * Based on code from Andy Lowe <source@mvista.com> and
11 * David Cohen <david.cohen@indt.org.br>.
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #include <linux/kernel.h>
30 #include <linux/scatterlist.h>
32 #include "omap24xxcam.h"
40 /* Ack all interrupt on CSR and IRQSTATUS_L0 */
41 static void omap24xxcam_dmahw_ack_all(void __iomem *base)
46 for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
47 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
48 /* ack interrupt in CSR */
49 omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
51 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
54 /* Ack dmach on CSR and IRQSTATUS_L0 */
55 static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
59 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
60 /* ack interrupt in CSR */
61 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
62 /* ack interrupt in IRQSTATUS */
63 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
68 static int omap24xxcam_dmahw_running(void __iomem *base, int dmach)
70 return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
73 static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
74 dma_addr_t start, u32 len)
76 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
77 CAMDMA_CCR_SEL_SRC_DST_SYNC
79 | CAMDMA_CCR_DST_AMODE_POST_INC
80 | CAMDMA_CCR_SRC_AMODE_POST_INC
82 | CAMDMA_CCR_WR_ACTIVE
83 | CAMDMA_CCR_RD_ACTIVE
84 | CAMDMA_CCR_SYNCHRO_CAMERA);
85 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
86 omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
87 omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
88 omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
89 CAMDMA_CSDP_WRITE_MODE_POSTED
90 | CAMDMA_CSDP_DST_BURST_EN_32
91 | CAMDMA_CSDP_DST_PACKED
92 | CAMDMA_CSDP_SRC_BURST_EN_32
93 | CAMDMA_CSDP_SRC_PACKED
94 | CAMDMA_CSDP_DATA_TYPE_8BITS);
95 omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
96 omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
97 omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
98 omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
99 omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
100 omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
101 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
102 CAMDMA_CSR_MISALIGNED_ERR
103 | CAMDMA_CSR_SECURE_ERR
104 | CAMDMA_CSR_TRANS_ERR
107 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
108 CAMDMA_CICR_MISALIGNED_ERR_IE
109 | CAMDMA_CICR_SECURE_ERR_IE
110 | CAMDMA_CICR_TRANS_ERR_IE
111 | CAMDMA_CICR_BLOCK_IE
112 | CAMDMA_CICR_DROP_IE);
115 static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
117 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
118 CAMDMA_CCR_SEL_SRC_DST_SYNC
120 | CAMDMA_CCR_DST_AMODE_POST_INC
121 | CAMDMA_CCR_SRC_AMODE_POST_INC
124 | CAMDMA_CCR_SYNCHRO_CAMERA);
127 static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
133 prev_dmach = NUM_CAMDMA_CHANNELS - 1;
135 prev_dmach = dmach - 1;
136 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
137 CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
138 /* Did we chain the DMA transfer before the previous one
141 ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
142 while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
143 & CAMDMA_CCR_ENABLE)) {
145 /* The previous transfer has ended and this one
146 * hasn't started, so we must not have chained
147 * to the previous one in time. We'll have to
150 omap24xxcam_dmahw_transfer_start(base, dmach);
153 ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
157 /* Abort all chained DMA transfers. After all transfers have been
158 * aborted and the DMA controller is idle, the completion routines for
159 * any aborted transfers will be called in sequence. The DMA
160 * controller may not be idle after this routine completes, because
161 * the completion routines might start new transfers.
163 static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
165 /* mask all interrupts from this channel */
166 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
167 /* unlink this channel */
168 omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
169 CAMDMA_CLNK_CTRL_ENABLE_LNK);
170 /* disable this channel */
171 omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
174 static void omap24xxcam_dmahw_init(void __iomem *base)
176 omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
177 CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
178 | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
179 | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);
181 omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
182 CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);
184 omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
189 * Individual DMA channel handling.
193 /* Start a DMA transfer from the camera to memory.
194 * Returns zero if the transfer was successfully started, or non-zero if all
195 * DMA channels are already in use or starting is currently inhibited.
197 static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
198 u32 len, dma_callback_t callback, void *arg)
203 spin_lock_irqsave(&dma->lock, flags);
205 if (!dma->free_dmach || atomic_read(&dma->dma_stop)) {
206 spin_unlock_irqrestore(&dma->lock, flags);
210 dmach = dma->next_dmach;
212 dma->ch_state[dmach].callback = callback;
213 dma->ch_state[dmach].arg = arg;
215 omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);
217 /* We're ready to start the DMA transfer. */
219 if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
220 /* A transfer is already in progress, so try to chain to it. */
221 omap24xxcam_dmahw_transfer_chain(dma->base, dmach,
224 /* No transfer is in progress, so we'll just start this one
227 omap24xxcam_dmahw_transfer_start(dma->base, dmach);
230 dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
233 spin_unlock_irqrestore(&dma->lock, flags);
238 /* Abort all chained DMA transfers. After all transfers have been
239 * aborted and the DMA controller is idle, the completion routines for
240 * any aborted transfers will be called in sequence. The DMA
241 * controller may not be idle after this routine completes, because
242 * the completion routines might start new transfers.
244 static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr)
247 int dmach, i, free_dmach;
248 dma_callback_t callback;
251 spin_lock_irqsave(&dma->lock, flags);
253 /* stop any DMA transfers in progress */
254 dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS;
255 for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
256 omap24xxcam_dmahw_abort_ch(dma->base, dmach);
257 dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
260 /* We have to be careful here because the callback routine
261 * might start a new DMA transfer, and we only want to abort
262 * transfers that were started before this routine was called.
264 free_dmach = dma->free_dmach;
265 while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
266 (free_dmach < NUM_CAMDMA_CHANNELS)) {
267 dmach = (dma->next_dmach + dma->free_dmach)
268 % NUM_CAMDMA_CHANNELS;
269 callback = dma->ch_state[dmach].callback;
270 arg = dma->ch_state[dmach].arg;
274 /* leave interrupts disabled during callback */
275 spin_unlock(&dma->lock);
276 (*callback) (dma, csr, arg);
277 spin_lock(&dma->lock);
281 spin_unlock_irqrestore(&dma->lock, flags);
284 /* Abort all chained DMA transfers. After all transfers have been
285 * aborted and the DMA controller is idle, the completion routines for
286 * any aborted transfers will be called in sequence. If the completion
287 * routines attempt to start a new DMA transfer it will fail, so the
288 * DMA controller will be idle after this routine completes.
290 static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr)
292 atomic_inc(&dma->dma_stop);
293 omap24xxcam_dma_abort(dma, csr);
294 atomic_dec(&dma->dma_stop);
297 /* Camera DMA interrupt service routine. */
298 void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
301 dma_callback_t callback;
304 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
305 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
306 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
308 spin_lock(&dma->lock);
310 if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
311 /* A camera DMA interrupt occurred while all channels
312 * are idle, so we'll acknowledge the interrupt in the
313 * IRQSTATUS register and exit.
315 omap24xxcam_dmahw_ack_all(dma->base);
316 spin_unlock(&dma->lock);
320 while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
321 dmach = (dma->next_dmach + dma->free_dmach)
322 % NUM_CAMDMA_CHANNELS;
323 if (omap24xxcam_dmahw_running(dma->base, dmach)) {
324 /* This buffer hasn't finished yet, so we're done. */
327 csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
328 if (csr & csr_error) {
329 /* A DMA error occurred, so stop all DMA
330 * transfers in progress.
332 spin_unlock(&dma->lock);
333 omap24xxcam_dma_stop(dma, csr);
336 callback = dma->ch_state[dmach].callback;
337 arg = dma->ch_state[dmach].arg;
340 spin_unlock(&dma->lock);
341 (*callback) (dma, csr, arg);
342 spin_lock(&dma->lock);
346 spin_unlock(&dma->lock);
348 omap24xxcam_sgdma_process(
349 container_of(dma, struct omap24xxcam_sgdma, dma));
352 void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
356 spin_lock_irqsave(&dma->lock, flags);
358 omap24xxcam_dmahw_init(dma->base);
360 spin_unlock_irqrestore(&dma->lock, flags);
363 static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
368 /* group all channels on DMA IRQ0 and unmask irq */
369 spin_lock_init(&dma->lock);
371 dma->free_dmach = NUM_CAMDMA_CHANNELS;
373 for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
374 dma->ch_state[ch].callback = NULL;
375 dma->ch_state[ch].arg = NULL;
381 * Scatter-gather DMA.
383 * High-level DMA construct for transferring whole picture frames to
384 * memory that is discontinuous.
388 /* DMA completion routine for the scatter-gather DMA fragments. */
389 static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr,
392 struct omap24xxcam_sgdma *sgdma =
393 container_of(dma, struct omap24xxcam_sgdma, dma);
394 int sgslot = (int)arg;
395 struct sgdma_state *sg_state;
396 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
397 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
398 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
400 spin_lock(&sgdma->lock);
402 /* We got an interrupt, we can remove the timer */
403 del_timer(&sgdma->reset_timer);
405 sg_state = sgdma->sg_state + sgslot;
406 if (!sg_state->queued_sglist) {
407 spin_unlock(&sgdma->lock);
408 printk(KERN_ERR "%s: sgdma completed when none queued!\n",
413 sg_state->csr |= csr;
414 if (!--sg_state->queued_sglist) {
415 /* Queue for this sglist is empty, so check to see if we're
418 if ((sg_state->next_sglist == sg_state->sglen)
419 || (sg_state->csr & csr_error)) {
420 sgdma_callback_t callback = sg_state->callback;
421 void *arg = sg_state->arg;
422 u32 sg_csr = sg_state->csr;
423 /* All done with this sglist */
426 spin_unlock(&sgdma->lock);
427 (*callback) (sgdma, sg_csr, arg);
433 spin_unlock(&sgdma->lock);
436 /* Start queued scatter-gather DMA transfers. */
437 void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
440 int queued_sgdma, sgslot;
441 struct sgdma_state *sg_state;
442 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
443 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
444 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
446 spin_lock_irqsave(&sgdma->lock, flags);
448 queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
449 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
450 while (queued_sgdma > 0) {
451 sg_state = sgdma->sg_state + sgslot;
452 while ((sg_state->next_sglist < sg_state->sglen) &&
453 !(sg_state->csr & csr_error)) {
454 const struct scatterlist *sglist;
457 sglist = sg_state->sglist + sg_state->next_sglist;
458 /* try to start the next DMA transfer */
459 if (sg_state->next_sglist + 1 == sg_state->sglen) {
461 * On the last sg, we handle the case where
462 * cam->img.pix.sizeimage % PAGE_ALIGN != 0
464 len = sg_state->len - sg_state->bytes_read;
466 len = sg_dma_len(sglist);
469 if (omap24xxcam_dma_start(&sgdma->dma,
470 sg_dma_address(sglist),
472 omap24xxcam_sgdma_callback,
474 /* DMA start failed */
475 spin_unlock_irqrestore(&sgdma->lock, flags);
478 /* DMA start was successful */
479 sg_state->next_sglist++;
480 sg_state->bytes_read += len;
481 sg_state->queued_sglist++;
483 /* We start the reset timer */
484 mod_timer(&sgdma->reset_timer, jiffies + HZ);
487 sgslot = (sgslot + 1) % NUM_SG_DMA;
490 spin_unlock_irqrestore(&sgdma->lock, flags);
494 * Queue a scatter-gather DMA transfer from the camera to memory.
495 * Returns zero if the transfer was successfully queued, or non-zero
496 * if all of the scatter-gather slots are already in use.
498 int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
499 const struct scatterlist *sglist, int sglen,
500 int len, sgdma_callback_t callback, void *arg)
503 struct sgdma_state *sg_state;
505 if ((sglen < 0) || ((sglen > 0) && !sglist))
508 spin_lock_irqsave(&sgdma->lock, flags);
510 if (!sgdma->free_sgdma) {
511 spin_unlock_irqrestore(&sgdma->lock, flags);
515 sg_state = sgdma->sg_state + sgdma->next_sgdma;
517 sg_state->sglist = sglist;
518 sg_state->sglen = sglen;
519 sg_state->next_sglist = 0;
520 sg_state->bytes_read = 0;
522 sg_state->queued_sglist = 0;
524 sg_state->callback = callback;
527 sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
530 spin_unlock_irqrestore(&sgdma->lock, flags);
532 omap24xxcam_sgdma_process(sgdma);
537 /* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
538 * Any queued scatter-gather DMA transactions that have not yet been started
539 * will remain queued. The DMA controller will be idle after this routine
540 * completes. When the scatter-gather queue is restarted, the next
541 * scatter-gather DMA transfer will begin at the start of a new transaction.
543 void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
547 struct sgdma_state *sg_state;
548 u32 csr = CAMDMA_CSR_TRANS_ERR;
550 /* stop any DMA transfers in progress */
551 omap24xxcam_dma_stop(&sgdma->dma, csr);
553 spin_lock_irqsave(&sgdma->lock, flags);
555 if (sgdma->free_sgdma < NUM_SG_DMA) {
556 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
557 sg_state = sgdma->sg_state + sgslot;
558 if (sg_state->next_sglist != 0) {
559 /* This DMA transfer was in progress, so abort it. */
560 sgdma_callback_t callback = sg_state->callback;
561 void *arg = sg_state->arg;
565 /* leave interrupts masked */
566 spin_unlock(&sgdma->lock);
567 (*callback) (sgdma, csr, arg);
568 spin_lock(&sgdma->lock);
573 spin_unlock_irqrestore(&sgdma->lock, flags);
576 void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
578 void (*reset_callback)(unsigned long data),
579 unsigned long reset_callback_data)
583 spin_lock_init(&sgdma->lock);
584 sgdma->free_sgdma = NUM_SG_DMA;
585 sgdma->next_sgdma = 0;
586 for (sg = 0; sg < NUM_SG_DMA; sg++) {
587 sgdma->sg_state[sg].sglen = 0;
588 sgdma->sg_state[sg].next_sglist = 0;
589 sgdma->sg_state[sg].bytes_read = 0;
590 sgdma->sg_state[sg].queued_sglist = 0;
591 sgdma->sg_state[sg].csr = 0;
592 sgdma->sg_state[sg].callback = NULL;
593 sgdma->sg_state[sg].arg = NULL;
596 omap24xxcam_dma_init(&sgdma->dma, base);
597 setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data);