diff options
author | Tony Lindgren <tony@atomide.com> | 2005-07-10 19:58:13 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-07-10 19:58:13 +0100 |
commit | 60906a8a4e07eb179a2ed90dda23fa36972c6336 (patch) | |
tree | 42105cffbdb2d8ef3275d161cac514ecd0504d2b /arch | |
parent | f577ffd75c02b6087d5bf5ca89f806b10f2a0246 (diff) |
[PATCH] ARM: 2807/1: OMAP update 7a/11: Move arch-omap to plat-omap
Patch from Tony Lindgren
This patch move common OMAP code from arch-omap to plat-omap
directory.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap/Kconfig | 99 | ||||
-rw-r--r-- | arch/arm/mach-omap/Makefile | 16 | ||||
-rw-r--r-- | arch/arm/mach-omap/common.c | 135 | ||||
-rw-r--r-- | arch/arm/mach-omap/common.h | 36 | ||||
-rw-r--r-- | arch/arm/mach-omap/dma.c | 1086 | ||||
-rw-r--r-- | arch/arm/mach-omap/gpio.c | 762 | ||||
-rw-r--r-- | arch/arm/mach-omap/mcbsp.c | 685 | ||||
-rw-r--r-- | arch/arm/mach-omap/mux.c | 163 | ||||
-rw-r--r-- | arch/arm/mach-omap/ocpi.c | 114 | ||||
-rw-r--r-- | arch/arm/mach-omap/pm.c | 632 | ||||
-rw-r--r-- | arch/arm/mach-omap/sleep.S | 314 | ||||
-rw-r--r-- | arch/arm/mach-omap/usb.c | 593 |
12 files changed, 0 insertions, 4635 deletions
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig deleted file mode 100644 index a72fe55b513..00000000000 --- a/arch/arm/mach-omap/Kconfig +++ /dev/null @@ -1,99 +0,0 @@ -if ARCH_OMAP - -menu "TI OMAP Implementations" - -config ARCH_OMAP_OTG - bool - -choice - prompt "OMAP System Type" - default ARCH_OMAP1 - -config ARCH_OMAP1 - bool "TI OMAP1" - -config ARCH_OMAP2 - bool "TI OMAP2" - -endchoice - -comment "OMAP Feature Selections" - -config OMAP_MUX - bool "OMAP multiplexing support" - depends on ARCH_OMAP - default y - help - Pin multiplexing support for OMAP boards. If your bootloader - sets the multiplexing correctly, say N. Otherwise, or if unsure, - say Y. - -config OMAP_MUX_DEBUG - bool "Multiplexing debug output" - depends on OMAP_MUX - default n - help - Makes the multiplexing functions print out a lot of debug info. - This is useful if you want to find out the correct values of the - multiplexing registers. - -config OMAP_MUX_WARNINGS - bool "Warn about pins the bootloader didn't set up" - depends on OMAP_MUX - default y - help - Choose Y here to warn whenever driver initialization logic needs - to change the pin multiplexing setup. When there are no warnings - printed, it's safe to deselect OMAP_MUX for your product. - -choice - prompt "System timer" - default OMAP_MPU_TIMER - -config OMAP_MPU_TIMER - bool "Use mpu timer" - help - Select this option if you want to use the OMAP mpu timer. This - timer provides more intra-tick resolution than the 32KHz timer, - but consumes more power. - -config OMAP_32K_TIMER - bool "Use 32KHz timer" - depends on ARCH_OMAP16XX - help - Select this option if you want to enable the OMAP 32KHz timer. - This timer saves power compared to the OMAP_MPU_TIMER, and has - support for no tick during idle. The 32KHz timer provides less - intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is - currently only available for OMAP-16xx. - -endchoice - -config OMAP_32K_TIMER_HZ - int "Kernel internal timer frequency for 32KHz timer" - range 32 1024 - depends on OMAP_32K_TIMER - default "128" - help - Kernel internal timer frequency should be a divisor of 32768, - such as 64 or 128. - -choice - prompt "Low-level debug console UART" - depends on ARCH_OMAP - default OMAP_LL_DEBUG_UART1 - -config OMAP_LL_DEBUG_UART1 - bool "UART1" - -config OMAP_LL_DEBUG_UART2 - bool "UART2" - -config OMAP_LL_DEBUG_UART3 - bool "UART3" - -endchoice - -endmenu - -endif diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile deleted file mode 100644 index 3be25ebfc45..00000000000 --- a/arch/arm/mach-omap/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Common support -obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o -obj-m := -obj-n := -obj- := - -# OCPI interconnect support for 1710, 1610 and 5912 -obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o - -# Power Management -obj-$(CONFIG_PM) += pm.o sleep.o - diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c deleted file mode 100644 index b6a5b39e7e8..00000000000 --- a/arch/arm/mach-omap/common.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * linux/arch/arm/mach-omap/common.c - * - * Code common to all OMAP machines. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/pm.h> -#include <linux/console.h> -#include <linux/serial.h> -#include <linux/tty.h> -#include <linux/serial_8250.h> -#include <linux/serial_reg.h> - -#include <asm/hardware.h> -#include <asm/system.h> -#include <asm/pgtable.h> -#include <asm/mach/map.h> -#include <asm/hardware/clock.h> -#include <asm/io.h> -#include <asm/mach-types.h> - -#include <asm/arch/board.h> -#include <asm/arch/mux.h> -#include <asm/arch/fpga.h> - -#include "clock.h" - -#define NO_LENGTH_CHECK 0xffffffff - -extern int omap_bootloader_tag_len; -extern u8 omap_bootloader_tag[]; - -struct omap_board_config_kernel *omap_board_config; -int omap_board_config_size = 0; - -static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) -{ - struct omap_board_config_kernel *kinfo = NULL; - int i; - -#ifdef CONFIG_OMAP_BOOT_TAG - struct omap_board_config_entry *info = NULL; - - if (omap_bootloader_tag_len > 4) - info = (struct omap_board_config_entry *) omap_bootloader_tag; - while (info != NULL) { - u8 *next; - - if (info->tag == tag) { - if (skip == 0) - break; - skip--; - } - - if ((info->len & 0x03) != 0) { - /* We bail out to avoid an alignment fault */ - printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n", - info->len, info->tag); - return NULL; - } - next = (u8 *) info + sizeof(*info) + info->len; - if (next >= omap_bootloader_tag + omap_bootloader_tag_len) - info = NULL; - else - info = (struct omap_board_config_entry *) next; - } - if (info != NULL) { - /* Check the length as a lame attempt to check for - * binary inconsistancy. */ - if (len != NO_LENGTH_CHECK) { - /* Word-align len */ - if (len & 0x03) - len = (len + 3) & ~0x03; - if (info->len != len) { - printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n", - tag, len, info->len); - return NULL; - } - } - if (len_out != NULL) - *len_out = info->len; - return info->data; - } -#endif - /* Try to find the config from the board-specific structures - * in the kernel. */ - for (i = 0; i < omap_board_config_size; i++) { - if (omap_board_config[i].tag == tag) { - kinfo = &omap_board_config[i]; - break; - } - } - if (kinfo == NULL) - return NULL; - return kinfo->data; -} - -const void *__omap_get_config(u16 tag, size_t len, int nr) -{ - return get_config(tag, len, nr, NULL); -} -EXPORT_SYMBOL(__omap_get_config); - -const void *omap_get_var_config(u16 tag, size_t *len) -{ - return get_config(tag, NO_LENGTH_CHECK, 0, len); -} -EXPORT_SYMBOL(omap_get_var_config); - -static int __init omap_add_serial_console(void) -{ - const struct omap_serial_console_config *info; - - info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, - struct omap_serial_console_config); - if (info != NULL && info->console_uart) { - static char speed[11], *opt = NULL; - - if (info->console_speed) { - snprintf(speed, sizeof(speed), "%u", info->console_speed); - opt = speed; - } - return add_preferred_console("ttyS", info->console_uart - 1, opt); - } - return 0; -} -console_initcall(omap_add_serial_console); diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h deleted file mode 100644 index bb257344f52..00000000000 --- a/arch/arm/mach-omap/common.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * linux/arch/arm/mach-omap/common.h - * - * Header for code common to all OMAP machines. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H -#define __ARCH_ARM_MACH_OMAP_COMMON_H - -struct sys_timer; - -extern void omap_map_common_io(void); -extern struct sys_timer omap_timer; -extern void omap_serial_init(int ports[]); - -#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c deleted file mode 100644 index 7a9ebe80d6f..00000000000 --- a/arch/arm/mach-omap/dma.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* - * linux/arch/arm/omap/dma.c - * - * 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. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/errno.h> -#include <linux/interrupt.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/hardware.h> -#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) - -#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) - -static int enable_1510_mode = 0; - -struct omap_dma_lch { - int next_lch; - int dev_id; - u16 saved_csr; - u16 enabled_irqs; - const char *dev_name; - void (* callback)(int lch, u16 ch_status, void *data); - void *data; - long flags; -}; - -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 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, - INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13, - INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD -}; - -static inline int get_gdma_dev(int req) -{ - u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; - int shift = ((req - 1) % 5) * 6; - - return ((omap_readl(reg) >> shift) & 0x3f) + 1; -} - -static inline void set_gdma_dev(int req, int dev) -{ - u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; - int shift = ((req - 1) % 5) * 6; - u32 l; - - l = omap_readl(reg); - l &= ~(0x3f << shift); - l |= (dev - 1) << shift; - omap_writel(l, reg); -} - -static void clear_lch_regs(int lch) -{ - int i; - u32 lch_base = OMAP_DMA_BASE + lch * 0x40; - - for (i = 0; i < 0x2c; i += 2) - 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) -{ - u16 w; - - w = omap_readw(OMAP_DMA_CSDP(lch)); - w &= ~0x03; - w |= data_type; - omap_writew(w, OMAP_DMA_CSDP(lch)); - - w = omap_readw(OMAP_DMA_CCR(lch)); - w &= ~(1 << 5); - if (sync_mode == OMAP_DMA_SYNC_FRAME) - w |= 1 << 5; - omap_writew(w, OMAP_DMA_CCR(lch)); - - w = omap_readw(OMAP_DMA_CCR2(lch)); - w &= ~(1 << 2); - if (sync_mode == OMAP_DMA_SYNC_BLOCK) - w |= 1 << 2; - omap_writew(w, OMAP_DMA_CCR2(lch)); - - omap_writew(elem_count, OMAP_DMA_CEN(lch)); - omap_writew(frame_count, OMAP_DMA_CFN(lch)); - -} -void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) -{ - u16 w; - - BUG_ON(omap_dma_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(); - } - omap_writew(w, OMAP_DMA_CCR2(lch)); - - w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; - /* 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) -{ - u16 w; - - w = omap_readw(OMAP_DMA_CSDP(lch)); - w &= ~(0x1f << 2); - w |= src_port << 2; - omap_writew(w, OMAP_DMA_CSDP(lch)); - - w = omap_readw(OMAP_DMA_CCR(lch)); - w &= ~(0x03 << 12); - w |= src_amode << 12; - omap_writew(w, OMAP_DMA_CCR(lch)); - - omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch)); - omap_writew(src_start, OMAP_DMA_CSSA_L(lch)); -} - -void omap_set_dma_src_index(int lch, int eidx, int fidx) -{ - omap_writew(eidx, OMAP_DMA_CSEI(lch)); - omap_writew(fidx, OMAP_DMA_CSFI(lch)); -} - -void omap_set_dma_src_data_pack(int lch, int enable) -{ - u16 w; - - w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6); - w |= enable ? (1 << 6) : 0; - omap_writew(w, OMAP_DMA_CSDP(lch)); -} - -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: - /* not supported by current hardware - * w |= (0x03 << 7); - * fall through - */ - default: - BUG(); - } - omap_writew(w, OMAP_DMA_CSDP(lch)); -} - -void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, - unsigned long dest_start) -{ - u16 w; - - w = omap_readw(OMAP_DMA_CSDP(lch)); - w &= ~(0x1f << 9); - w |= dest_port << 9; - omap_writew(w, OMAP_DMA_CSDP(lch)); - - w = omap_readw(OMAP_DMA_CCR(lch)); - w &= ~(0x03 << 14); - w |= dest_amode << 14; - omap_writew(w, OMAP_DMA_CCR(lch)); - - omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch)); - omap_writew(dest_start, OMAP_DMA_CDSA_L(lch)); -} - -void omap_set_dma_dest_index(int lch, int eidx, int fidx) -{ - omap_writew(eidx, OMAP_DMA_CDEI(lch)); - omap_writew(fidx, OMAP_DMA_CDFI(lch)); -} - -void omap_set_dma_dest_data_pack(int lch, int enable) -{ - u16 w; - - w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13); - w |= enable ? (1 << 13) : 0; - omap_writew(w, OMAP_DMA_CSDP(lch)); -} - -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; - case OMAP_DMA_DATA_BURST_8: - w |= (0x03 << 14); - break; - default: - printk(KERN_ERR "Invalid DMA burst mode\n"); - BUG(); - return; - } - omap_writew(w, OMAP_DMA_CSDP(lch)); -} - -static inline void init_intr(int lch) -{ - u16 w; - - /* Read CSR to make sure it's cleared. */ - w = omap_readw(OMAP_DMA_CSR(lch)); - /* Enable some nice interrupts. */ - omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch)); - dma_chan[lch].flags |= OMAP_DMA_ACTIVE; -} - -static inline void enable_lnk(int lch) -{ - u16 w; - - /* Clear the STOP_LNK bits */ - w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); - w &= ~(1 << 14); - omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); - - /* And set the ENABLE_LNK bits */ - if (dma_chan[lch].next_lch != -1) - omap_writew(dma_chan[lch].next_lch | (1 << 15), - OMAP_DMA_CLNK_CTRL(lch)); -} - -static inline void disable_lnk(int lch) -{ - u16 w; - - /* Disable interrupts */ - omap_writew(0, OMAP_DMA_CICR(lch)); - - /* Set the STOP_LNK bit */ - w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); - w |= (1 << 14); - w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); - - dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; -} - -void omap_start_dma(int lch) -{ - u16 w; - - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { - int next_lch, cur_lch; - char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; - - dma_chan_link_map[lch] = 1; - /* Set the link register of the first channel */ - enable_lnk(lch); - - memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); - cur_lch = dma_chan[lch].next_lch; - do { - next_lch = dma_chan[cur_lch].next_lch; - - /* The loop case: we've been here already */ - if (dma_chan_link_map[cur_lch]) - break; - /* Mark the current channel */ - dma_chan_link_map[cur_lch] = 1; - - enable_lnk(cur_lch); - init_intr(cur_lch); - - cur_lch = next_lch; - } while (next_lch != -1); - } - - init_intr(lch); - - w = omap_readw(OMAP_DMA_CCR(lch)); - w |= OMAP_DMA_CCR_EN; - omap_writew(w, OMAP_DMA_CCR(lch)); - dma_chan[lch].flags |= OMAP_DMA_ACTIVE; -} - -void omap_stop_dma(int lch) -{ - u16 w; - - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { - int next_lch, cur_lch = lch; - char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; - - memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); - do { - /* The loop case: we've been here already */ - if (dma_chan_link_map[cur_lch]) - break; - /* Mark the current channel */ - dma_chan_link_map[cur_lch] = 1; - - disable_lnk(cur_lch); - - next_lch = dma_chan[cur_lch].next_lch; - cur_lch = next_lch; - } while (next_lch != -1); - - return; - } - /* Disable all interrupts on the channel */ - omap_writew(0, OMAP_DMA_CICR(lch)); - - w = omap_readw(OMAP_DMA_CCR(lch)); - w &= ~OMAP_DMA_CCR_EN; - omap_writew(w, OMAP_DMA_CCR(lch)); - dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; -} - -void omap_enable_dma_irq(int lch, u16 bits) -{ - dma_chan[lch].enabled_irqs |= bits; -} - -void omap_disable_dma_irq(int lch, u16 bits) -{ - dma_chan[lch].enabled_irqs &= ~bits; -} - -static int dma_handle_ch(int ch) -{ - u16 csr; - - if (enable_1510_mode && ch >= 6) { - csr = dma_chan[ch].saved_csr; - dma_chan[ch].saved_csr = 0; - } else - csr = omap_readw(OMAP_DMA_CSR(ch)); - if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { - dma_chan[ch + 6].saved_csr = csr >> 7; - csr &= 0x7f; - } - if (!csr) - return 0; - if (unlikely(dma_chan[ch].dev_id == -1)) { - printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n", - ch, csr); - return 0; - } - if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) - printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id); - if (unlikely(csr & OMAP_DMA_DROP_IRQ)) - printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n", - dma_chan[ch].dev_id); - if (likely(csr & OMAP_DMA_BLOCK_IRQ)) - dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; - if (likely(dma_chan[ch].callback != NULL)) - dma_chan[ch].callback(ch, csr, dma_chan[ch].data); - return 1; -} - -static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - int ch = ((int) dev_id) - 1; - int handled = 0; - - for (;;) { - int handled_now = 0; - - handled_now += dma_handle_ch(ch); - if (enable_1510_mode && dma_chan[ch + 6].saved_csr) - handled_now += dma_handle_ch(ch + 6); - if (!handled_now) - break; - handled += handled_now; - } - - return handled ? IRQ_HANDLED : IRQ_NONE; -} - -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_out) -{ - int ch, free_ch = -1; - unsigned long flags; - struct omap_dma_lch *chan; - - spin_lock_irqsave(&dma_chan_lock, flags); - for (ch = 0; ch < dma_chan_count; ch++) { - if (free_ch == -1 && dma_chan[ch].dev_id == -1) { - free_ch = ch; - if (dev_id == 0) - break; - } - } - if (free_ch == -1) { - spin_unlock_irqrestore(&dma_chan_lock, flags); - return -EBUSY; - } - chan = dma_chan + free_ch; - chan->dev_id = dev_id; - clear_lch_regs(free_ch); - spin_unlock_irqrestore(&dma_chan_lock, flags); - - chan->dev_id = dev_id; - chan->dev_name = dev_name; - chan->callback = callback; - chan->data = data; - chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; - - if (cpu_is_omap16xx()) { - /* If the sync device is set, configure it dynamically. */ - if (dev_id != 0) { - set_gdma_dev(free_ch + 1, dev_id); - dev_id = free_ch + 1; - } - /* Disable the 1510 compatibility mode and set the sync device - * id. */ - omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch)); - } else { - omap_writew(dev_id, OMAP_DMA_CCR(free_ch)); - } - *dma_ch_out = free_ch; - - return 0; -} - -void omap_free_dma(int ch) -{ - unsigned long flags; - - spin_lock_irqsave(&dma_chan_lock, flags); - if (dma_chan[ch].dev_id == -1) { - printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch); - spin_unlock_irqrestore(&dma_chan_lock, flags); - return; - } - dma_chan[ch].dev_id = -1; - spin_unlock_irqrestore(&dma_chan_lock, flags); - - /* Disable all DMA interrupts for the channel. */ - omap_writew(0, OMAP_DMA_CICR(ch)); - /* Make sure the DMA transfer is stopped. */ - omap_writew(0, OMAP_DMA_CCR(ch)); -} - -int omap_dma_in_1510_mode(void) -{ - return enable_1510_mode; -} - -/* - * lch_queue DMA will start right after lch_head one is finished. - * For this DMA link to start, you still need to start (see omap_start_dma) - * the first one. That will fire up the entire queue. - */ -void omap_dma_link_lch (int lch_head, int lch_queue) -{ - if (omap_dma_in_1510_mode()) { - printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); - BUG(); - return; - } - - if ((dma_chan[lch_head].dev_id == -1) || - (dma_chan[lch_queue].dev_id == -1)) { - printk(KERN_ERR "omap_dma: trying to link non requested channels\n"); - dump_stack(); - } - - dma_chan[lch_head].next_lch = lch_queue; -} - -/* - * Once the DMA queue is stopped, we can destroy it. - */ -void omap_dma_unlink_lch (int lch_head, int lch_queue) -{ - if (omap_dma_in_1510_mode()) { - printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); - BUG(); - return; - } - - if (dma_chan[lch_head].next_lch != lch_queue || - dma_chan[lch_head].next_lch == -1) { - printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n"); - dump_stack(); - } - - - if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || - (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { - printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n"); - dump_stack(); - } - - dma_chan[lch_head].next_lch = -1; -} - - -static struct lcd_dma_info { - spinlock_t lock; - int reserved; - 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, - int data_type) -{ - lcd_dma.addr = addr; - lcd_dma.data_type = data_type; - lcd_dma.xres = fb_xres; - 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; - 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: - es = 1; - break; - case OMAP_DMA_DATA_TYPE_S16: - es = 2; - break; - case OMAP_DMA_DATA_TYPE_S32: - es = 4; - break; - default: - BUG(); - return; - } - - 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; - 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; - 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()) { - 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); - omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L); - - return; - } - - /* 1610 regs */ - omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U); - omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L); - omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U); - omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L); - - omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1); - omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1); - - w = omap_readw(OMAP1610_DMA_LCD_CSDP); - w &= ~0x03; - w |= lcd_dma.data_type; - omap_writew(w, OMAP1610_DMA_LCD_CSDP); - - 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; |