Commit 958163e2 authored by Tony Lindgren's avatar Tony Lindgren Committed by Russell King

[ARM PATCH] 2007/1: OMAP update 3/6: Arch files

Patch from Tony Lindgren

This patch syncs the mainline kernel with the linux-omap tree.
The highlights of the patch are:
- DMA fixes from Samuel Ortiz
- USB low level configuration from David Brownell
- H3 support from Nishant Kamat
- TPS65010 power management interface from Dirk Behme
parent a7116ca5
......@@ -3,25 +3,29 @@
#
# Common support
obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o time.o
obj-y := common.o time.o irq.o dma.o clocks.o mux.o gpio.o mcbsp.o
obj-m :=
obj-n :=
obj- :=
led-y := leds.o
# Specific board support
obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
# OCPI interconnect support for 1610 and 5912
# OCPI interconnect support for 1710, 1610 and 5912
obj-$(CONFIG_ARCH_OMAP1710) += ocpi.o
obj-$(CONFIG_ARCH_OMAP1610) += ocpi.o
obj-$(CONFIG_ARCH_OMAP5912) += ocpi.o
# LEDs support
led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-perseus2.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
obj-$(CONFIG_LEDS) += $(led-y)
# Power Management
......
......@@ -25,9 +25,13 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
#include "common.h"
extern void __init omap_init_time(void);
static void __init omap_generic_init_irq(void)
{
omap_init_irq();
......@@ -36,17 +40,49 @@ static void __init omap_generic_init_irq(void)
/*
* Muxes the serial ports on
*/
#ifdef CONFIG_ARCH_OMAP1510
static void __init omap_early_serial_init(void)
{
#ifdef CONFIG_OMAP_LL_DEBUG_UART1
omap_cfg_reg(UART1_TX);
omap_cfg_reg(UART1_RTS);
#endif
#ifdef CONFIG_OMAP_LL_DEBUG_UART2
omap_cfg_reg(UART2_TX);
omap_cfg_reg(UART2_RTS);
#endif
#ifdef CONFIG_OMAP_LL_DEBUG_UART1
omap_cfg_reg(UART3_TX);
omap_cfg_reg(UART3_RX);
#endif
}
#endif
/* assume no Mini-AB port */
#ifdef CONFIG_ARCH_OMAP1510
static struct omap_usb_config generic1510_usb_config __initdata = {
.register_host = 1,
.register_dev = 1,
.hmc_mode = 16,
.pins[0] = 3,
};
#endif
#ifdef CONFIG_ARCH_OMAP1610
static struct omap_usb_config generic1610_usb_config __initdata = {
.register_host = 1,
.register_dev = 1,
.hmc_mode = 16,
.pins[0] = 6,
};
#endif
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_USB, NULL },
};
static void __init omap_generic_init(void)
{
......@@ -55,9 +91,19 @@ static void __init omap_generic_init(void)
* You have to mux them off in device drivers later on
* if not needed.
*/
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
omap_early_serial_init();
generic_config[0].data = &generic1510_usb_config;
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (!cpu_is_omap1510()) {
generic_config[0].data = &generic1610_usb_config;
}
#endif
omap_board_config = generic_config;
omap_board_config_size = ARRAY_SIZE(generic_config);
}
static void __init omap_generic_map_io(void)
......@@ -65,18 +111,12 @@ static void __init omap_generic_map_io(void)
omap_map_io();
}
static void __init omap_generic_init_time(void)
{
omap_init_time();
}
MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
BOOT_PARAMS(0x10000100)
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
INITTIME(omap_generic_init_time)
INITTIME(omap_init_time)
MACHINE_END
......@@ -29,9 +29,12 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/fpga.h>
#include <asm/arch/usb.h>
#include "common.h"
extern void __init omap_init_time(void);
#ifdef CONFIG_ARCH_OMAP1510
extern int omap_gpio_init(void);
......@@ -49,8 +52,8 @@ static struct resource innovator1510_smc91x_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = INT_ETHER,
.end = INT_ETHER,
.start = OMAP1510_INT_ETHER,
.end = OMAP1510_INT_ETHER,
.flags = IORESOURCE_IRQ,
},
};
......@@ -108,11 +111,43 @@ void innovator_init_irq(void)
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
omap_gpio_init();
fpga_init_irq();
omap1510_fpga_init_irq();
}
#endif
}
#ifdef CONFIG_ARCH_OMAP1510
static struct omap_usb_config innovator1510_usb_config __initdata = {
/* has usb host and device, but no Mini-AB port */
.register_host = 1,
.register_dev = 1,
/* Assume bad Innovator wiring; Use internal host only with custom cable */
.hmc_mode = 16,
.pins[0] = 2,
};
#endif
#ifdef CONFIG_ARCH_OMAP1610
static struct omap_usb_config h2_usb_config __initdata = {
/* usb1 has a Mini-AB port and external isp1301 transceiver */
.otg = 2,
#ifdef CONFIG_USB_GADGET_OMAP
.hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled
// .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback)
#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
.hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled
#endif
.pins[1] = 3,
};
#endif
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
};
static void __init innovator_init(void)
{
#ifdef CONFIG_ARCH_OMAP1510
......@@ -121,10 +156,21 @@ static void __init innovator_init(void)
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
if (!cpu_is_omap1510()) {
platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
}
#endif
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510())
innovator_config[0].data = &innovator1510_usb_config;
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610())
innovator_config[0].data = &h2_usb_config;
#endif
omap_board_config = innovator_config;
omap_board_config_size = ARRAY_SIZE(innovator_config);
}
static void __init innovator_map_io(void)
......@@ -144,7 +190,7 @@ static void __init innovator_map_io(void)
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
if (!cpu_is_omap1510()) {
iotable_init(innovator1610_io_desc, ARRAY_SIZE(innovator1610_io_desc));
}
#endif
......@@ -156,6 +202,6 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
BOOT_PARAMS(0x10000100)
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(innovator_init)
INITTIME(omap_init_time)
MACHINE_END
......@@ -41,6 +41,8 @@
#include "common.h"
extern void __init omap_init_time(void);
static struct map_desc osk5912_io_desc[] __initdata = {
{ OMAP_OSK_ETHR_BASE, OMAP_OSK_ETHR_START, OMAP_OSK_ETHR_SIZE,MT_DEVICE },
{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
......@@ -94,6 +96,6 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
BOOT_PARAMS(0x10000100)
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(osk_init)
INITTIME(omap_init_time)
MACHINE_END
......@@ -23,9 +23,12 @@
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
#include "common.h"
extern void __init omap_init_time(void);
void omap_perseus2_init_irq(void)
{
omap_init_irq();
......@@ -33,14 +36,14 @@ void omap_perseus2_init_irq(void)
static struct resource smc91x_resources[] = {
[0] = {
.start = OMAP730_FPGA_ETHR_START, /* Physical */
.end = OMAP730_FPGA_ETHR_START + SZ_4K,
.start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
.end = H2P2_DBG_FPGA_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0,
.start = INT_730_MPU_EXT_NIRQ,
.end = 0,
.flags = INT_ETHER,
.flags = IORESOURCE_IRQ,
},
};
......@@ -62,7 +65,7 @@ static void __init omap_perseus2_init(void)
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_perseus2_io_desc[] __initdata = {
{OMAP730_FPGA_BASE, OMAP730_FPGA_START, OMAP730_FPGA_SIZE,
{H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
MT_DEVICE},
};
......@@ -111,6 +114,6 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
INITTIME(omap_init_time)
INIT_MACHINE(omap_perseus2_init)
INITTIME(omap_init_time)
MACHINE_END
......@@ -36,6 +36,8 @@
#include <asm/arch/clocks.h>
#include <asm/arch/board.h>
extern void start_mputimer1(unsigned long load_val);
/* Input clock in MHz */
static unsigned int source_clock = 12;
......@@ -239,7 +241,7 @@ int ck_auto_unclock = 1;
int ck_debug = 0;
#define CK_MAX_PLL_FREQ OMAP_CK_MAX_RATE
static __u8 ck_valid_table[CK_MAX_PLL_FREQ / 8 + 1];
static __u32 ck_valid_table[CK_MAX_PLL_FREQ / 32 + 1];
static __u8 ck_lookup_table[CK_MAX_PLL_FREQ];
int
......@@ -615,11 +617,11 @@ __ck_make_lookup_table(void)
int __init
init_ck(void)
{
const struct omap_clock_info *info;
const struct omap_clock_config *info;
int crystal_type = 0; /* Default 12 MHz */
__ck_make_lookup_table();
info = omap_get_per_info(OMAP_TAG_CLOCK, struct omap_clock_info);
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
if (info != NULL) {
if (!cpu_is_omap1510())
crystal_type = info->system_clock_type;
......@@ -645,7 +647,8 @@ init_ck(void)
#elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
omap_writew(0x250E, ARM_CKCTL);
omap_writew(0x2710, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
|| defined(CONFIG_ARCH_OMAP1710))
omap_writew(0x150f, ARM_CKCTL);
if (crystal_type == 2) {
source_clock = 13; /* MHz */
......
......@@ -104,7 +104,7 @@ static struct map_desc omap1510_io_desc[] __initdata = {
};
#endif
#ifdef CONFIG_ARCH_OMAP1610
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
static struct map_desc omap1610_io_desc[] __initdata = {
{ OMAP1610_DSP_BASE, OMAP1610_DSP_START, OMAP1610_DSP_SIZE, MT_DEVICE },
{ OMAP1610_DSPREG_BASE, OMAP1610_DSPREG_START, OMAP1610_DSPREG_SIZE, MT_DEVICE },
......@@ -147,8 +147,8 @@ static void __init _omap_map_io(void)
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
if (cpu_is_omap1610() || cpu_is_omap1710()) {
iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
}
#endif
......@@ -181,13 +181,18 @@ void omap_map_io(void)
extern int omap_bootloader_tag_len;
extern u8 omap_bootloader_tag[];
const void *__omap_get_per_info(u16 tag, size_t len)
struct omap_board_config_kernel *omap_board_config;
int omap_board_config_size = 0;
const void *__omap_get_config(u16 tag, size_t len)
{
struct omap_board_info_entry *info = NULL;
struct omap_board_config_entry *info = NULL;
struct omap_board_config_kernel *kinfo = NULL;
int i;
#ifdef CONFIG_OMAP_BOOT_TAG
if (omap_bootloader_tag_len > 4)
info = (struct omap_board_info_entry *) omap_bootloader_tag;
info = (struct omap_board_config_entry *) omap_bootloader_tag;
while (info != NULL) {
u8 *next;
......@@ -198,26 +203,38 @@ const void *__omap_get_per_info(u16 tag, size_t len)
if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
info = NULL;
else
info = (struct omap_board_info_entry *) next;
info = (struct omap_board_config_entry *) next;
}
#endif
if (info == NULL)
return NULL;
if (info != NULL) {
/* Check the length as a lame attempt to check for
* binary inconsistancy. */
if (info->len != len) {
printk(KERN_ERR "OMAP per_info: Length mismatch with tag %x (want %d, got %d)\n",
printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
tag, len, info->len);
return NULL;
}
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;
}
EXPORT_SYMBOL(__omap_get_per_info);
EXPORT_SYMBOL(__omap_get_config);
static int __init omap_add_serial_console(void)
{
const struct omap_uart_info *info;
const struct omap_uart_config *info;
info = omap_get_per_info(OMAP_TAG_UART, struct omap_uart_info);
info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
if (info != NULL && info->console_uart) {
static char speed[11], *opt = NULL;
......
......@@ -28,7 +28,6 @@
#define __ARCH_ARM_MACH_OMAP_COMMON_H
extern void omap_map_io(void);
extern void omap_init_time(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
......
......@@ -118,7 +118,7 @@ void omap_set_dma_constant_fill(int lch, u32 color)
u16 w;
#ifdef CONFIG_DEBUG_KERNEL
if (omap_dma_in_1510_mode) {
if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode.");
BUG();
return;
......@@ -141,7 +141,7 @@ void omap_set_dma_transparent_copy(int lch, u32 color)
u16 w;
#ifdef CONFIG_DEBUG_KERNEL
if (omap_dma_in_1510_mode) {
if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode.");
BUG();
}
......@@ -266,46 +266,78 @@ void omap_set_dma_dest_burst_mode(int lch, int burst_mode)
omap_writew(w, OMAP_DMA_CSDP(lch));
}
void omap_start_dma(int lch)
static inline void init_intr(int lch)
{
u16 w;
if (!omap_dma_in_1510_mode()) {
int next_lch;
/* 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;
}
next_lch = dma_chan[lch].next_lch;
static inline void enable_lnk(int lch)
{
u16 w;
/* Enable the queue, if needed so. */
if (next_lch != -1) {
/* Clear the STOP_LNK bits */
w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
w &= ~(1 << 14);
omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
w &= ~(1 << 14);
omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
/* And set the ENABLE_LNK bits */
omap_writew(next_lch | (1 << 15),
if (dma_chan[lch].next_lch != -1)
omap_writew(dma_chan[lch].next_lch | (1 << 15),
OMAP_DMA_CLNK_CTRL(lch));
/* The loop case */
if (dma_chan[next_lch].next_lch == lch)
omap_writew(lch | (1 << 15),
OMAP_DMA_CLNK_CTRL(next_lch));
}
/* Read CSR to make sure it's cleared. */
w = omap_readw(OMAP_DMA_CSR(next_lch));
/* Enable some nice interrupts. */
omap_writew(dma_chan[next_lch].enabled_irqs,
OMAP_DMA_CICR(next_lch));
dma_chan[next_lch].flags |= OMAP_DMA_ACTIVE;
}
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);
}
/* 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));
init_intr(lch);
w = omap_readw(OMAP_DMA_CCR(lch));
w |= OMAP_DMA_CCR_EN;
......@@ -316,37 +348,34 @@ void omap_start_dma(int lch)
void omap_stop_dma(int lch)
{
u16 w;
int next_lch;
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));
if (omap_dma_in_1510_mode()) {
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;
return;
}
next_lch = dma_chan[lch].next_lch;
/*
* According to thw HW spec, enabling the STOP_LNK bit
* resets the CCR_EN bit at the same time.
*/
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;
if (next_lch != -1) {
omap_writew(0, OMAP_DMA_CICR(next_lch));
w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
w |= (1 << 14);
w = omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
dma_chan[next_lch].flags &= ~OMAP_DMA_ACTIVE;
}
}
void omap_enable_dma_irq(int lch, u16 bits)
......@@ -445,7 +474,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()) {
if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
/* If the sync device is set, configure it dynamically. */
if (dev_id != 0) {
set_gdma_dev(free_ch + 1, dev_id);
......@@ -533,7 +562,6 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
}
dma_chan[lch_head].next_lch = -1;
dma_chan[lch_queue].next_lch = -1;
}
......@@ -713,7 +741,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()) {
} else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap730() || cpu_is_omap1710()) {
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",
......@@ -771,6 +799,8 @@ EXPORT_SYMBOL(omap_request_dma);
EXPORT_SYMBOL(omap_free_dma);
EXPORT_SYMBOL(omap_start_dma);
EXPORT_SYMBOL(omap_stop_dma);
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);
......
......@@ -31,19 +31,9 @@
#include <asm/arch/fpga.h>
#include <asm/arch/gpio.h>
unsigned char fpga_read(int reg)
{
return __raw_readb(reg);
}
void fpga_write(unsigned char val, int reg)
{
__raw_writeb(val, reg);
}
static void fpga_mask_irq(unsigned int irq)
{
irq -= IH_FPGA_BASE;
irq -= OMAP1510_IH_FPGA_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
......@@ -76,7 +66,7 @@ static void fpga_ack_irq(unsigned int irq)
static void fpga_unmask_irq(unsigned int irq)
{
irq -= IH_FPGA_BASE;
irq -= OMAP1510_IH_FPGA_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
......@@ -114,8 +104,8 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
break;
}
for (fpga_irq = IH_FPGA_BASE;
(fpga_irq < (IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
for (fpga_irq = OMAP1510_IH_FPGA_BASE;
(fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
fpga_irq++, stat >>= 1) {
if (stat & 1) {
d = irq_desc + fpga_irq;
......@@ -162,7 +152,7 @@ static struct irqchip omap_fpga_irq = {
* interrupts at the interrupt controller via disable_irq/enable_irq
* could pose a problem.
*/
void fpga_init_irq(void)
void omap1510_fpga_init_irq(void)
{
int i;
......@@ -170,9 +160,9 @@ void fpga_init_irq(void)
__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
__raw_writeb(0, INNOVATOR_FPGA_IMR2);
for (i = IH_FPGA_BASE; i < (IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
if (i == INT_FPGA_TS) {
if (i == OMAP1510_INT_FPGA_TS) {
/*
* The touchscreen interrupt is level-sensitive, so
* we'll use the regular mask_ack routine for it.
......@@ -201,9 +191,7 @@ void fpga_init_irq(void)
omap_request_gpio(13);
omap_set_gpio_direction(13, 1);
omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
set_irq_chained_handler(INT_FPGA, innovator_fpga_IRQ_demux);
set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
}
EXPORT_SYMBOL(fpga_init_irq);
EXPORT_SYMBOL(fpga_read);
EXPORT_SYMBOL(fpga_write);
EXPORT_SYMBOL(omap1510_fpga_init_irq);
......@@ -94,7 +94,7 @@ struct gpio_bank {
#define METHOD_GPIO_1610 2
#define METHOD_GPIO_730 3
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
static struct gpio_bank gpio_bank_1610[5] = {
{ OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
......@@ -113,7 +113,7 @@ static struct gpio_bank gpio_bank_1510[2] = {
#ifdef CONFIG_ARCH_OMAP730
static struct gpio_bank gpio_bank_730[7] = {
{ OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP730_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 },
{ OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 },
{ OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 },
......@@ -135,8 +135,8 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
return &gpio_bank[1];
}
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if (cpu_is_omap1610() || cpu_is_omap5912()) {
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) {
if (OMAP_GPIO_IS_MPUIO(gpio))
return &gpio_bank[0];
return &gpio_bank[1 + (gpio >> 4)];
......@@ -172,8 +172,8 @@ static inline int gpio_valid(int gpio)
if (cpu_is_omap1510() && gpio < 16)
return 0;
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if ((cpu_is_omap1610() || cpu_is_omap5912()) && gpio < 64)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if ((cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) && gpio < 64)
return 0;
#endif
#ifdef CONFIG_ARCH_OMAP730
......@@ -554,7 +554,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
if (bank->method == METHOD_GPIO_1510)
isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610)
isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
#endif
......@@ -588,7 +588,7 @@ static void gpio_ack_irq(unsigned int irq)
if (bank->method == METHOD_GPIO_1510)
__raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610)
__raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
#endif
......@@ -629,7 +629,7 @@ static void mpuio_mask_irq(unsigned int irq)
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
struct gpio_bank *bank = get_gpio_bank(gpio);
_set_gpio_irqenable(bank, gpio, 0);
_set_gpio_irqenable(bank, get_gpio_index(gpio), 0);
}
static void mpuio_unmask_irq(unsigned int irq)
......@@ -637,7 +637,7 @@ static void mpuio_unmask_irq(unsigned int irq)
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
struct gpio_bank *bank = get_gpio_bank(gpio);
_set_gpio_irqenable(bank, gpio, 1);
_set_gpio_irqenable(bank, get_gpio_index(gpio), 1);
}
static struct irqchip gpio_irq_chip = {
......@@ -668,8 +668,8 @@ static int __init _omap_gpio_init(void)
gpio_bank = gpio_bank_1510;
}
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if (cpu_is_omap1610() || cpu_is_omap5912()) {
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (cpu_is_omap1610() || cpu_is_omap1710() || cpu_is_omap5912()) {
int rev;
gpio_bank_count = 5;
......@@ -702,7 +702,7 @@ static int __init _omap_gpio_init(void)
__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
}
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610) {
__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
......@@ -731,7 +731,7 @@ static int __init _omap_gpio_init(void)
/* Enable system clock for GPIO module.
* The CAM_CLK_CTRL *is* really the right place. */
if (cpu_is_omap1610())
if (cpu_is_omap1610() || cpu_is_omap1710())
omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
return 0;
......
......@@ -140,7 +140,9 @@ static struct omap_irq_bank omap1510_irq_banks[] = {
};
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
|| defined(CONFIG_ARCH_OMAP1710)
static struct omap_irq_bank omap1610_irq_banks[] = {
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfffff7ff },
......@@ -171,8 +173,9 @@ void __init omap_init_irq(void)
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
}
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if (cpu_is_omap1610() || cpu_is_omap5912()) {
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
|| defined(CONFIG_ARCH_OMAP1710)
if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
irq_banks = omap1610_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
}
......@@ -190,6 +193,11 @@ void __init omap_init_irq(void)
irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
/* Enable interrupts in global mask */
if (cpu_is_omap730()) {
irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
}
/* Install the interrupt handlers for each bank */
for (i = 0; i < irq_bank_count; i++) {
for (j = i * 32; j < (i + 1) * 32; j++) {
......@@ -205,5 +213,9 @@ void __init omap_init_irq(void)
}
/* Unmask level 2 handler */
if (cpu_is_omap730()) {
omap_unmask_irq(INT_730_IH2_IRQ);
} else {
omap_unmask_irq(INT_IH2_IRQ);
}
}
......@@ -3,6 +3,7 @@
*
* OMAP LEDs dispatcher
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/leds.h>
......@@ -11,17 +12,17 @@
#include "leds.h"
static int __init
omap1510_leds_init(void)
omap_leds_init(void)
{
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
else if (machine_is_omap_perseus2()) {
leds_event = perseus2_leds_event;
else if (machine_is_omap_h2() || machine_is_omap_perseus2()) {
leds_event = h2p2_dbg_leds_event;
}
leds_event(led_start);
return 0;
}
__initcall(omap1510_leds_init);
__initcall(omap_leds_init);
extern void innovator_leds_event(led_event_t evt);
extern void perseus2_leds_event(led_event_t evt);
extern void h2p2_dbg_leds_event(led_event_t evt);
......@@ -59,8 +59,8 @@ int ocpi_enable(void)
/* Make sure there's clock for OCPI */
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
if (cpu_is_omap1610() || cpu_is_omap1710()) {
val = omap_readl(OMAP1610_ARM_IDLECT3);
val |= EN_OCPI_CK;
val &= ~IDLOCPI_ARM;
......
/*
* arch/arm/mach-omap/usb.c -- platform level USB initialization
*
* Copyright (C) 2004 Texas Instruments, Inc.
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#undef DEBUG
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/usb_otg.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
/* These routines should handle the standard chip-specific modes
* for usb0/1/2 ports, covering basic mux and transceiver setup.
* Call omap_usb_init() once, from INIT_MACHINE().
*
* Some board-*.c files will need to set up additional mux options,
* like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
*/
/* TESTED ON:
* - 1611B H2 (with usb1 mini-AB)
* - 1510 Innovator with built-in transceiver (custom cable feeding 5V VBUS)
* - 1710 custom development board using alternate pin group
*/
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_ARCH_OMAP_OTG
static struct otg_transceiver *xceiv;
/**
* otg_get_transceiver - find the (single) OTG transceiver driver
*
* Returns the transceiver driver, after getting a refcount to it; or
* null if there is no such transceiver. The caller is responsible for
* releasing that count.
*/
struct otg_transceiver *otg_get_transceiver(void)
{
if (xceiv)
get_device(xceiv->dev);
return xceiv;
}
EXPORT_SYMBOL(otg_get_transceiver);
int otg_set_transceiver(struct otg_transceiver *x)
{
if (xceiv && x)
return -EBUSY;
xceiv = x;
return 0;
}
EXPORT_SYMBOL(otg_set_transceiver);
#endif
/*-------------------------------------------------------------------------*/
static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
{
u32 syscon1 = 0;
if (nwires == 0) {
USB_TRANSCEIVER_CTRL_REG &= ~(1 << 3);
return 0;
}
/*
* VP and VM are needed for all active usb0 configurations.
* USB0_VP and USB0_VM are always set on 1510, there's no muxing
* available for them.
*/
if (nwires >= 2 && !cpu_is_omap1510()) {
omap_cfg_reg(AA9_USB0_VP);
omap_cfg_reg(R9_USB0_VM);
}
/* internal transceiver */
if (nwires == 2) {
if (cpu_is_omap1510()) {
/* This works for OHCI on 1510-Innovator, nothing to mux */
return 0;
}
#if 0
/* NOTE: host OR device mode for now, no OTG */
USB_TRANSCEIVER_CTRL_REG &= ~(3 << 4);
if (is_device) {
omap_cfg_reg(W4_USB_PUEN);
omap_cfg_reg(R18_1510_USB_GPIO0);
// omap_cfg_reg(USB0_VBUS);
// omap_cfg_reg(USB0_PUEN);
// USB_TRANSCEIVER_CTRL_REG.CONF_USB0_PORT_R = 7
// when USB0_PUEN is needed
} else /* host mode needs D+ and D- pulldowns */
USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
return 3 << 16;
#else
/* FIXME: 1610 needs to return the right value here */
printk(KERN_ERR "usb0 internal transceiver, nyet\n");
return 0;
#endif
}
/* alternate pin config, external transceiver */
omap_cfg_reg(V6_USB0_TXD);
omap_cfg_reg(W9_USB0_TXEN);
omap_cfg_reg(W5_USB0_SE0);
#ifdef CONFIG_ARCH_OMAP_USB_SPEED
/* FIXME: there's good chance that pin V9 is used for MMC2 port cmddir */
omap_cfg_reg(V9_USB0_SPEED);
// omap_cfg_reg(V9_USB0_SUSP);
#endif
if (nwires != 3)
omap_cfg_reg(Y5_USB0_RCV);
switch (nwires) {
case 3:
syscon1 = 2;
break;
case 4:
syscon1 = 1;
break;
case 6:
syscon1 = 3;
/* REVISIT: Is CONF_USB2_UNI_R only needed when nwires = 6? */
USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
break;
default:
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
0, nwires);
}
return syscon1 << 16;
}
static u32 __init omap_usb1_init(unsigned nwires)
{
u32 syscon1 = 0;
if (nwires != 6)
USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
if (nwires == 0)
return 0;
/* external transceiver */
omap_cfg_reg(USB1_TXD);
omap_cfg_reg(USB1_TXEN);
if (cpu_is_omap1510()) {
omap_cfg_reg(USB1_SEO);
omap_cfg_reg(USB1_SPEED);
// SUSP
} else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
omap_cfg_reg(W13_1610_USB1_SE0);
omap_cfg_reg(R13_1610_USB1_SPEED);
// SUSP
} else {
pr_debug("usb unrecognized\n");
}
if (nwires != 3)
omap_cfg_reg(USB1_RCV);
switch (nwires) {
case 3:
syscon1 = 2;
break;
case 4:
syscon1 = 1;
break;
case 6:
syscon1 = 3;
omap_cfg_reg(USB1_VP);
omap_cfg_reg(USB1_VM);
USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
break;
default:
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
1, nwires);
}
return syscon1 << 20;
}
static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
{
u32 syscon1 = 0;
if (alt_pingroup)
return 0;
if (nwires != 6)
USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
if (nwires == 0)
return 0;
/* external transceiver */
if (cpu_is_omap1510()) {
omap_cfg_reg(USB2_TXD);
omap_cfg_reg(USB2_TXEN);
omap_cfg_reg(USB2_SEO);
if (nwires != 3)
omap_cfg_reg(USB2_RCV);
} else if (cpu_is_omap1610() || cpu_is_omap5912() || cpu_is_omap1710()) {
omap_cfg_reg(V6_USB2_TXD);
omap_cfg_reg(W9_USB2_TXEN);
omap_cfg_reg(W5_USB2_SE0);
if (nwires != 3)
omap_cfg_reg(Y5_USB2_RCV);
} else {
pr_debug("usb unrecognized\n");
}
// omap_cfg_reg(USB2_SUSP);
// FIXME omap_cfg_reg(USB2_SPEED);
switch (nwires) {
case 3:
syscon1 = 2;
break;
case 4:
syscon1 = 1;
break;
case 6:
syscon1 = 3;
if (cpu_is_omap1510()) {
omap_cfg_reg(USB2_VP);
omap_cfg_reg(USB2_VM);
} else {
omap_cfg_reg(AA9_USB2_VP);
omap_cfg_reg(R9_USB2_VM);
}
USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
break;
default:
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
2, nwires);
}
return syscon1 << 24;
}
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_USB_GADGET_OMAP) || \
defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \
(defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG))
static void usb_release(struct device *dev)
{
/* normally not freed */
}
#endif
#ifdef CONFIG_USB_GADGET_OMAP
static struct resource udc_resources[] = {
/* order is significant! */
{ /* registers */
.start = IO_ADDRESS(UDC_BASE),
.end = IO_ADDRESS(UDC_BASE + 0xff),
.flags = IORESOURCE_MEM,
}, { /* general IRQ */
.start = IH2_BASE + 20,
.flags = IORESOURCE_IRQ,
}, { /* PIO IRQ */
.start = IH2_BASE + 30,
.flags = IORESOURCE_IRQ,
}, { /* SOF IRQ */
.start = IH2_BASE + 29,
.flags = IORESOURCE_IRQ,
},
};
static u64 udc_dmamask = ~(u32)0;
static struct platform_device udc_device = {
.name = "omap_udc",
.id = -1,
.dev = {
.release = usb_release,
.dma_mask = &udc_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(udc_resources),
.resource = udc_resources,
};
#endif
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* The dmamask must be set for OHCI to work */
static u64 ohci_dmamask = ~(u32)0;
static struct resource ohci_resources[] = {
{
.start = IO_ADDRESS(OMAP_OHCI_BASE),
.end = IO_ADDRESS(OMAP_OHCI_BASE + 4096),
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HHC_1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device ohci_device = {
.name = "ohci",
.id = -1,
.dev = {
.release = usb_release,
.dma_mask = &ohci_dmamask,
.coherent_dma_mask = 0x0fffffff,
},
.num_resources = ARRAY_SIZE(ohci_resources),
.resource = ohci_resources,
};
#endif
#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
static struct resource otg_resources[] = {
/* order is significant! */
{
.start = IO_ADDRESS(OTG_BASE),
.end = IO_ADDRESS(OTG_BASE + 0xff),
.flags = IORESOURCE_MEM,
}, {
.start = IH2_BASE + 8,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device otg_device = {
.name = "omap_otg",
.id = -1,
.dev = {
.release = usb_release,
},
.num_resources = ARRAY_SIZE(otg_resources),
.resource = otg_resources,
};
#endif
/*-------------------------------------------------------------------------*/
// FIXME correct answer depends on hmc_mode,
// as does any nonzero value for config->otg port number
#define is_usb0_device(config) 0
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_ARCH_OMAP_OTG
void __init
omap_otg_init(struct omap_usb_config *config)
{
u32 syscon = OTG_SYSCON_1_REG & 0xffff;
int status;
int alt_pingroup = 0;
/* NOTE: no bus or clock setup (yet?) */
syscon = OTG_SYSCON_1_REG & 0xffff;
if (!(syscon & OTG_RESET_DONE))
pr_debug("USB resets not complete?\n");
// OTG_IRQ_EN_REG = 0;
/* pin muxing and transceiver pinouts */
if (config->pins[0] > 2) /* alt pingroup 2 */
alt_pingroup = 1;
syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
syscon |= omap_usb1_init(config->pins[1]);
syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
OTG_SYSCON_1_REG = syscon;
syscon = config->hmc_mode;
syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
if (config->otg || config->register_host)
syscon |= UHOST_EN;
#ifdef CONFIG_USB_OTG
if (config->otg)
syscon |= OTG_EN;
#endif
pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
OTG_SYSCON_2_REG = syscon;
printk("USB: hmc %d", config->hmc_mode);
if (alt_pingroup)
printk(", usb2 alt %d wires", config->pins[2]);
else if (config->pins[0])
printk(", usb0 %d wires%s", config->pins[2],
is_usb0_device(config) ? " (dev)" : "");
if (config->pins[1])
printk(", usb1 %d wires", config->pins[1]);
if (!alt_pingroup && config->pins[2])
printk(", usb2 %d wires", config->pins[2]);
if (config->otg)
printk(", Mini-AB on usb%d", config->otg - 1);
printk("\n");
/* don't clock unused USB controllers */
syscon = OTG_SYSCON_1_REG;
syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
#ifdef CONFIG_USB_GADGET_OMAP
if (config->otg || config->register_dev) {
syscon &= ~DEV_IDLE_EN;
udc_device.dev.platform_data = config;
status = platform_device_register(&udc_device);
if (status)
pr_debug("can't register UDC device, %d\n", status);
}
#endif
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
if (config->otg || config->register_host) {
syscon &= ~HST_IDLE_EN;
ohci_device.dev.platform_data = config;
status = platform_device_register(&ohci_device);
if (status)
pr_debug("can't register OHCI device, %d\n", status);
}
#endif
#ifdef CONFIG_USB_OTG
if (config->otg) {
syscon &= ~OTG_IDLE_EN;
if (cpu_is_omap730())
otg_resources[1].start = INT_730_USB_OTG;
status = platform_device_register(&otg_device);
// ...
}
#endif
pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
OTG_SYSCON_1_REG = syscon;
status = 0;
}
#else
static inline void omap_otg_init(struct omap_usb_config *config) {}
#endif
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_ARCH_OMAP1510
static void __init omap_1510_usb_init(struct omap_usb_config *config)
{
int status;
unsigned int val;
omap_usb0_init(config->pins[0], is_usb0_device(config));
omap_usb1_init(config->pins[1]);
omap_usb2_init(config->pins[2], 0);
val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
val |= (config->hmc_mode << 1);
omap_writel(val, MOD_CONF_CTRL_0);
// FIXME this has a UDC controller too
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
if (config->otg || config->register_host) {
ohci_device.dev.platform_data = config;
status = platform_device_register(&ohci_device);
if (status)
pr_debug("can't register OHCI device, %d\n", status);
}
// FIXME completely untested ...
#endif
}
#else
static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
#endif
/*-------------------------------------------------------------------------*/
static struct omap_usb_config platform_data;
static int __init
omap_usb_init(void)
{
const struct omap_usb_config *config;
config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
if (config == NULL) {
printk(KERN_ERR "USB: No board-specific platform config found\n");
return -ENODEV;
}
platform_data = *config;
if (cpu_is_omap730()
|| cpu_is_omap1610()
|| cpu_is_omap1710()
|| cpu_is_omap5912())
omap_otg_init(&platform_data);
else if (cpu_is_omap1510())
omap_1510_usb_init(&platform_data);
else {
printk(KERN_ERR "USB: No init for your chip yet\n");
return -ENODEV;
}
return 0;
}
subsys_initcall(omap_usb_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment