diff options
author | Tony Lindgren <tony@atomide.com> | 2006-04-02 18:46:27 +0200 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-04-02 18:46:27 +0200 |
commit | 120db2cba8e40c562e5a4aea44ede2f360a5de75 (patch) | |
tree | f08247e64219571b634faf5a809e8505fb0292f2 /arch/arm | |
parent | [ARM] 3454/1: ARM: OMAP: 6/8 Update framebuffer low-level init code, take 2 (diff) | |
download | linux-120db2cba8e40c562e5a4aea44ede2f360a5de75.tar.xz linux-120db2cba8e40c562e5a4aea44ede2f360a5de75.zip |
[ARM] 3455/1: ARM: OMAP: 7/8 Misc updates, take 2
Patch from Tony Lindgren
Update misc OMAP core code from linux-omap tree:
- McBSP updates by Samuel Ortiz, Andrzej Zaborowski
- Whitespace cleanups by Ladislav Michl
- Other fixes by various linux-omap developers
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap1/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/mach-omap1/io.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap1/irq.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-omap1/serial.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/io.c | 21 | ||||
-rw-r--r-- | arch/arm/plat-omap/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 345 | ||||
-rw-r--r-- | arch/arm/plat-omap/ocpi.c | 3 |
9 files changed, 357 insertions, 63 deletions
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index b0b00156faae..9ea719550ad3 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -3,7 +3,13 @@ # # Common support -obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o +obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o + +obj-$(CONFIG_OMAP_MPU_TIMER) += time.o + +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o + led-y := leds.o # Specific board support @@ -14,8 +20,9 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o -obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o +obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o +obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o ifeq ($(CONFIG_ARCH_OMAP15XX),y) # Innovator-1510 FPGA diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 82d556be79c5..be3a2a4ee2b8 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -18,6 +18,7 @@ #include <asm/io.h> #include <asm/arch/mux.h> #include <asm/arch/tc.h> +#include <asm/arch/omapfb.h> extern int omap1_clk_init(void); extern void omap_check_revision(void); @@ -110,7 +111,7 @@ void __init omap1_map_common_io(void) } #endif #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); } #endif @@ -121,6 +122,7 @@ void __init omap1_map_common_io(void) #endif omap_sram_init(); + omapfb_reserve_mem(); } /* diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index ed65a7d2e941..a0431c00fa81 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -60,7 +60,7 @@ struct omap_irq_bank { unsigned long wake_enable; }; -static unsigned int irq_bank_count = 0; +static unsigned int irq_bank_count; static struct omap_irq_bank *irq_banks; static inline unsigned int irq_bank_readl(int bank, int offset) @@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger) #ifdef CONFIG_ARCH_OMAP730 static struct omap_irq_bank omap730_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, }; #endif #ifdef CONFIG_ARCH_OMAP15XX static struct omap_irq_bank omap1510_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, }; static struct omap_irq_bank omap310_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, }; #endif #if defined(CONFIG_ARCH_OMAP16XX) static struct omap_irq_bank omap1610_irq_banks[] = { - { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, - { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, }; diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index e924e0c6a4ce..9b4cd698bec8 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -30,9 +30,9 @@ #include <asm/arch/pm.h> #endif -static struct clk * uart1_ck = NULL; -static struct clk * uart2_ck = NULL; -static struct clk * uart3_ck = NULL; +static struct clk * uart1_ck; +static struct clk * uart2_ck; +static struct clk * uart3_ck; static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, int offset) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 42041166435c..111eaa64258f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -3,11 +3,15 @@ # # Common support -obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o +obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o + # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o +obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 8ea67bf196a5..7d5711611f2f 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -16,9 +16,13 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <asm/mach/map.h> +#include <asm/tlb.h> #include <asm/io.h> + +#include <asm/mach/map.h> + #include <asm/arch/mux.h> +#include <asm/arch/omapfb.h> extern void omap_sram_init(void); extern int omap2_clk_init(void); @@ -43,11 +47,24 @@ static struct map_desc omap2_io_desc[] __initdata = { } }; -void __init omap_map_common_io(void) +void __init omap2_map_common_io(void) { iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); + + /* Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but we must also do it here because of the CPU + * revision check below. + */ + local_flush_tlb_all(); + flush_cache_all(); + omap2_check_revision(); omap_sram_init(); + omapfb_reserve_mem(); +} + +void __init omap2_init_common_hw(void) +{ omap2_mux_init(); omap2_clk_init(); } diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 9ccf1943fc94..2896b4546411 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -3,16 +3,16 @@ # # Common support -obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o +obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o obj-m := obj-n := obj- := +obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o + # OCPI interconnect support for 1710, 1610 and 5912 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o -# Power Management -obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 1cd2cace7e1b..196aac3ac329 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -34,7 +34,7 @@ #ifdef CONFIG_MCBSP_DEBUG #define DBG(x...) printk(x) #else -#define DBG(x...) do { } while (0) +#define DBG(x...) do { } while (0) #endif struct omap_mcbsp { @@ -44,6 +44,7 @@ struct omap_mcbsp { omap_mcbsp_word_length rx_word_length; omap_mcbsp_word_length tx_word_length; + omap_mcbsp_io_type_t io_type; /* IRQ or poll */ /* IRQ based TX/RX */ int rx_irq; int tx_irq; @@ -64,10 +65,19 @@ struct omap_mcbsp { }; static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; +#ifdef CONFIG_ARCH_OMAP1 static struct clk *mcbsp_dsp_ck = 0; static struct clk *mcbsp_api_ck = 0; static struct clk *mcbsp_dspxor_ck = 0; - +#endif +#ifdef CONFIG_ARCH_OMAP2 +static struct clk *mcbsp1_ick = 0; +static struct clk *mcbsp1_fck = 0; +static struct clk *mcbsp2_ick = 0; +static struct clk *mcbsp2_fck = 0; +static struct clk *sys_ck = 0; +static struct clk *sys_clkout = 0; +#endif static void omap_mcbsp_dump_reg(u8 id) { @@ -88,7 +98,6 @@ static void omap_mcbsp_dump_reg(u8 id) DBG("***********************\n"); } - static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); @@ -109,7 +118,6 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_re return IRQ_HANDLED; } - static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); @@ -176,7 +184,7 @@ static int omap_mcbsp_check(unsigned int id) return 0; } - if (cpu_is_omap1510() || cpu_is_omap16xx()) { + if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { if (id > OMAP_MAX_MCBSP_COUNT) { printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); return -1; @@ -187,9 +195,10 @@ static int omap_mcbsp_check(unsigned int id) return -1; } +#ifdef CONFIG_ARCH_OMAP1 static void omap_mcbsp_dsp_request(void) { - if (cpu_is_omap1510() || cpu_is_omap16xx()) { + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { clk_enable(mcbsp_dsp_ck); clk_enable(mcbsp_api_ck); @@ -207,12 +216,49 @@ static void omap_mcbsp_dsp_request(void) static void omap_mcbsp_dsp_free(void) { - if (cpu_is_omap1510() || cpu_is_omap16xx()) { + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { clk_disable(mcbsp_dspxor_ck); clk_disable(mcbsp_dsp_ck); clk_disable(mcbsp_api_ck); } } +#endif + +#ifdef CONFIG_ARCH_OMAP2 +static void omap2_mcbsp2_mux_setup(void) +{ + omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); + omap_cfg_reg(R14_24XX_MCBSP2_FSX); + omap_cfg_reg(W15_24XX_MCBSP2_DR); + omap_cfg_reg(V15_24XX_MCBSP2_DX); + omap_cfg_reg(V14_24XX_GPIO117); + omap_cfg_reg(W14_24XX_SYS_CLKOUT); +} +#endif + +/* + * We can choose between IRQ based or polled IO. + * This needs to be called before omap_mcbsp_request(). + */ +int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) +{ + if (omap_mcbsp_check(id) < 0) + return -EINVAL; + + spin_lock(&mcbsp[id].lock); + + if (!mcbsp[id].free) { + printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); + spin_unlock(&mcbsp[id].lock); + return -EINVAL; + } + + mcbsp[id].io_type = io_type; + + spin_unlock(&mcbsp[id].lock); + + return 0; +} int omap_mcbsp_request(unsigned int id) { @@ -221,12 +267,26 @@ int omap_mcbsp_request(unsigned int id) if (omap_mcbsp_check(id) < 0) return -EINVAL; +#ifdef CONFIG_ARCH_OMAP1 /* * On 1510, 1610 and 1710, McBSP1 and McBSP3 * are DSP public peripherals. */ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) omap_mcbsp_dsp_request(); +#endif + +#ifdef CONFIG_ARCH_OMAP2 + if (cpu_is_omap24xx()) { + if (id == OMAP_MCBSP1) { + clk_enable(mcbsp1_ick); + clk_enable(mcbsp1_fck); + } else { + clk_enable(mcbsp2_ick); + clk_enable(mcbsp2_fck); + } + } +#endif spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { @@ -238,30 +298,33 @@ int omap_mcbsp_request(unsigned int id) mcbsp[id].free = 0; spin_unlock(&mcbsp[id].lock); - /* We need to get IRQs here */ - err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, - "McBSP", - (void *) (&mcbsp[id])); - if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", - mcbsp[id].tx_irq, mcbsp[id].id); - return err; - } + if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { + /* We need to get IRQs here */ + err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", + mcbsp[id].tx_irq, mcbsp[id].id); + return err; + } - init_completion(&(mcbsp[id].tx_irq_completion)); + init_completion(&(mcbsp[id].tx_irq_completion)); - err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, - "McBSP", - (void *) (&mcbsp[id])); - if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", - mcbsp[id].rx_irq, mcbsp[id].id); - free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); - return err; + err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", + mcbsp[id].rx_irq, mcbsp[id].id); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); + return err; + } + + init_completion(&(mcbsp[id].rx_irq_completion)); } - init_completion(&(mcbsp[id].rx_irq_completion)); return 0; } @@ -271,8 +334,24 @@ void omap_mcbsp_free(unsigned int id) if (omap_mcbsp_check(id) < 0) return; - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) - omap_mcbsp_dsp_free(); +#ifdef CONFIG_ARCH_OMAP1 + if (cpu_class_is_omap1()) { + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_free(); + } +#endif + +#ifdef CONFIG_ARCH_OMAP2 + if (cpu_is_omap24xx()) { + if (id == OMAP_MCBSP1) { + clk_disable(mcbsp1_ick); + clk_disable(mcbsp1_fck); + } else { + clk_disable(mcbsp2_ick); + clk_disable(mcbsp2_fck); + } + } +#endif spin_lock(&mcbsp[id].lock); if (mcbsp[id].free) { @@ -284,9 +363,11 @@ void omap_mcbsp_free(unsigned int id) mcbsp[id].free = 1; spin_unlock(&mcbsp[id].lock); - /* Free IRQs */ - free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); - free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); + if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { + /* Free IRQs */ + free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); + } } /* @@ -461,6 +542,115 @@ u32 omap_mcbsp_recv_word(unsigned int id) } +int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) +{ + u32 io_base = mcbsp[id].io_base; + omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; + omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; + u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; + + if (tx_word_length != rx_word_length) + return -EINVAL; + + /* First we wait for the transmitter to be ready */ + spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); + while (!(spcr2 & XRDY)) { + spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); + if (attempts++ > 1000) { + /* We must reset the transmitter */ + OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); + udelay(10); + OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); + udelay(10); + printk("McBSP transmitter not ready\n"); + return -EAGAIN; + } + } + + /* Now we can push the data */ + if (tx_word_length > OMAP_MCBSP_WORD_16) + OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); + OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); + + /* We wait for the receiver to be ready */ + spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); + while (!(spcr1 & RRDY)) { + spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); + if (attempts++ > 1000) { + /* We must reset the receiver */ + OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); + udelay(10); + OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); + udelay(10); + printk("McBSP receiver not ready\n"); + return -EAGAIN; + } + } + + /* Receiver is ready, let's read the dummy data */ + if (rx_word_length > OMAP_MCBSP_WORD_16) + word_msb = OMAP_MCBSP_READ(io_base, DRR2); + word_lsb = OMAP_MCBSP_READ(io_base, DRR1); + + return 0; +} + +int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) +{ + u32 io_base = mcbsp[id].io_base, clock_word = 0; + omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; + omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; + u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; + + if (tx_word_length != rx_word_length) + return -EINVAL; + + /* First we wait for the transmitter to be ready */ + spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); + while (!(spcr2 & XRDY)) { + spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); + if (attempts++ > 1000) { + /* We must reset the transmitter */ + OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); + udelay(10); + OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); + udelay(10); + printk("McBSP transmitter not ready\n"); + return -EAGAIN; + } + } + + /* We first need to enable the bus clock */ + if (tx_word_length > OMAP_MCBSP_WORD_16) + OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16); + OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff); + + /* We wait for the receiver to be ready */ + spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); + while (!(spcr1 & RRDY)) { + spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); + if (attempts++ > 1000) { + /* We must reset the receiver */ + OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); + udelay(10); + OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); + udelay(10); + printk("McBSP receiver not ready\n"); + return -EAGAIN; + } + } + + /* Receiver is ready, there is something for us */ + if (rx_word_length > OMAP_MCBSP_WORD_16) + word_msb = OMAP_MCBSP_READ(io_base, DRR2); + word_lsb = OMAP_MCBSP_READ(io_base, DRR1); + + word[0] = (word_lsb | (word_msb << 16)); + + return 0; +} + + /* * Simple DMA based buffer rx/tx routines. * Nothing fancy, just a single buffer tx/rx through DMA. @@ -471,6 +661,9 @@ u32 omap_mcbsp_recv_word(unsigned int id) int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_tx_ch; + int src_port = 0; + int dest_port = 0; + int sync_dev = 0; if (omap_mcbsp_check(id) < 0) return -EINVAL; @@ -487,20 +680,27 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng init_completion(&(mcbsp[id].tx_dma_completion)); + if (cpu_class_is_omap1()) { + src_port = OMAP_DMA_PORT_TIPB; + dest_port = OMAP_DMA_PORT_EMIFF; + } + if (cpu_is_omap24xx()) + sync_dev = mcbsp[id].dma_tx_sync; + omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, - 0, 0); + sync_dev, 0); omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, - OMAP_DMA_PORT_TIPB, + src_port, OMAP_DMA_AMODE_CONSTANT, mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, 0, 0); omap_set_dma_src_params(mcbsp[id].dma_tx_lch, - OMAP_DMA_PORT_EMIFF, + dest_port, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); @@ -514,6 +714,9 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_rx_ch; + int src_port = 0; + int dest_port = 0; + int sync_dev = 0; if (omap_mcbsp_check(id) < 0) return -EINVAL; @@ -530,20 +733,27 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng init_completion(&(mcbsp[id].rx_dma_completion)); + if (cpu_class_is_omap1()) { + src_port = OMAP_DMA_PORT_TIPB; + dest_port = OMAP_DMA_PORT_EMIFF; + } + if (cpu_is_omap24xx()) + sync_dev = mcbsp[id].dma_rx_sync; + omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, OMAP_DMA_DATA_TYPE_S16, length >> 1, 1, OMAP_DMA_SYNC_ELEMENT, - 0, 0); + sync_dev, 0); omap_set_dma_src_params(mcbsp[id].dma_rx_lch, - OMAP_DMA_PORT_TIPB, + src_port, OMAP_DMA_AMODE_CONSTANT, mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, 0, 0); omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, - OMAP_DMA_PORT_EMIFF, + dest_port, OMAP_DMA_AMODE_POST_INC, buffer, 0, 0); @@ -688,6 +898,23 @@ static const struct omap_mcbsp_info mcbsp_1610[] = { }; #endif +#if defined(CONFIG_ARCH_OMAP24XX) +static const struct omap_mcbsp_info mcbsp_24xx[] = { + [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), + .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + }, + [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), + .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + }, +}; +#endif + static int __init omap_mcbsp_init(void) { int mcbsp_count = 0, i; @@ -695,6 +922,7 @@ static int __init omap_mcbsp_init(void) printk("Initializing OMAP McBSP system\n"); +#ifdef CONFIG_ARCH_OMAP1 mcbsp_dsp_ck = clk_get(0, "dsp_ck"); if (IS_ERR(mcbsp_dsp_ck)) { printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); @@ -710,6 +938,29 @@ static int __init omap_mcbsp_init(void) printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); return PTR_ERR(mcbsp_dspxor_ck); } +#endif +#ifdef CONFIG_ARCH_OMAP2 + mcbsp1_ick = clk_get(0, "mcbsp1_ick"); + if (IS_ERR(mcbsp1_ick)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); + return PTR_ERR(mcbsp1_ick); + } + mcbsp1_fck = clk_get(0, "mcbsp1_fck"); + if (IS_ERR(mcbsp1_fck)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); + return PTR_ERR(mcbsp1_fck); + } + mcbsp2_ick = clk_get(0, "mcbsp2_ick"); + if (IS_ERR(mcbsp2_ick)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); + return PTR_ERR(mcbsp2_ick); + } + mcbsp2_fck = clk_get(0, "mcbsp2_fck"); + if (IS_ERR(mcbsp2_fck)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); + return PTR_ERR(mcbsp2_fck); + } +#endif #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { @@ -718,7 +969,7 @@ static int __init omap_mcbsp_init(void) } #endif #ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { mcbsp_info = mcbsp_1510; mcbsp_count = ARRAY_SIZE(mcbsp_1510); } @@ -729,6 +980,19 @@ static int __init omap_mcbsp_init(void) mcbsp_count = ARRAY_SIZE(mcbsp_1610); } #endif +#if defined(CONFIG_ARCH_OMAP24XX) + if (cpu_is_omap24xx()) { + mcbsp_info = mcbsp_24xx; + mcbsp_count = ARRAY_SIZE(mcbsp_24xx); + + /* REVISIT: where's the right place? */ + omap2_mcbsp2_mux_setup(); + sys_ck = clk_get(0, "sys_ck"); + sys_clkout = clk_get(0, "sys_clkout"); + clk_set_parent(sys_clkout, sys_ck); + clk_enable(sys_clkout); + } +#endif for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { if (i >= mcbsp_count) { mcbsp[i].io_base = 0; @@ -741,6 +1005,7 @@ static int __init omap_mcbsp_init(void) mcbsp[i].dma_rx_lch = -1; mcbsp[i].io_base = mcbsp_info[i].virt_base; + mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; @@ -751,11 +1016,11 @@ static int __init omap_mcbsp_init(void) return 0; } - arch_initcall(omap_mcbsp_init); EXPORT_SYMBOL(omap_mcbsp_config); EXPORT_SYMBOL(omap_mcbsp_request); +EXPORT_SYMBOL(omap_mcbsp_set_io_type); EXPORT_SYMBOL(omap_mcbsp_free); EXPORT_SYMBOL(omap_mcbsp_start); EXPORT_SYMBOL(omap_mcbsp_stop); @@ -763,4 +1028,6 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); EXPORT_SYMBOL(omap_mcbsp_recv_word); EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); EXPORT_SYMBOL(omap_mcbsp_recv_buffer); +EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); +EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 5cc6775c789c..37792d43738b 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c @@ -62,9 +62,6 @@ int ocpi_enable(void) if (!cpu_is_omap16xx()) return -ENODEV; - /* Make sure there's clock for OCPI */ - clk_enable(ocpi_ck); - /* Enable access for OHCI in OCPI */ val = omap_readl(OCPI_PROT); val &= ~0xff; |