vserver 1.9.5.x5
[linux-2.6.git] / arch / arm / mach-omap / dma.c
index cfb23d8..515aa6a 100644 (file)
@@ -4,6 +4,9 @@
  * Copyright (C) 2003 Nokia Corporation
  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
  * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
  *
  * Support functions for the OMAP internal DMA channels.
  *
@@ -26,6 +29,8 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 
+#include <asm/arch/tc.h>
+
 #define OMAP_DMA_ACTIVE                0x01
 
 #define OMAP_DMA_CCR_EN                (1 << 7)
@@ -87,6 +92,34 @@ static void clear_lch_regs(int lch)
                omap_writew(0, lch_base + i);
 }
 
+void omap_set_dma_priority(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;
+       }
+       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,
                                  int frame_count, int sync_mode)
 {
@@ -113,51 +146,38 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
        omap_writew(frame_count, OMAP_DMA_CFN(lch));
 
 }
-void omap_set_dma_constant_fill(int lch, u32 color)
+void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 {
        u16 w;
 
-#ifdef CONFIG_DEBUG_KERNEL
-       if (omap_dma_in_1510_mode()) {
-               printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode.");
-               BUG();
-               return;
-       }
-#endif
-       w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
-       w |= 0x01;
-       omap_writew(w, OMAP_DMA_CCR2(lch));
-
-       omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
-       omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
-
-       w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
-       w |= 1;         /* Channel type G */
-       omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
-}
-
-void omap_set_dma_transparent_copy(int lch, u32 color)
-{
-       u16 w;
+       BUG_ON(omap_dma_in_1510_mode());
 
-#ifdef CONFIG_DEBUG_KERNEL
-       if (omap_dma_in_1510_mode()) {
-               printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode.");
+       w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+       switch (mode) {
+       case OMAP_DMA_CONSTANT_FILL:
+               w |= 0x01;
+               break;
+       case OMAP_DMA_TRANSPARENT_COPY:
+               w |= 0x02;
+               break;
+       case OMAP_DMA_COLOR_DIS:
+               break;
+       default:
                BUG();
        }
-#endif
-       w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
-       w |= 0x02;
        omap_writew(w, OMAP_DMA_CCR2(lch));
 
-       omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
-       omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
-
        w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
-       w |= 1;         /* Channel type G */
+       /* Default is channel type 2D */
+       if (mode) {
+               omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+               omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+               w |= 1;         /* Channel type G */
+       }
        omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
 }
 
+
 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                             unsigned long src_start)
 {
@@ -192,22 +212,24 @@ void omap_set_dma_src_data_pack(int lch, int enable)
        omap_writew(w, OMAP_DMA_CSDP(lch));
 }
 
-void omap_set_dma_src_burst_mode(int lch, int burst_mode)
+void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 {
        u16 w;
 
        w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
        switch (burst_mode) {
+       case OMAP_DMA_DATA_BURST_DIS:
+               break;
        case OMAP_DMA_DATA_BURST_4:
                w |= (0x01 << 7);
                break;
        case OMAP_DMA_DATA_BURST_8:
-               w |= (0x03 << 7);
-               break;
+               /* not supported by current hardware
+                * w |= (0x03 << 7);
+                * fall through
+                */
        default:
-               printk(KERN_ERR "Invalid DMA burst mode\n");
                BUG();
-               return;
        }
        omap_writew(w, OMAP_DMA_CSDP(lch));
 }
@@ -246,12 +268,14 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
        omap_writew(w, OMAP_DMA_CSDP(lch));
 }
 
-void omap_set_dma_dest_burst_mode(int lch, int burst_mode)
+void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 {
        u16 w;
 
        w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
        switch (burst_mode) {
+       case OMAP_DMA_DATA_BURST_DIS:
+               break;
        case OMAP_DMA_DATA_BURST_4:
                w |= (0x01 << 14);
                break;
@@ -454,10 +478,6 @@ int omap_request_dma(int dev_id, const char *dev_name,
                        if (dev_id == 0)
                                break;
                }
-               if (dev_id != 0 && dma_chan[ch].dev_id == dev_id) {
-                       spin_unlock_irqrestore(&dma_chan_lock, flags);
-                       return -EAGAIN;
-               }
        }
        if (free_ch == -1) {
                spin_unlock_irqrestore(&dma_chan_lock, flags);
@@ -474,7 +494,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
        chan->data = data;
        chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
 
-       if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
+       if (cpu_is_omap16xx() || cpu_is_omap730()) {
                /* If the sync device is set, configure it dynamically. */
                if (dev_id != 0) {
                        set_gdma_dev(free_ch + 1, dev_id);
@@ -571,8 +591,15 @@ static struct lcd_dma_info {
        void (* callback)(u16 status, void *data);
        void *cb_data;
 
+       int active;
        unsigned long addr, size;
        int rotate, data_type, xres, yres;
+       int vxres;
+       int mirror;
+       int xscale, yscale;
+       int ext_ctrl;
+       int src_port;
+       int single_transfer;
 } lcd_dma;
 
 void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
@@ -584,14 +611,70 @@ void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
        lcd_dma.yres = fb_yres;
 }
 
+void omap_set_lcd_dma_src_port(int port)
+{
+       lcd_dma.src_port = port;
+}
+
+void omap_set_lcd_dma_ext_controller(int external)
+{
+       lcd_dma.ext_ctrl = external;
+}
+
+void omap_set_lcd_dma_single_transfer(int single)
+{
+       lcd_dma.single_transfer = single;
+}
+
+
+void omap_set_lcd_dma_b1_rotation(int rotate)
+{
+       if (omap_dma_in_1510_mode()) {
+               printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
+               BUG();
+               return;
+       }
+       lcd_dma.rotate = rotate;
+}
+
+void omap_set_lcd_dma_b1_mirror(int mirror)
+{
+       if (omap_dma_in_1510_mode()) {
+               printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
+               BUG();
+       }
+       lcd_dma.mirror = mirror;
+}
+
+void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
+{
+       if (omap_dma_in_1510_mode()) {
+               printk(KERN_ERR "DMA virtual resulotion is not supported "
+                               "in 1510 mode\n");
+               BUG();
+       }
+       lcd_dma.vxres = vxres;
+}
+
+void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
+{
+       if (omap_dma_in_1510_mode()) {
+               printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
+               BUG();
+       }
+       lcd_dma.xscale = xscale;
+       lcd_dma.yscale = yscale;
+}
+
 static void set_b1_regs(void)
 {
        unsigned long top, bottom;
        int es;
-       u16 w, en, fn;
-       s16 ei;
-       s32 fi;
-       u32 l;
+       u16 w;
+       unsigned long en, fn;
+       long ei, fi;
+       unsigned long vxres;
+       unsigned int xscale, yscale;
 
        switch (lcd_dma.data_type) {
        case OMAP_DMA_DATA_TYPE_S8:
@@ -608,25 +691,81 @@ static void set_b1_regs(void)
                return;
        }
 
-       if (lcd_dma.rotate == 0) {
-               top = lcd_dma.addr;
-               bottom = lcd_dma.addr + (lcd_dma.xres * lcd_dma.yres - 1) * es;
-               /* 1510 DMA requires the bottom address to be 2 more than the
-                * actual last memory access location. */
-               if (omap_dma_in_1510_mode() &&
-                   lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
-                       bottom += 2;
+       vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
+       xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
+       yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
+       BUG_ON(vxres < lcd_dma.xres);
+#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
+#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+       switch (lcd_dma.rotate) {
+       case 0:
+               if (!lcd_dma.mirror) {
+                       top = PIXADDR(0, 0);
+                       bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+                       /* 1510 DMA requires the bottom address to be 2 more
+                        * than the actual last memory access location. */
+                       if (omap_dma_in_1510_mode() &&
+                           lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+                               bottom += 2;
+                       ei = PIXSTEP(0, 0, 1, 0);
+                       fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
+               } else {
+                       top = PIXADDR(lcd_dma.xres - 1, 0);
+                       bottom = PIXADDR(0, lcd_dma.yres - 1);
+                       ei = PIXSTEP(1, 0, 0, 0);
+                       fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
+               }
                en = lcd_dma.xres;
                fn = lcd_dma.yres;
-               ei = 0;
-               fi = 0;
-       } else {
-               top = lcd_dma.addr + (lcd_dma.xres - 1) * es;
-               bottom = lcd_dma.addr + (lcd_dma.yres - 1) * lcd_dma.xres * es;
+               break;
+       case 90:
+               if (!lcd_dma.mirror) {
+                       top = PIXADDR(0, lcd_dma.yres - 1);
+                       bottom = PIXADDR(lcd_dma.xres - 1, 0);
+                       ei = PIXSTEP(0, 1, 0, 0);
+                       fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
+               } else {
+                       top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+                       bottom = PIXADDR(0, 0);
+                       ei = PIXSTEP(0, 1, 0, 0);
+                       fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
+               }
                en = lcd_dma.yres;
                fn = lcd_dma.xres;
-               ei = (lcd_dma.xres - 1) * es + 1;
-               fi = -(lcd_dma.xres * (lcd_dma.yres - 1) + 2) * 2 + 1;
+               break;
+       case 180:
+               if (!lcd_dma.mirror) {
+                       top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+                       bottom = PIXADDR(0, 0);
+                       ei = PIXSTEP(1, 0, 0, 0);
+                       fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
+               } else {
+                       top = PIXADDR(0, lcd_dma.yres - 1);
+                       bottom = PIXADDR(lcd_dma.xres - 1, 0);
+                       ei = PIXSTEP(0, 0, 1, 0);
+                       fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
+               }
+               en = lcd_dma.xres;
+               fn = lcd_dma.yres;
+               break;
+       case 270:
+               if (!lcd_dma.mirror) {
+                       top = PIXADDR(lcd_dma.xres - 1, 0);
+                       bottom = PIXADDR(0, lcd_dma.yres - 1);
+                       ei = PIXSTEP(0, 0, 0, 1);
+                       fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
+               } else {
+                       top = PIXADDR(0, 0);
+                       bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+                       ei = PIXSTEP(0, 0, 0, 1);
+                       fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
+               }
+               en = lcd_dma.yres;
+               fn = lcd_dma.xres;
+               break;
+       default:
+               BUG();
+               return; /* Supress warning about uninitialized vars */
        }
 
        if (omap_dma_in_1510_mode()) {
@@ -652,33 +791,50 @@ static void set_b1_regs(void)
        w |= lcd_dma.data_type;
        omap_writew(w, OMAP1610_DMA_LCD_CSDP);
 
-       if (!lcd_dma.rotate)
+       w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+       /* Always set the source port as SDRAM for now*/
+       w &= ~(0x03 << 6);
+       if (lcd_dma.ext_ctrl)
+               w |= 1 << 8;
+       else
+               w &= ~(1 << 8);
+       if (lcd_dma.callback != NULL)
+               w |= 1 << 1;            /* Block interrupt enable */
+       else
+               w &= ~(1 << 1);
+       omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+       if (!(lcd_dma.rotate || lcd_dma.mirror ||
+             lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
                return;
 
-       /* Rotation stuff */
-       l = omap_readw(OMAP1610_DMA_LCD_CSDP);
-       /* Disable burst access */
-       l &= ~(0x03 << 7);
-       omap_writew(l, OMAP1610_DMA_LCD_CSDP);
-
-       l = omap_readw(OMAP1610_DMA_LCD_CCR);
+       w = omap_readw(OMAP1610_DMA_LCD_CCR);
        /* Set the double-indexed addressing mode */
-       l |= (0x03 << 12);
-       omap_writew(l, OMAP1610_DMA_LCD_CCR);
+       w |= (0x03 << 12);
+       omap_writew(w, OMAP1610_DMA_LCD_CCR);
 
        omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
        omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
        omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
 }
 
-void omap_set_lcd_dma_b1_rotation(int rotate)
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
-       if (omap_dma_in_1510_mode()) {
-               printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
-               BUG();
-               return;
+       u16 w;
+
+       w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+       if (unlikely(!(w & (1 << 3)))) {
+               printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
+               return IRQ_NONE;
        }
-       lcd_dma.rotate = rotate;
+       /* Ack the IRQ */
+       w |= (1 << 3);
+       omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+       lcd_dma.active = 0;
+       if (lcd_dma.callback != NULL)
+               lcd_dma.callback(w, lcd_dma.cb_data);
+
+       return IRQ_HANDLED;
 }
 
 int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
@@ -695,6 +851,15 @@ int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
        spin_unlock_irq(&lcd_dma.lock);
        lcd_dma.callback = callback;
        lcd_dma.cb_data = data;
+       lcd_dma.active = 0;
+       lcd_dma.single_transfer = 0;
+       lcd_dma.rotate = 0;
+       lcd_dma.vxres = 0;
+       lcd_dma.mirror = 0;
+       lcd_dma.xscale = 0;
+       lcd_dma.yscale = 0;
+       lcd_dma.ext_ctrl = 0;
+       lcd_dma.src_port = 0;
 
        return 0;
 }
@@ -714,23 +879,97 @@ void omap_free_lcd_dma(void)
        spin_unlock(&lcd_dma.lock);
 }
 
-void omap_start_lcd_dma(void)
+void omap_enable_lcd_dma(void)
 {
+       u16 w;
+
+       /* Set the Enable bit only if an external controller is
+        * connected. Otherwise the OMAP internal controller will
+        * start the transfer when it gets enabled.
+        */
+       if (enable_1510_mode || !lcd_dma.ext_ctrl)
+               return;
+       w = omap_readw(OMAP1610_DMA_LCD_CCR);
+       w |= 1 << 7;
+       omap_writew(w, OMAP1610_DMA_LCD_CCR);
+       lcd_dma.active = 1;
+}
+
+void omap_setup_lcd_dma(void)
+{
+       BUG_ON(lcd_dma.active);
        if (!enable_1510_mode) {
                /* Set some reasonable defaults */
+               omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
                omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
                omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
-               omap_writew(0x5740, OMAP1610_DMA_LCD_CCR);
        }
        set_b1_regs();
-       if (!enable_1510_mode)
-               omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) | 1, OMAP1610_DMA_LCD_CCR);
+       if (!enable_1510_mode) {
+               u16 w;
+
+               w = omap_readw(OMAP1610_DMA_LCD_CCR);
+               /* If DMA was already active set the end_prog bit to have
+                * the programmed register set loaded into the active
+                * register set.
+                */
+               w |= 1 << 11;           /* End_prog */
+               if (!lcd_dma.single_transfer)
+                       w |= (3 << 8);  /* Auto_init, repeat */
+               omap_writew(w, OMAP1610_DMA_LCD_CCR);
+       }
 }
 
 void omap_stop_lcd_dma(void)
 {
-       if (!enable_1510_mode)
-               omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
+       lcd_dma.active = 0;
+       if (!enable_1510_mode && lcd_dma.ext_ctrl)
+               omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7),
+                           OMAP1610_DMA_LCD_CCR);
+}
+
+/*
+ * Clears any DMA state so the DMA engine is ready to restart with new buffers
+ * through omap_start_dma(). Any buffers in flight are discarded.
+ */
+void omap_clear_dma(int lch)
+{
+       unsigned long flags;
+       int status;
+
+       local_irq_save(flags);
+       omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
+                   OMAP_DMA_CCR(lch));
+       status = OMAP_DMA_CSR(lch);     /* clear pending interrupts */
+       local_irq_restore(flags);
+}
+
+/*
+ * Returns current physical source address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CSSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_src_pos(int lch)
+{
+       return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
+                            (OMAP_DMA_CSSA_U(lch) << 16));
+}
+
+/*
+ * Returns current physical destination address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CDSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_dst_pos(int lch)
+{
+       return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
+                            (OMAP_DMA_CDSA_U(lch) << 16));
 }
 
 static int __init omap_init_dma(void)
@@ -741,7 +980,7 @@ static int __init omap_init_dma(void)
                printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
                dma_chan_count = 9;
                enable_1510_mode = 1;
-       } else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
+       } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
                printk(KERN_INFO "OMAP DMA hardware version %d\n",
                       omap_readw(OMAP_DMA_HW_ID));
                printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
@@ -756,7 +995,7 @@ static int __init omap_init_dma(void)
                        w = omap_readw(OMAP_DMA_GSCR);
                        w |= 1 << 3;
                        omap_writew(w, OMAP_DMA_GSCR);
-                       dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
+                       dma_chan_count = 16;
                } else
                        dma_chan_count = 9;
        } else {
@@ -790,11 +1029,25 @@ static int __init omap_init_dma(void)
                        return r;
                }
        }
-
+       r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
+       if (r != 0) {
+               int i;
+
+               printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
+               for (i = 0; i < dma_chan_count; i++)
+                       free_irq(dma_irq[i], (void *) (i + 1));
+               return r;
+       }
        return 0;
 }
+
 arch_initcall(omap_init_dma);
 
+
+EXPORT_SYMBOL(omap_get_dma_src_pos);
+EXPORT_SYMBOL(omap_get_dma_dst_pos);
+EXPORT_SYMBOL(omap_clear_dma);
+EXPORT_SYMBOL(omap_set_dma_priority);
 EXPORT_SYMBOL(omap_request_dma);
 EXPORT_SYMBOL(omap_free_dma);
 EXPORT_SYMBOL(omap_start_dma);
@@ -803,8 +1056,7 @@ EXPORT_SYMBOL(omap_enable_dma_irq);
 EXPORT_SYMBOL(omap_disable_dma_irq);
 
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
-EXPORT_SYMBOL(omap_set_dma_constant_fill);
-EXPORT_SYMBOL(omap_set_dma_transparent_copy);
+EXPORT_SYMBOL(omap_set_dma_color_mode);
 
 EXPORT_SYMBOL(omap_set_dma_src_params);
 EXPORT_SYMBOL(omap_set_dma_src_index);
@@ -821,7 +1073,14 @@ EXPORT_SYMBOL(omap_dma_unlink_lch);
 
 EXPORT_SYMBOL(omap_request_lcd_dma);
 EXPORT_SYMBOL(omap_free_lcd_dma);
-EXPORT_SYMBOL(omap_start_lcd_dma);
+EXPORT_SYMBOL(omap_enable_lcd_dma);
+EXPORT_SYMBOL(omap_setup_lcd_dma);
 EXPORT_SYMBOL(omap_stop_lcd_dma);
 EXPORT_SYMBOL(omap_set_lcd_dma_b1);
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
 EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
+