]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-omap/dma.c
h63xx: lcd support
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dma.c
index 0ec472f25abff0d9f3100120fb058bdb679be56e..6eb66bfecea201eba2136fa2c4278bdb6ef67d0e 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/hardware.h>
 #include <asm/dma.h>
 #include <asm/io.h>
+#include <asm/mach-types.h>
 
 #include <asm/arch/tc.h>
 
@@ -64,7 +65,7 @@ static int dma_chan_count;
 static spinlock_t dma_chan_lock;
 static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
 
-const static u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
+static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
        INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
        INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
        INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
@@ -153,7 +154,7 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
        OMAP_DMA_CSDP_REG(lch) &= ~0x03;
        OMAP_DMA_CSDP_REG(lch) |= data_type;
 
-       if (cpu_class_is_omap1()) {     
+       if (cpu_class_is_omap1()) {
                OMAP_DMA_CCR_REG(lch) &= ~(1 << 5);
                if (sync_mode == OMAP_DMA_SYNC_FRAME)
                        OMAP_DMA_CCR_REG(lch) |= 1 << 5;
@@ -247,7 +248,7 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 
        if (cpu_is_omap24xx())
                OMAP2_DMA_CSSA_REG(lch) = src_start;
-               
+
        OMAP_DMA_CSEI_REG(lch) = src_ei;
        OMAP_DMA_CSFI_REG(lch) = src_fi;
 }
@@ -323,7 +324,7 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
        }
 
        if (cpu_is_omap24xx())
-               OMAP2_DMA_CDSA_REG(lch) = dest_start;   
+               OMAP2_DMA_CDSA_REG(lch) = dest_start;
 
        OMAP_DMA_CDEI_REG(lch) = dst_ei;
        OMAP_DMA_CDFI_REG(lch) = dst_fi;
@@ -473,6 +474,9 @@ int omap_request_dma(int dev_id, const char *dev_name,
        chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ |
                                OMAP_DMA_BLOCK_IRQ;
 
+       if (cpu_is_omap24xx())
+               chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ;
+
        if (cpu_is_omap16xx()) {
                /* If the sync device is set, configure it dynamically. */
                if (dev_id != 0) {
@@ -488,7 +492,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
 
        if (cpu_is_omap24xx()) {
                omap2_enable_irq_lch(free_ch);
-               
+
                omap_enable_channel_irq(free_ch);
                /* Clear the CSR register and IRQ status register */
                OMAP_DMA_CSR_REG(free_ch) = 0x0;
@@ -836,20 +840,26 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id,
 
 static int omap2_dma_handle_ch(int ch)
 {
-       u32 val = OMAP_DMA_CSR_REG(ch);
+       u32 status = OMAP_DMA_CSR_REG(ch);
+       u32 val;
 
-       if (!val)
+       if (!status)
                return 0;
        if (unlikely(dma_chan[ch].dev_id == -1))
                return 0;
-       if (unlikely(val & OMAP_DMA_TOUT_IRQ))
+       /* REVISIT: According to 24xx TRM, there's no TOUT_IE */
+       if (unlikely(status & OMAP_DMA_TOUT_IRQ))
                printk(KERN_INFO "DMA timeout with device %d\n",
                       dma_chan[ch].dev_id);
-       if (unlikely(val & OMAP_DMA_DROP_IRQ))
+       if (unlikely(status & OMAP_DMA_DROP_IRQ))
                printk(KERN_INFO
                       "DMA synchronization event drop occurred with device "
                       "%d\n", dma_chan[ch].dev_id);
 
+       if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
+               printk(KERN_INFO "DMA transaction error with device %d\n",
+                      dma_chan[ch].dev_id);
+
        OMAP_DMA_CSR_REG(ch) = 0x20;
 
        val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
@@ -857,10 +867,8 @@ static int omap2_dma_handle_ch(int ch)
        val = 1 << (ch);
        omap_writel(val, OMAP_DMA4_IRQSTATUS_L0);
 
-       if (likely(dma_chan[ch].callback != NULL)){
-               val = OMAP_DMA_CSR_REG(ch);
-               dma_chan[ch].callback(ch, val, dma_chan[ch].data);
-       }
+       if (likely(dma_chan[ch].callback != NULL))
+               dma_chan[ch].callback(ch, status, dma_chan[ch].data);
 
        return 0;
 }
@@ -1079,6 +1087,10 @@ static void set_b1_regs(void)
        }
 
        if (omap_dma_in_1510_mode()) {
+               u16 l = omap_readw(OMAP1510_DMA_LCD_CTRL);
+               l &= ~(1 << 6);
+               omap_writew (l, OMAP1510_DMA_LCD_CTRL);
+
                omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
                omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
                omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
@@ -1251,6 +1263,11 @@ void omap_stop_lcd_dma(void)
        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
 }
 
+int omap_lcd_dma_ext_running(void)
+{
+       return lcd_dma.ext_ctrl && lcd_dma.active;
+}
+
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
@@ -1382,6 +1399,7 @@ EXPORT_SYMBOL(omap_free_lcd_dma);
 EXPORT_SYMBOL(omap_enable_lcd_dma);
 EXPORT_SYMBOL(omap_setup_lcd_dma);
 EXPORT_SYMBOL(omap_stop_lcd_dma);
+EXPORT_SYMBOL(omap_lcd_dma_ext_running);
 EXPORT_SYMBOL(omap_set_lcd_dma_b1);
 EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
 EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);