^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/arm/mach-omap1/lcd_dma.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Extracted from arch/arm/plat-omap/dma.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2003 - 2008 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Juha Yrjölä <juha.yrjola@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Graphics DMA and LCD DMA graphics tranformations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * by Imre Deak <imre.deak@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Copyright (C) 2009 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Support functions for the OMAP internal DMA channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/omap-dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <mach/hardware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <mach/lcdc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int omap_lcd_dma_running(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * On OMAP1510, internal LCD controller will start the transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * when it gets enabled, so assume DMA running if LCD enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Check if LCD DMA is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (cpu_is_omap16xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct lcd_dma_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void (*callback)(u16 status, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void *cb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int rotate, data_type, xres, yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int vxres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int mirror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int xscale, yscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int ext_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int src_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int single_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } lcd_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int data_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) lcd_dma.addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) lcd_dma.data_type = data_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) lcd_dma.xres = fb_xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) lcd_dma.yres = fb_yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) EXPORT_SYMBOL(omap_set_lcd_dma_b1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) void omap_set_lcd_dma_ext_controller(int external)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) lcd_dma.ext_ctrl = external;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void omap_set_lcd_dma_single_transfer(int single)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) lcd_dma.single_transfer = single;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void omap_set_lcd_dma_b1_rotation(int rotate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) lcd_dma.rotate = rotate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void omap_set_lcd_dma_b1_mirror(int mirror)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) lcd_dma.mirror = mirror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pr_err("DMA virtual resolution is not supported in 1510 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) lcd_dma.vxres = vxres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) lcd_dma.xscale = xscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) lcd_dma.yscale = yscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void set_b1_regs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned long top, bottom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int es;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long en, fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) long ei, fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned long vxres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int xscale, yscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) switch (lcd_dma.data_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case OMAP_DMA_DATA_TYPE_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) es = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case OMAP_DMA_DATA_TYPE_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) es = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case OMAP_DMA_DATA_TYPE_S32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) es = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) BUG_ON(vxres < lcd_dma.xres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define PIXADDR(x, y) (lcd_dma.addr + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ((y) * vxres * yscale + (x) * xscale) * es)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) switch (lcd_dma.rotate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!lcd_dma.mirror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) top = PIXADDR(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* 1510 DMA requires the bottom address to be 2 more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * than the actual last memory access location. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (cpu_is_omap15xx() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bottom += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ei = PIXSTEP(0, 0, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) top = PIXADDR(lcd_dma.xres - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) bottom = PIXADDR(0, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ei = PIXSTEP(1, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) en = lcd_dma.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) fn = lcd_dma.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case 90:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!lcd_dma.mirror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) top = PIXADDR(0, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) bottom = PIXADDR(lcd_dma.xres - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ei = PIXSTEP(0, 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bottom = PIXADDR(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ei = PIXSTEP(0, 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) en = lcd_dma.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) fn = lcd_dma.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case 180:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!lcd_dma.mirror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) bottom = PIXADDR(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ei = PIXSTEP(1, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) top = PIXADDR(0, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) bottom = PIXADDR(lcd_dma.xres - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ei = PIXSTEP(0, 0, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) en = lcd_dma.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) fn = lcd_dma.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 270:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!lcd_dma.mirror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) top = PIXADDR(lcd_dma.xres - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) bottom = PIXADDR(0, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ei = PIXSTEP(0, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) top = PIXADDR(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ei = PIXSTEP(0, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) en = lcd_dma.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) fn = lcd_dma.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return; /* Suppress warning about uninitialized vars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* 1610 regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) w = omap_readw(OMAP1610_DMA_LCD_CSDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) w &= ~0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) w |= lcd_dma.data_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) omap_writew(w, OMAP1610_DMA_LCD_CSDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) w = omap_readw(OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* Always set the source port as SDRAM for now*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) w &= ~(0x03 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (lcd_dma.callback != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) w |= 1 << 1; /* Block interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) w &= ~(1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) omap_writew(w, OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!(lcd_dma.rotate || lcd_dma.mirror ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) w = omap_readw(OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Set the double-indexed addressing mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) w |= (0x03 << 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) omap_writew(w, OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) w = omap_readw(OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (unlikely(!(w & (1 << 3)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Ack the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) w |= (1 << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) omap_writew(w, OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) lcd_dma.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (lcd_dma.callback != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) lcd_dma.callback(w, lcd_dma.cb_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) spin_lock_irq(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (lcd_dma.reserved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) spin_unlock_irq(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) printk(KERN_ERR "LCD DMA channel already reserved\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) lcd_dma.reserved = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) spin_unlock_irq(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) lcd_dma.callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) lcd_dma.cb_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) lcd_dma.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) lcd_dma.single_transfer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) lcd_dma.rotate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) lcd_dma.vxres = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) lcd_dma.mirror = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) lcd_dma.xscale = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) lcd_dma.yscale = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) lcd_dma.ext_ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) lcd_dma.src_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) EXPORT_SYMBOL(omap_request_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) void omap_free_lcd_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) spin_lock(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!lcd_dma.reserved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) spin_unlock(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) printk(KERN_ERR "LCD DMA is not reserved\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) lcd_dma.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) spin_unlock(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) EXPORT_SYMBOL(omap_free_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void omap_enable_lcd_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Set the Enable bit only if an external controller is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * connected. Otherwise the OMAP internal controller will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * start the transfer when it gets enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) w = omap_readw(OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) w |= 1 << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) omap_writew(w, OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) lcd_dma.active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) w = omap_readw(OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) w |= 1 << 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) omap_writew(w, OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) EXPORT_SYMBOL(omap_enable_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) void omap_setup_lcd_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) BUG_ON(lcd_dma.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Set some reasonable defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) set_b1_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) w = omap_readw(OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * If DMA was already active set the end_prog bit to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * the programmed register set loaded into the active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * register set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) w |= 1 << 11; /* End_prog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (!lcd_dma.single_transfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) w |= (3 << 8); /* Auto_init, repeat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) omap_writew(w, OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) EXPORT_SYMBOL(omap_setup_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) void omap_stop_lcd_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) lcd_dma.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) w = omap_readw(OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) w &= ~(1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) omap_writew(w, OMAP1610_DMA_LCD_CCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) w = omap_readw(OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) w &= ~(1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) omap_writew(w, OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) EXPORT_SYMBOL(omap_stop_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int __init omap_init_lcd_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!cpu_class_is_omap1())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u16 w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* this would prevent OMAP sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) w = omap_readw(OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) w &= ~(1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) omap_writew(w, OMAP1610_DMA_LCD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) spin_lock_init(&lcd_dma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) "LCD DMA", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (r != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pr_err("unable to request IRQ for LCD DMA (error %d)\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) arch_initcall(omap_init_lcd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)