X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap%2Fdma.c;h=515aa6a5e4d0c8f1eb75daf93d68a876f27ee578;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=cfb23d894a958af55e8fb40214f9aaf319d6ba7c;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c index cfb23d894..515aa6a5e 100644 --- a/arch/arm/mach-omap/dma.c +++ b/arch/arm/mach-omap/dma.c @@ -4,6 +4,9 @@ * Copyright (C) 2003 Nokia Corporation * Author: Juha Yrjölä * DMA channel linking for 1610 by Samuel Ortiz + * Graphics DMA and LCD DMA graphics tranformations + * by Imre Deak + * 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 #include +#include + #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); +