]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: Additional 24xx DMA fixes and functions
authorTony Lindgren <tony@atomide.com>
Mon, 12 Jun 2006 21:03:30 +0000 (14:03 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 12 Jun 2006 21:03:30 +0000 (14:03 -0700)
- DMA priority is set for each channel on 24xx, not for each port

- Add support for setting 24xx DMA write mode

- Add support for changing dma callback function and data

Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/plat-omap/dma.c
drivers/video/omap/omapfb_main.c
include/asm-arm/arch-omap/dma.h

index c5d0214ef1911f1d0d4769f68642ecd60139cea9..ab0eff0466be18aae7099335d51482c97896a1f5 100644 (file)
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch)
                omap_writew(0, lch_base + i);
 }
 
-void omap_set_dma_priority(int dst_port, int priority)
+void omap_set_dma_priority(int lch, int dst_port, int priority)
 {
        unsigned long reg;
        u32 l;
 
-       switch (dst_port) {
-       case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
-               reg = OMAP_TC_OCPT1_PRIOR;
-               break;
-       case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
-               reg = OMAP_TC_OCPT2_PRIOR;
-               break;
-       case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
-               reg = OMAP_TC_EMIFF_PRIOR;
-               break;
-       case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
-               reg = OMAP_TC_EMIFS_PRIOR;
-               break;
-       default:
-               BUG();
-               return;
+       if (cpu_class_is_omap1()) {
+               switch (dst_port) {
+               case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
+                       reg = OMAP_TC_OCPT1_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
+                       reg = OMAP_TC_OCPT2_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
+                       reg = OMAP_TC_EMIFF_PRIOR;
+                       break;
+               case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
+                       reg = OMAP_TC_EMIFS_PRIOR;
+                       break;
+               default:
+                       BUG();
+                       return;
+               }
+               l = omap_readl(reg);
+               l &= ~(0xf << 8);
+               l |= (priority & 0xf) << 8;
+               omap_writel(l, reg);
+       }
+
+       if (cpu_is_omap24xx()) {
+               if (priority)
+                       OMAP_DMA_CCR_REG(lch) |= (1 << 6);
+               else
+                       OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
        }
-       l = omap_readl(reg);
-       l &= ~(0xf << 8);
-       l |= (priority & 0xf) << 8;
-       omap_writel(l, reg);
 }
 
 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
@@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
        OMAP1_DMA_LCH_CTRL_REG(lch) = w;
 }
 
+void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
+{
+       if (cpu_is_omap24xx()) {
+               OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
+               OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
+       }
+}
+
 /* Note that src_port is only for omap1 */
 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                             unsigned long src_start,
@@ -697,6 +714,28 @@ void omap_stop_dma(int lch)
        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 
+/*
+ * Allows changing the DMA callback function or data. This may be needed if
+ * the driver shares a single DMA channel for multiple dma triggers.
+ */
+int omap_set_dma_callback(int lch,
+                         void (* callback)(int lch, u16 ch_status, void *data),
+                         void *data)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dma_chan_lock, flags);
+       if (dma_chan[lch].dev_id == -1) {
+               printk(KERN_ERR "DMA callback for not set for free channel\n");
+               return -EINVAL;
+       }
+       dma_chan[lch].callback = callback;
+       dma_chan[lch].data = data;
+       spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+       return 0;
+}
+
 /*
  * Returns current physical source address for the given DMA channel.
  * If the channel is running the caller must disable interrupts prior calling
index dd34c7ab0e4eda984caa5abd713266ed57d89ee6..5a013b6eaca6b3337b04c939bb3b24f8f2e1693f 100644 (file)
@@ -1337,7 +1337,8 @@ static int omapfb_do_probe(struct platform_device *pdev, struct lcd_panel *panel
 
 #ifdef CONFIG_FB_OMAP_DMA_TUNE
        /* Set DMA priority for EMIFF access to highest */
-       omap_set_dma_priority(OMAP_DMA_PORT_EMIFF, 15);
+       if (cpu_class_is_omap1())
+               omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);
 #endif
 
        r = ctrl_change_mode(fbdev);
index 1b1b02307e77f5c600ed32064915bf0594158511..7f152d5fa120c663c70dd447d4aace50fac7881a 100644 (file)
@@ -331,6 +331,12 @@ enum omap_dma_color_mode {
        OMAP_DMA_TRANSPARENT_COPY
 };
 
+enum omap_dma_write_mode {
+       OMAP_DMA_WRITE_NON_POSTED = 0,
+       OMAP_DMA_WRITE_POSTED,
+       OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
 struct omap_dma_channel_params {
        int data_type;          /* data type 8,16,32 */
        int elem_count;         /* number of elements in a frame */
@@ -356,7 +362,7 @@ struct omap_dma_channel_params {
 };
 
 
-extern void omap_set_dma_priority(int dst_port, int priority);
+extern void omap_set_dma_priority(int lch, int dst_port, int priority);
 extern int omap_request_dma(int dev_id, const char *dev_name,
                            void (* callback)(int lch, u16 ch_status, void *data),
                            void *data, int *dma_ch);
@@ -371,6 +377,7 @@ extern void omap_set_dma_transfer_params(int lch, int data_type,
                                         int dma_trigger, int src_or_dst_synch);
 extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
                                    u32 color);
+extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
 
 extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                                    unsigned long src_start,
@@ -394,6 +401,9 @@ extern void omap_set_dma_params(int lch,
 extern void omap_dma_link_lch (int lch_head, int lch_queue);
 extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
 
+extern int omap_set_dma_callback(int lch,
+                       void (* callback)(int lch, u16 ch_status, void *data),
+                       void *data);
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
 extern int omap_get_dma_src_addr_counter(int lch);