Commit 62b2119f authored by Tony Lindgren's avatar Tony Lindgren Committed by Russell King

[ARM PATCH] 1846/1: OMAP update 1/2: arch files

Patch from Tony Lindgren

This patch syncs the mainline kernel with the linux-omap tree. The
patch contains following updates:
- Move virtual IO area to 0xfefb0000 from 0xfffb0000 to fix parts of
  IO area overlapping with ARM Linux reserved memory area
- Add support to OMAP-730, OMAP-5912, and OMAP-1710 processors
- Reorganize board support
- Add OMAP core detection
This patch requires ARM Linux patch 1844/1 be applied to compile
OMAP-730 and OMAP-5912
parent 78c4d584
menu "TI OMAP Implementations"
choice
prompt "OMAP Core Type"
comment "OMAP Core Type"
config ARCH_OMAP730
depends on ARCH_OMAP
default ARCH_OMAP1510
bool "OMAP730 Based System"
select CPU_ARM926T
config ARCH_OMAP1510
bool "OMAP-1510 Based System"
depends on ARCH_OMAP
default y
bool "OMAP1510 Based System"
select CPU_ARM925T
select CPU_DCACHE_WRITETHROUGH
config ARCH_OMAP1610
bool "OMAP-1610 Based System"
depends on ARCH_OMAP
bool "OMAP1610 Based System"
select CPU_ARM926T
endchoice
choice
prompt "OMAP Board Type"
config ARCH_OMAP5912
depends on ARCH_OMAP
default MACH_OMAP_INNOVATOR
bool "OMAP5912 Based System"
select CPU_ARM926T
comment "OMAP Board Type"
config MACH_OMAP_INNOVATOR
bool "TI Innovator"
default y
depends on ARCH_OMAP1510 || ARCH_OMAP1610
help
TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
have such a board.
config MACH_OMAP_H2
bool "TI H2 Support"
depends on ARCH_OMAP1610
select MACH_OMAP_INNOVATOR
help
TI OMAP 1610 H2 board support. Say Y here if you have such
a board.
config MACH_OMAP_H3
bool "TI H3 Support"
depends on ARCH_OMAP1610
help
TI OMAP 1610 H3 board support. Say Y here if you have such
a board.
config MACH_OMAP_H4
bool "TI H4 Support"
depends on ARCH_OMAP1610
help
TI OMAP 1610 H4 board support. Say Y here if you have such
a board.
config MACH_OMAP_OSK
bool "TI OSK Support"
depends on ARCH_OMAP5912
help
TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
if you have such a board.
config MACH_OMAP_PERSEUS2
bool "TI Perseus2"
depends on ARCH_OMAP730
select LEDS
select LEDS_TIMER
select LEDS_CPU
help
Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
a board.
config MACH_OMAP_GENERIC
bool "Generic OMAP board"
depends on ARCH_OMAP1510 || ARCH_OMAP1610
......@@ -38,16 +83,15 @@ config MACH_OMAP_GENERIC
custom OMAP boards. Say Y here if you have a custom
board.
endchoice
comment "OMAP Feature Selections"
config MACH_OMAP_H2
bool "TI H2 Support"
depends on ARCH_OMAP1610 && MACH_OMAP_INNOVATOR
help
TI OMAP 1610 H2 board support. Say Y here if you have such
a board.
#config OMAP_BOOT_TAG
# bool "OMAP bootloader information passing"
# depends on ARCH_OMAP
# default n
# help
# Say Y, if you have a bootloader which passes information
# about your board and its peripheral configuration.
config OMAP_MUX
bool "OMAP multiplexing support"
......@@ -67,6 +111,22 @@ config OMAP_MUX_DEBUG
This is useful if you want to find out the correct values of the
multiplexing registers.
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
config OMAP_ARM_195MHZ
bool "OMAP ARM 195 MHz CPU"
depends on ARCH_OMAP730
......@@ -75,7 +135,7 @@ config OMAP_ARM_195MHZ
config OMAP_ARM_192MHZ
bool "OMAP ARM 192 MHz CPU"
depends on ARCH_OMAP1610
depends on ARCH_OMAP1610 || ARCH_OMAP5912
help
Enable 192MHz clock for OMAP CPU. If unsure, say N.
......@@ -87,7 +147,7 @@ config OMAP_ARM_182MHZ
config OMAP_ARM_168MHZ
bool "OMAP ARM 168 MHz CPU"
depends on ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_OMAP730
depends on ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_OMAP730 || ARCH_OMAP5912
help
Enable 168MHz clock for OMAP CPU. If unsure, say N.
......
......@@ -9,28 +9,28 @@ obj-n :=
obj- :=
led-y := leds.o
# OCPI interconnect support for 1610
ifeq ($(CONFIG_ARCH_OMAP1610),y)
obj-y += ocpi.o
ifeq ($(CONFIG_OMAP_INNOVATOR),y)
obj-y += innovator1610.o
endif
endif
ifeq ($(CONFIG_ARCH_OMAP1510),y)
ifeq ($(CONFIG_OMAP_INNOVATOR),y)
obj-y += innovator1510.o fpga.o
endif
endif
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += omap-generic.o
obj-$(CONFIG_MACH_OMAP_PERSEUS2) += omap-perseus2.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
# OCPI interconnect support for 1610 and 5912
obj-$(CONFIG_ARCH_OMAP1610) += ocpi.o
obj-$(CONFIG_ARCH_OMAP5912) += ocpi.o
# LEDs support
led-$(CONFIG_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-perseus2.o
obj-$(CONFIG_LEDS) += $(led-y)
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
ifeq ($(CONFIG_ARCH_OMAP1510),y)
# Innovator-1510 FPGA
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
endif
# kgdb support
obj-$(CONFIG_KGDB_SERIAL) += kgdb-serial.o
/*
* linux/arch/arm/mach-omap/board-generic.c
*
* Modified from board-innovator1510.c
*
* Code for generic OMAP board. Should work on many OMAP systems where
* the device drivers take care of all the necessary hardware initialization.
* Do not put any board specific code to this file; create a new machine
* type if you need custom low-level initializations.
*
* 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/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include "common.h"
static void __init omap_generic_init_irq(void)
{
omap_init_irq();
}
/*
* Muxes the serial ports on
*/
static void __init omap_early_serial_init(void)
{
omap_cfg_reg(UART1_TX);
omap_cfg_reg(UART1_RTS);
omap_cfg_reg(UART2_TX);
omap_cfg_reg(UART2_RTS);
omap_cfg_reg(UART3_TX);
omap_cfg_reg(UART3_RX);
}
static void __init omap_generic_init(void)
{
/*
* Make sure the serial ports are muxed on at this point.
* You have to mux them off in device drivers later on
* if not needed.
*/
if (cpu_is_omap1510()) {
omap_early_serial_init();
}
}
static void __init omap_generic_map_io(void)
{
omap_map_io();
}
MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xe0000000, 0xe0000000)
BOOT_PARAMS(0x10000100)
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
MACHINE_END
/*
* linux/arch/arm/mach-omap/board-innovator.c
*
* Board specific inits for OMAP-1510 and OMAP-1610 Innovator
*
* Copyright (C) 2001 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
*
* Copyright (C) 2002 MontaVista Software, Inc.
*
* Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
* Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
*
* 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/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/fpga.h>
#include "common.h"
#ifdef CONFIG_ARCH_OMAP1510
extern int omap_gpio_init(void);
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc[] __initdata = {
{ OMAP1510P1_FPGA_BASE, OMAP1510P1_FPGA_START, OMAP1510P1_FPGA_SIZE,
MT_DEVICE },
};
static struct resource innovator1510_smc91x_resources[] = {
[0] = {
.start = OMAP1510P1_FPGA_ETHR_START, /* Physical */
.end = OMAP1510P1_FPGA_ETHR_START + 16,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = INT_ETHER,
.end = INT_ETHER,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device innovator1510_smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(innovator1510_smc91x_resources),
.resource = innovator1510_smc91x_resources,
};
static struct platform_device *innovator1510_devices[] __initdata = {
&innovator1510_smc91x_device,
};
#endif /* CONFIG_ARCH_OMAP1510 */
#ifdef CONFIG_ARCH_OMAP1610
static struct map_desc innovator1610_io_desc[] __initdata = {
{ OMAP1610_ETHR_BASE, OMAP1610_ETHR_START, OMAP1610_ETHR_SIZE,MT_DEVICE },
{ OMAP1610_NOR_FLASH_BASE, OMAP1610_NOR_FLASH_START, OMAP1610_NOR_FLASH_SIZE,
MT_DEVICE },
};
static struct resource innovator1610_smc91x_resources[] = {
[0] = {
.start = OMAP1610_ETHR_START, /* Physical */
.end = OMAP1610_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0, /* Really GPIO 0 */
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device innovator1610_smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(innovator1610_smc91x_resources),
.resource = innovator1610_smc91x_resources,
};
static struct platform_device *innovator1610_devices[] __initdata = {
&innovator1610_smc91x_device,
};
#endif /* CONFIG_ARCH_OMAP1610 */
void innovator_init_irq(void)
{
omap_init_irq();
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
omap_gpio_init();
fpga_init_irq();
}
#endif
}
static void __init innovator_init(void)
{
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
}
#endif
}
static void __init innovator_map_io(void)
{
omap_map_io();
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
/* Dump the Innovator FPGA rev early - useful info for support. */
printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
fpga_read(OMAP1510P1_FPGA_REV_HIGH),
fpga_read(OMAP1510P1_FPGA_REV_LOW),
fpga_read(OMAP1510P1_FPGA_BOARD_REV));
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
iotable_init(innovator1610_io_desc, ARRAY_SIZE(innovator1610_io_desc));
}
#endif
}
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
MAINTAINER("MontaVista Software, Inc.")
BOOT_MEM(0x10000000, 0xe0000000, 0xe0000000)
BOOT_PARAMS(0x10000100)
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
INIT_MACHINE(innovator_init)
MACHINE_END
/*
* linux/arch/arm/mach-omap/board-osk.c
*
* Board specific init for OMAP5912 OSK
*
* Written by Dirk Behme <dirk.behme@de.bosch.com>
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/fpga.h>
#include "common.h"
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,
MT_DEVICE },
};
static struct resource osk5912_smc91x_resources[] = {
[0] = {
.start = OMAP_OSK_ETHR_START, /* Physical */
.end = OMAP_OSK_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0, /* Really GPIO 0 */
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device osk5912_smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(osk5912_smc91x_resources),
.resource = osk5912_smc91x_resources,
};
static struct platform_device *osk5912_devices[] __initdata = {
&osk5912_smc91x_device,
};
void osk_init_irq(void)
{
omap_init_irq();
}
static void __init osk_init(void)
{
platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
}
static void __init osk_map_io(void)
{
omap_map_io();
iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
}
MACHINE_START(OMAP_OSK, "TI-OSK")
MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>")
BOOT_MEM(0x10000000, 0xe0000000, 0xe0000000)
BOOT_PARAMS(0x10000100)
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
INIT_MACHINE(osk_init)
MACHINE_END
/*
* linux/arch/arm/mach-omap/board-perseus2.c
*
* Modified from board-generic.c
*
* 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/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/clocks.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include "common.h"
void omap_perseus2_init_irq(void)
{
omap_init_irq();
}
static struct resource smc91x_resources[] = {
[0] = {
.start = OMAP730_FPGA_ETHR_START, /* Physical */
.end = OMAP730_FPGA_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0,
.end = 0,
.flags = INT_ETHER,
},
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
static struct platform_device *devices[] __initdata = {
&smc91x_device,
};
static void __init omap_perseus2_init(void)
{
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
}
/* 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,
MT_DEVICE},
};
static void __init omap_perseus2_map_io(void)
{
omap_map_io();
iotable_init(omap_perseus2_io_desc,
ARRAY_SIZE(omap_perseus2_io_desc));
/* Early, board-dependent init */
/*
* Hold GSM Reset until needed
*/
omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
/*
* UARTs -> done automagically by 8250 driver
*/
/*
* CSx timings, GPIO Mux ... setup
*/
/* Flash: CS0 timings setup */
omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
/*
* Ethernet support trough the debug board
* CS1 timings setup
*/
omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
/*
* Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
* It is used as the Ethernet controller interrupt
*/
omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
}
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
MAINTAINER("Kevin Hilman <k-hilman@ti.com>")
BOOT_MEM(0x10000000, 0xe0000000, 0xe0000000)
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
INIT_MACHINE(omap_perseus2_init)
MACHINE_END
......@@ -93,6 +93,8 @@ static struct bus_type omap_bus_types[OMAP_NR_BUSES] = {
*/
inline int dmadev_uses_omap_lbus(struct device * dev)
{
if (dev == NULL || !cpu_is_omap1510())
return 0;
return dev->bus == &omap_bus_types[OMAP_BUS_LBUS] ? 1 : 0;
}
......@@ -184,6 +186,9 @@ int omap_device_register(struct omap_dev *odev)
if (odev->dma_mask)
odev->dev.dma_mask = odev->dma_mask;
if (odev->coherent_dma_mask)
odev->dev.coherent_dma_mask = odev->coherent_dma_mask;
snprintf(odev->dev.bus_id, BUS_ID_SIZE, "%s%u",
odev->name, odev->devid);
......
......@@ -34,6 +34,7 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/arch/clocks.h>
#include <asm/arch/board.h>
/* Input clock in MHz */
static unsigned int source_clock = 12;
......@@ -49,10 +50,10 @@ typedef struct {
char *name;
__u8 flags;
ck_t parent;
volatile __u16 *rate_reg; /* Clock rate register */
volatile __u16 *enbl_reg; /* Enable register */
volatile __u16 *idle_reg; /* Idle register */
volatile __u16 *slct_reg; /* Select register */
unsigned long rate_reg; /* Clock rate register */
unsigned long enbl_reg; /* Enable register */
unsigned long idle_reg; /* Idle register */
unsigned long slct_reg; /* Select register */
__s8 rate_shift; /* Clock rate bit shift */
__s8 enbl_shift; /* Clock enable bit shift */
__s8 idle_shift; /* Clock idle bit shift */
......@@ -245,7 +246,7 @@ int
ck_set_input(ck_t ck, ck_t input)
{
int ret = 0, shift;
volatile __u16 *reg;
unsigned short reg;
unsigned long flags;
if (!CK_IN_RANGE(ck) || !CK_CAN_SWITCH(ck)) {
......@@ -253,15 +254,17 @@ ck_set_input(ck_t ck, ck_t input)
goto exit;
}
reg = CK_SELECT_REG(ck);
reg = omap_readw(CK_SELECT_REG(ck));
shift = CK_SELECT_SHIFT(ck);
spin_lock_irqsave(&clock_lock, flags);
if (input == OMAP_CLKIN) {
*((volatile __u16 *) reg) &= ~(1 << shift);
reg &= ~(1 << shift);
omap_writew(reg, CK_SELECT_REG(ck));
goto exit;
} else if (input == CK_PARENT(ck)) {
*((volatile __u16 *) reg) |= (1 << shift);
reg |= (1 << shift);
omap_writew(reg, CK_SELECT_REG(ck));
goto exit;
}
......@@ -285,11 +288,11 @@ ck_get_input(ck_t ck, ck_t * input)
spin_lock_irqsave(&clock_lock, flags);
if (CK_CAN_SWITCH(ck)) {
int shift;
volatile __u16 *reg;
unsigned short reg;
reg = CK_SELECT_REG(ck);
reg = omap_readw(CK_SELECT_REG(ck));
shift = CK_SELECT_SHIFT(ck);
if (*reg & (1 << shift)) {
if (reg & (1 << shift)) {
*input = CK_PARENT(ck);
goto exit;
}
......@@ -305,7 +308,7 @@ ck_get_input(ck_t ck, ck_t * input)
static int
__ck_set_pll_rate(ck_t ck, int rate)
{
volatile __u16 *pll;
unsigned short pll;
unsigned long flags;
if ((rate < 0) || (rate > CK_MAX_PLL_FREQ))
......@@ -322,13 +325,16 @@ __ck_set_pll_rate(ck_t ck, int rate)
}
spin_lock_irqsave(&clock_lock, flags);
pll = (volatile __u16 *) CK_RATE_REG(ck);
pll = omap_readw(CK_RATE_REG(ck));
/* Clear the rate bits */
*pll &= ~(0x1f << 5);
pll &= ~(0x1f << 5);
/* Set the rate bits */
*pll |= (ck_lookup_table[rate - 1] << 5);
pll |= (ck_lookup_table[rate - 1] << 5);
omap_writew(pll, CK_RATE_REG(ck));
spin_unlock_irqrestore(&clock_lock, flags);
return 0;
......@@ -338,7 +344,7 @@ static int
__ck_set_clkm_rate(ck_t ck, int rate)
{
int shift, prate, div, ret;
volatile __u16 *reg;
unsigned short reg;
unsigned long flags;
spin_lock_irqsave(&clock_lock, flags);
......@@ -390,10 +396,11 @@ __ck_set_clkm_rate(ck_t ck, int rate)
* At last, we can set the divisor. Clear the old rate bits and
* set the new ones.
*/
reg = (volatile __u16 *) CK_RATE_REG(ck);
reg = omap_readw(CK_RATE_REG(ck));
shift = CK_RATE_SHIFT(ck);
*reg &= ~(3 << shift);
*reg |= (div << shift);
reg &= ~(3 << shift);
reg |= (div << shift);
omap_writew(reg, CK_RATE_REG(ck));
/* And return the new (actual, after rounding down) rate. */
ret = prate;
......@@ -432,7 +439,7 @@ __ck_get_pll_rate(ck_t ck)
{
int m, d;
__u16 pll = *((volatile __u16 *) CK_RATE_REG(ck));
unsigned short pll = omap_readw(CK_RATE_REG(ck));
m = (pll & (0x1f << 7)) >> 7;
m = m ? m : 1;
......@@ -448,7 +455,7 @@ __ck_get_clkm_rate(ck_t ck)
static int bits2div[] = { 1, 2, 4, 8 };
int in, bits, reg, shift;
reg = *(CK_RATE_REG(ck));
reg = omap_readw(CK_RATE_REG(ck));
shift = CK_RATE_SHIFT(ck);
in = ck_get_rate(CK_PARENT(ck));
......@@ -520,7 +527,7 @@ ck_get_rate(ck_t ck)
int
ck_enable(ck_t ck)
{
volatile __u16 *reg;
unsigned short reg;
int ret = -EINVAL, shift;
unsigned long flags;
......@@ -537,9 +544,10 @@ ck_enable(ck_t ck)
goto exit;
spin_lock_irqsave(&clock_lock, flags);
reg = CK_ENABLE_REG(ck);
reg = omap_readw(CK_ENABLE_REG(ck));
shift = CK_ENABLE_SHIFT(ck);
*reg |= (1 << shift);
reg |= (1 << shift);
omap_writew(reg, CK_ENABLE_REG(ck));
spin_unlock_irqrestore(&clock_lock, flags);
exit:
......@@ -549,7 +557,7 @@ ck_enable(ck_t ck)
int
ck_disable(ck_t ck)
{
volatile __u16 *reg;
unsigned short reg;
int ret = -EINVAL, shift;
unsigned long flags;
......@@ -568,9 +576,10 @@ ck_disable(ck_t ck)
return -EINVAL;
spin_lock_irqsave(&clock_lock, flags);
reg = CK_ENABLE_REG(ck);
reg = omap_readw(CK_ENABLE_REG(ck));
shift = CK_ENABLE_SHIFT(ck);
*reg &= ~(1 << shift);
reg &= ~(1 << shift);
omap_writew(reg, CK_ENABLE_REG(ck));
spin_unlock_irqrestore(&clock_lock, flags);
exit:
......@@ -606,54 +615,71 @@ __ck_make_lookup_table(void)
int __init
init_ck(void)
{
const struct omap_clock_info *info;
int crystal_type = 0; /* Default 12 MHz */
__ck_make_lookup_table();
info = omap_get_per_info(OMAP_TAG_CLOCK, struct omap_clock_info);
if (info != NULL) {
if (!cpu_is_omap1510())
crystal_type = info->system_clock_type;
}
/* We want to be in syncronous scalable mode */
*ARM_SYSST = 0x1000;
omap_writew(0x1000, ARM_SYSST);
#if defined(CONFIG_OMAP_ARM_30MHZ)
*ARM_CKCTL = 0x1555;
*DPLL_CTL_REG = 0x2290;
omap_writew(0x1555, ARM_CKCTL);
omap_writew(0x2290, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_60MHZ)
*ARM_CKCTL = 0x1005;
*DPLL_CTL_REG = 0x2290;
omap_writew(0x1005, ARM_CKCTL);
omap_writew(0x2290, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_96MHZ)
*ARM_CKCTL = 0x1005;
*DPLL_CTL_REG = 0x2410;
omap_writew(0x1005, ARM_CKCTL);
omap_writew(0x2410, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_120MHZ)
*ARM_CKCTL = 0x110a;
*DPLL_CTL_REG = 0x2510;
omap_writew(0x110a, ARM_CKCTL);
omap_writew(0x2510, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_168MHZ)
*ARM_CKCTL = 0x110f;
*DPLL_CTL_REG = 0x2710;
omap_writew(0x110f, ARM_CKCTL);
omap_writew(0x2710, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
*ARM_CKCTL = 0x250E;
*DPLL_CTL_REG = 0x2713;
#elif defined(CONFIG_OMAP_ARM_192MHZ) && defined(CONFIG_ARCH_OMAP1610)
*ARM_CKCTL = 0x110f;
omap_writew(0x250E, ARM_CKCTL);
omap_writew(0x2710, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
omap_writew(0x150f, ARM_CKCTL);
if (crystal_type == 2) {
source_clock = 13; /* MHz */
*DPLL_CTL_REG = 0x2510;
omap_writew(0x2510, DPLL_CTL_REG);
} else
*DPLL_CTL_REG = 0x2810;
omap_writew(0x2810, DPLL_CTL_REG);
#elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
*ARM_CKCTL = 0x250E;
*DPLL_CTL_REG = 0x2793;
omap_writew(0x250E, ARM_CKCTL);
omap_writew(0x2790, DPLL_CTL_REG);
#else
#error "OMAP MHZ not set, please run make xconfig"
#endif
#ifdef CONFIG_MACH_OMAP_PERSEUS2
/* Select slicer output as OMAP input clock */
omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL_REG) & ~0x1, OMAP730_PCC_UPLD_CTRL_REG);
#endif
/* Turn off some other junk the bootloader might have turned on */
*ARM_CKCTL &= 0x0fff; /* Turn off DSP, ARM_INTHCK, ARM_TIMXO */
*ARM_RSTCT1 = 0; /* Put DSP/MPUI into reset until needed */
*ARM_RSTCT2 = 1;
*ARM_IDLECT1 = 0x400;
/* Turn off DSP, ARM_INTHCK, ARM_TIMXO */
omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
/* Put DSP/MPUI into reset until needed */
omap_writew(0, ARM_RSTCT1);
omap_writew(1, ARM_RSTCT2);
omap_writew(0x400, ARM_IDLECT1);
/*
* According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
* of the ARM_IDLECT2 register must be set to zero. The power-on
* default value of this bit is one.
*/
*ARM_IDLECT2 = 0x0000; /* Turn LCD clock off also */
omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
/*
* Only enable those clocks we will need, let the drivers
......
......@@ -13,29 +13,60 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/console.h>
#include <asm/hardware.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <asm/arch/clocks.h>
#include <asm/arch/board.h>
#include <asm/io.h>
#include "common.h"
/*
* Common OMAP I/O mapping
* ----------------------------------------------------------------------------
* OMAP I/O mapping
*
* The machine specific code may provide the extra mapping besides the
* default mapping provided here.
* ----------------------------------------------------------------------------
*/
static struct map_desc standard_io_desc[] __initdata = {
{ IO_BASE, IO_START, IO_SIZE, MT_DEVICE },
{ OMAP_DSP_BASE, OMAP_DSP_START, OMAP_DSP_SIZE, MT_DEVICE },
{ OMAP_DSPREG_BASE, OMAP_DSPREG_START, OMAP_DSPREG_SIZE, MT_DEVICE },
{ OMAP_SRAM_BASE, OMAP_SRAM_START, OMAP_SRAM_SIZE, MT_DEVICE }
static struct map_desc omap_io_desc[] __initdata = {
{ IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
};
#ifdef CONFIG_ARCH_OMAP730
static struct map_desc omap730_io_desc[] __initdata = {
{ OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE },
{ OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
{ OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE }
};
#endif
#ifdef CONFIG_ARCH_OMAP1510
static struct map_desc omap1510_io_desc[] __initdata = {
{ OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE },
{ OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
{ OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE }
};
#endif
#ifdef CONFIG_ARCH_OMAP1610
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 },
{ OMAP1610_SRAM_BASE, OMAP1610_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE }
};
#endif
#ifdef CONFIG_ARCH_OMAP5912
static struct map_desc omap5912_io_desc[] __initdata = {
{ OMAP5912_DSP_BASE, OMAP5912_DSP_START, OMAP5912_DSP_SIZE, MT_DEVICE },
{ OMAP5912_DSPREG_BASE, OMAP5912_DSPREG_START, OMAP5912_DSPREG_SIZE, MT_DEVICE },
{ OMAP5912_SRAM_BASE, OMAP5912_SRAM_START, OMAP5912_SRAM_SIZE, MT_DEVICE }
};
#endif
static int initialized = 0;
......@@ -43,13 +74,36 @@ static void __init _omap_map_io(void)
{
initialized = 1;
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
/* We have to initialize the IO space mapping before we can run
* cpu_is_omapxxx() macros. */
iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
#ifdef CONFIG_ARCH_OMAP730
if (cpu_is_omap730()) {
iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
}
#endif
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
}
#endif
#ifdef CONFIG_ARCH_OMAP5912
if (cpu_is_omap5912()) {
iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
}
#endif
/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
* on a Posted Write in the TIPB Bridge".
*/
__raw_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG);
__raw_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG);
omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG);
omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG);
/* Must init clocks early to assure that timer interrupt works
*/
......@@ -65,5 +119,55 @@ void omap_map_io(void)
_omap_map_io();
}
EXPORT_SYMBOL(omap_map_io);
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_info_entry *info = NULL;
#ifdef CONFIG_OMAP_BOOT_TAG
if (omap_bootloader_tag_len > 4)
info = (struct omap_board_info_entry *) omap_bootloader_tag;
while (info != NULL) {
u8 *next;
if (info->tag == tag)
break;
next = (u8 *) info + sizeof(*info) + info->len;
if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
info = NULL;
else
info = (struct omap_board_info_entry *) next;
}
#endif
if (info == NULL)
return NULL;
if (info->len != len) {
printk(KERN_ERR "OMAP per_info: Length mismatch with tag %x (want %d, got %d)\n",
tag, len, info->len);
return NULL;
}
return info->data;
}
EXPORT_SYMBOL(__omap_get_per_info);
static int __init omap_add_serial_console(void)
{
const struct omap_uart_info *info;
info = omap_get_per_info(OMAP_TAG_UART, struct omap_uart_info);
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);
/*
* 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
extern void omap_map_io(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
This diff is collapsed.
/*
* linux/arch/arm/mach-omap/fpga.c
*
* Interrupt handler for OMAP-1510 FPGA
* Interrupt handler for OMAP-1510 Innovator FPGA
*
* Copyright (C) 2001 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
......
This diff is collapsed.
/*
* linux/arch/arm/mach-omap/irq.c
*
* Interrupt handler for OMAP-1510 and 1610
* Interrupt handler for all OMAP boards
*
* Copyright (C) 2001 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
* Copyright (C) 2004 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
*
* Modified for OMAP-1610 by Tony Lindgren <tony.lindgren@nokia.com>
* GPIO interrupt handler moved to gpio.c for OMAP-1610 by Juha Yrjola
* Completely re-written to support various OMAP chips with bank specific
* interrupt handlers.
*
* Some snippets of the code taken from the older OMAP interrupt handler
* Copyright (C) 2001 RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
*
* GPIO interrupt handler moved to gpio.c by Juha Yrjola
*
* 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
......@@ -44,181 +49,226 @@
#include <asm/io.h>
#define NUM_IRQS IH_BOARD_BASE
#include "irq.h"
static void mask_irq(unsigned int irq);
static void unmask_irq(unsigned int irq);
static void ack_irq(unsigned int irq);
static unsigned int banks = 0;
static struct omap_irq_bank irq_banks[MAX_NR_IRQ_BANKS];
static inline void
write_ih(int level, int reg, u32 value)
static inline unsigned int irq_bank_readl(int bank, int offset)
{
if (cpu_is_omap1510()) {
__raw_writel(value,
(IO_ADDRESS((level ? OMAP_IH2_BASE : OMAP_IH1_BASE) +
(reg))));
} else {
if (level) {
__raw_writel(value,
IO_ADDRESS(OMAP_IH2_BASE + ((level - 1) << 8) +
reg));
} else {
__raw_writel(value, IO_ADDRESS(OMAP_IH1_BASE + reg));
}
}
return omap_readl(irq_banks[bank].base_reg + offset);
}
static inline u32
read_ih(int level, int reg)
static inline void irq_bank_writel(unsigned long value, int bank, int offset)
{
if (cpu_is_omap1510()) {
return __raw_readl((IO_ADDRESS((level ? OMAP_IH2_BASE : OMAP_IH1_BASE)
+ (reg))));
} else {
if (level) {
return __raw_readl(IO_ADDRESS(OMAP_IH2_BASE +
((level - 1) << 8) + reg));
} else {
return __raw_readl(IO_ADDRESS(OMAP_IH1_BASE + reg));
}
}
omap_writel(value, irq_banks[bank].base_reg + offset);
}
static inline int
get_level(int irq)
/*
* Ack routine for chips with register offsets of 0x100
*/
static void omap_offset_ack_irq(unsigned int irq)
{
if (cpu_is_omap1510()) {
return (((irq) < IH2_BASE) ? 0 : 1);
if (irq > 31)
omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG);
omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG);
}
/*
* Mask routine for chips with register offsets of 0x100
*/
static void omap_offset_mask_irq(unsigned int irq)
{
int bank = IRQ_TO_BANK(irq);
if (bank) {
omap_writel(
omap_readl(OMAP_IH2_BASE + BANK_OFFSET(bank) + IRQ_MIR)
| (1 << IRQ_BIT(irq)),
OMAP_IH2_BASE + BANK_OFFSET(bank) + IRQ_MIR);
} else {
if (irq < IH2_BASE)
return 0;
else {
return (irq >> 5);
}
omap_writel(
omap_readl(OMAP_IH1_BASE + IRQ_MIR)
| (1 << IRQ_BIT(irq)),
OMAP_IH1_BASE + IRQ_MIR);
}
}
static inline int
get_irq_num(int irq)
/*
* Unmask routine for chips with register offsets of 0x100
*/
static void omap_offset_unmask_irq(unsigned int irq)
{
if (cpu_is_omap1510()) {
return (((irq) < IH2_BASE) ? irq : irq - IH2_BASE);
int bank = IRQ_TO_BANK(irq);
if (bank) {
omap_writel(
omap_readl(OMAP_IH2_BASE + BANK_OFFSET(bank) + IRQ_MIR)
& ~(1 << IRQ_BIT(irq)),
OMAP_IH2_BASE + BANK_OFFSET(bank) + IRQ_MIR);
} else {
return irq & 0x1f;
omap_writel(
omap_readl(OMAP_IH1_BASE + IRQ_MIR)
& ~(1 << IRQ_BIT(irq)),
OMAP_IH1_BASE + IRQ_MIR);
}
}
static void
mask_irq(unsigned int irq)
static void omap_offset_mask_ack_irq(unsigned int irq)
{
int level = get_level(irq);
int irq_num = get_irq_num(irq);
u32 mask = read_ih(level, IRQ_MIR) | (1 << irq_num);
write_ih(level, IRQ_MIR, mask);
omap_offset_mask_irq(irq);
omap_offset_ack_irq(irq);
}
static void
ack_irq(unsigned int irq)
/*
* Given the irq number returns the bank number
*/
signed int irq_get_bank(unsigned int irq)
{
int level = get_level(irq);
int i;
if (level > 1)
level = 1;
do {
write_ih(level, IRQ_CONTROL_REG, 0x1);
/*
* REVISIT: So says the TRM:
* if (level) write_ih(0, ITR, 0);
*/
} while (level--);
for (i = 0; i < banks; i++) {
if (irq >= irq_banks[i].start_irq
&& irq <= irq_banks[i].start_irq + BANK_NR_IRQS) {
return i;
}
}
printk(KERN_ERR "No irq handler found for irq %i\n", irq);
return -ENODEV;
}
void
unmask_irq(unsigned int irq)
/*
* Given the bank and irq number returns the irq bit at the bank register
*/
signed int irq_bank_get_bit(int bank, unsigned int irq)
{
int level = get_level(irq);
int irq_num = get_irq_num(irq);
u32 mask = read_ih(level, IRQ_MIR) & ~(1 << irq_num);
if (irq_banks[bank].start_irq > irq) {
printk(KERN_ERR "Incorrect irq %i: bank %i offset %i\n",
irq, bank, irq_banks[bank].start_irq);
return -ENODEV;
}
write_ih(level, IRQ_MIR, mask);
return irq - irq_banks[bank].start_irq;
}
static void
mask_ack_irq(unsigned int irq)
/*
* Allows tuning the IRQ type and priority
*
* NOTE: There is currently no OMAP fiq handler for Linux. Read the
* mailing list threads on FIQ handlers if you are planning to
* add a FIQ handler for OMAP.
*/
void omap_irq_set_cfg(int irq, int fiq, int priority, int irq_level)
{
mask_irq(irq);
ack_irq(irq);
signed int bank;
unsigned int irq_bit;
unsigned long val, offset;
bank = irq_get_bank(irq);
if (bank < 0)
return;
irq_bit = irq_bank_get_bit(bank, irq);
if (irq_bit < 0)
return;
/* FIQ is only availabe on bank 0 interrupts */
fiq = bank ? 0 : (fiq & 0x1);
val = fiq | ((priority & 0x1f) << 2) | ((irq_level & 0x1) << 1);
offset = IRQ_ILR0 + irq_bit * 0x4;
irq_bank_writel(val, bank, offset);
}
static struct irqchip omap_normal_irq = {
.ack = mask_ack_irq,
.mask = mask_irq,
.unmask = unmask_irq,
static struct omap_irq_desc *irq_bank_desc[] __initdata = {
&omap730_bank0_irqs,
&omap730_bank1_irqs,
&omap730_bank2_irqs,
&omap1510_bank0_irqs,
&omap1510_bank1_irqs,
&omap1610_bank0_irqs,
&omap1610_bank1_irqs,
&omap1610_bank2_irqs,
&omap1610_bank3_irqs,
NULL,
};
static void
irq_priority(int irq, int fiq, int priority, int trigger)
void __init omap_init_irq(void)
{
int level, irq_num;
unsigned long reg_value, reg_addr;
level = get_level(irq);
irq_num = get_irq_num(irq);
/* FIQ is only available on level 0 interrupts */
fiq = level ? 0 : (fiq & 0x1);
reg_value = (fiq) | ((priority & 0x1f) << 2) |
((trigger & 0x1) << 1);
reg_addr = (IRQ_ILR0 + irq_num * 0x4);
write_ih(level, reg_addr, reg_value);
}
int i,j, board_irq_type = 0, interrupts = 0;
struct omap_irq_desc *entry;
void __init
omap_init_irq(void)
{
int i, irq_count, irq_bank_count = 0;
uint *trigger;
if (cpu_is_omap1510()) {
static uint trigger_1510[2] = {
0xb3febfff, 0xffbfffed
};
irq_bank_count = 2;
irq_count = 64;
trigger = trigger_1510;
if (cpu_is_omap730()) {
board_irq_type = OMAP_IRQ_TYPE730;
} else if (cpu_is_omap1510()) {
board_irq_type = OMAP_IRQ_TYPE1510;
} else if (cpu_is_omap1610() || cpu_is_omap5912()) {
board_irq_type = OMAP_IRQ_TYPE1610;
}
if (cpu_is_omap1610()) {
static uint trigger_1610[5] = {
0xb3fefe8f, 0xfffff7ff, 0xffffffff
};
irq_bank_count = 5;
irq_count = 160;
trigger = trigger_1610;
if (board_irq_type == 0) {
printk("Could not detect OMAP type\n");
return;
}
/* Scan through the interrupt bank maps and copy the right data */
for (i = 0; (entry = irq_bank_desc[i]) != NULL; i++) {
if (entry->cpu_type == board_irq_type) {
printk("Type %i IRQs from %3i to %3i base at 0x%lx\n",
board_irq_type, entry->start_irq,
entry->start_irq + BANK_NR_IRQS, entry->base_reg);
irq_banks[banks].start_irq = entry->start_irq;
irq_banks[banks].level_map = entry->level_map;
irq_banks[banks].base_reg = entry->base_reg;
irq_banks[banks].mask_reg = entry->mask_reg;
irq_banks[banks].ack_reg = entry->ack_reg;
irq_banks[banks].handler = entry->handler;
interrupts += BANK_NR_IRQS;
banks++;
}
if (cpu_is_omap730()) {
static uint trigger_730[] = {
0xb3f8e22f, 0xfdb9c1f2, 0x800040f3
};
irq_bank_count = 3;
irq_count = 96;
trigger = trigger_730;
}
for (i = 0; i < irq_bank_count; i++) {
printk("Found total of %i interrupts in %i interrupt banks\n",
interrupts, banks);
/* Mask and clear all interrupts */
write_ih(i, IRQ_MIR, ~0x0);
write_ih(i, IRQ_ITR, 0x0);
for (i = 0; i < banks; i++) {
irq_bank_writel(~0x0, i, IRQ_MIR);
irq_bank_writel(0x0, i, IRQ_ITR);
}
/* Clear any pending interrupts */
write_ih(1, IRQ_CONTROL_REG, 3);
write_ih(0, IRQ_CONTROL_REG, 3);
for (i = 0; i < irq_count; i++) {
set_irq_chip(i, &omap_normal_irq);
set_irq_handler(i, do_level_IRQ);
set_irq_flags(i, IRQF_VALID);
/*
* Clear any pending interrupts
*/
irq_bank_writel(3, 0, IRQ_CONTROL_REG);
irq_bank_writel(3, 1, IRQ_CONTROL_REG);
irq_priority(i, 0, 0, trigger[get_level(i)] >> get_irq_num(i) & 1);
/* Install the interrupt handlers for each bank */
for (i = 0; i < banks; i++) {
for (j = irq_banks[i].start_irq;
j <= irq_banks[i].start_irq + BANK_NR_IRQS; j++) {
int irq_level;
set_irq_chip(j, irq_banks[i].handler);
set_irq_handler(j, do_level_IRQ);
set_irq_flags(j, IRQF_VALID);
irq_level = irq_banks[i].level_map
>> (j - irq_banks[i].start_irq) & 1;
omap_irq_set_cfg(j, 0, 0, irq_level);
}
unmask_irq(INT_IH2_IRQ);
}
/* Unmask level 2 handler */
omap_writel(0, irq_banks[0].mask_reg);
}
EXPORT_SYMBOL(omap_irq_set_cfg);
/*
* linux/arch/arm/mach-omap/irq.h
*
* OMAP specific interrupt bank definitions
*
* Copyright (C) 2004 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
*
* 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.
*/
#define OMAP_IRQ_TYPE710 1
#define OMAP_IRQ_TYPE730 2
#define OMAP_IRQ_TYPE1510 3
#define OMAP_IRQ_TYPE1610 4
#define OMAP_IRQ_TYPE1710 5
#define MAX_NR_IRQ_BANKS 4
#define BANK_NR_IRQS 32
struct omap_irq_desc {
unsigned int cpu_type;
unsigned int start_irq;
unsigned long level_map;
unsigned long base_reg;
unsigned long mask_reg;
unsigned long ack_reg;
struct irqchip *handler;
};
struct omap_irq_bank {
unsigned int start_irq;
unsigned long level_map;
unsigned long base_reg;
unsigned long mask_reg;
unsigned long ack_reg;
struct irqchip *handler;
};
static void omap_offset_ack_irq(unsigned int irq);
static void omap_offset_mask_irq(unsigned int irq);
static void omap_offset_unmask_irq(unsigned int irq);
static void omap_offset_mask_ack_irq(unsigned int irq);
/* NOTE: These will not work if irq bank offset != 0x100 */
#define IRQ_TO_BANK(irq) (irq >> 5)
#define IRQ_BIT(irq) (irq & 0x1f)
#define BANK_OFFSET(bank) ((bank - 1) * 0x100)
static struct irqchip omap_offset_irq = {
.ack = omap_offset_mask_ack_irq,
.mask = omap_offset_mask_irq,
.unmask = omap_offset_unmask_irq,
};
/*
* OMAP-730 interrupt banks
*/
static struct omap_irq_desc omap730_bank0_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE730,
.start_irq = 0,
.level_map = 0xb3f8e22f,
.base_reg = OMAP_IH1_BASE,
.mask_reg = OMAP_IH1_BASE + IRQ_MIR,
.ack_reg = OMAP_IH1_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap730_bank1_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE730,
.start_irq = 32,
.level_map = 0xfdb9c1f2,
.base_reg = OMAP_IH2_BASE,
.mask_reg = OMAP_IH2_BASE + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap730_bank2_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE730,
.start_irq = 64,
.level_map = 0x800040f3,
.base_reg = OMAP_IH2_BASE + 0x100,
.mask_reg = OMAP_IH2_BASE + 0x100 + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG, /* Not replicated */
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
/*
* OMAP-1510 interrupt banks
*/
static struct omap_irq_desc omap1510_bank0_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1510,
.start_irq = 0,
.level_map = 0xb3febfff,
.base_reg = OMAP_IH1_BASE,
.mask_reg = OMAP_IH1_BASE + IRQ_MIR,
.ack_reg = OMAP_IH1_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap1510_bank1_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1510,
.start_irq = 32,
.level_map = 0xffbfffed,
.base_reg = OMAP_IH2_BASE,
.mask_reg = OMAP_IH2_BASE + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
/*
* OMAP-1610 interrupt banks
*/
static struct omap_irq_desc omap1610_bank0_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1610,
.start_irq = 0,
.level_map = 0xb3fefe8f,
.base_reg = OMAP_IH1_BASE,
.mask_reg = OMAP_IH1_BASE + IRQ_MIR,
.ack_reg = OMAP_IH1_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap1610_bank1_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1610,
.start_irq = 32,
.level_map = 0xfffff7ff,
.base_reg = OMAP_IH2_BASE,
.mask_reg = OMAP_IH2_BASE + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG,
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap1610_bank2_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1610,
.start_irq = 64,
.level_map = 0xffffffff,
.base_reg = OMAP_IH2_BASE + 0x100,
.mask_reg = OMAP_IH2_BASE + 0x100 + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG, /* Not replicated */
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
static struct omap_irq_desc omap1610_bank3_irqs __initdata = {
.cpu_type = OMAP_IRQ_TYPE1610,
.start_irq = 96,
.level_map = 0xffffffff,
.base_reg = OMAP_IH2_BASE + 0x200,
.mask_reg = OMAP_IH2_BASE + 0x200 + IRQ_MIR,
.ack_reg = OMAP_IH2_BASE + IRQ_CONTROL_REG, /* Not replicated */
.handler = &omap_offset_irq, /* IH2 regs at 0x100 offsets */
};
......@@ -14,7 +14,6 @@
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
#include <asm/arch/omap-perseus2.h>
#include "leds.h"
......@@ -97,7 +96,7 @@ void perseus2_leds_event(led_event_t evt)
/*
* Actually burn the LEDs
*/
__raw_writew(~hw_led_state & 0xffff, OMAP730_FPGA_LEDS);
omap_writew(~hw_led_state & 0xffff, OMAP730_FPGA_LEDS);
local_irq_restore(flags);
}
......@@ -13,9 +13,13 @@
static int __init
omap1510_leds_init(void)
{
if (machine_is_innovator())
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
else if (machine_is_omap_perseus2()) {
leds_event = perseus2_leds_event;
}
leds_event(led_start);
return 0;
}
......
......@@ -32,14 +32,14 @@
#define __MUX_C__
#include <asm/arch/mux.h>
static spinlock_t mux_spin_lock = SPIN_LOCK_UNLOCKED;
/*
* Sets the Omap MUX and PULL_DWN registers based on the table
*/
int omap_cfg_reg(const reg_cfg_t reg_cfg)
{
#ifdef CONFIG_OMAP_MUX
static spinlock_t mux_spin_lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
reg_cfg_set *cfg;
unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
......@@ -56,20 +56,20 @@ int omap_cfg_reg(const reg_cfg_t reg_cfg)
/* Check the mux register in question */
if (cfg->mux_reg) {
reg_orig = __raw_readl(cfg->mux_reg);
reg_orig = omap_readl(cfg->mux_reg);
/* The mux registers always seem to be 3 bits long */
reg = reg_orig & ~(0x7 << cfg->mask_offset);
reg |= (cfg->mask << cfg->mask_offset);
__raw_writel(reg, cfg->mux_reg);
omap_writel(reg, cfg->mux_reg);
}
/* Check for pull up or pull down selection on 1610 */
if (!cpu_is_omap1510()) {
if (cfg->pu_pd_reg && cfg->pull_val) {
pu_pd_orig = __raw_readl(cfg->pu_pd_reg);
pu_pd_orig = omap_readl(cfg->pu_pd_reg);
if (cfg->pu_pd_val) {
/* Use pull up */
pu_pd = pu_pd_orig | (1 << cfg->pull_bit);
......@@ -77,13 +77,13 @@ int omap_cfg_reg(const reg_cfg_t reg_cfg)
/* Use pull down */
pu_pd = pu_pd_orig & ~(1 << cfg->pull_bit);
}
__raw_writel(pu_pd, cfg->pu_pd_reg);
omap_writel(pu_pd, cfg->pu_pd_reg);
}
}
/* Check for an associated pull down register */
if (cfg->pull_reg) {
pull_orig = __raw_readl(cfg->pull_reg);
pull_orig = omap_readl(cfg->pull_reg);
if (cfg->pull_val) {
/* Low bit = pull enabled */
......@@ -93,7 +93,7 @@ int omap_cfg_reg(const reg_cfg_t reg_cfg)
pull = pull_orig | (1 << cfg->pull_bit);
}
__raw_writel(pull, cfg->pull_reg);
omap_writel(pull, cfg->pull_reg);
}
#ifdef CONFIG_OMAP_MUX_DEBUG
......@@ -110,6 +110,7 @@ int omap_cfg_reg(const reg_cfg_t reg_cfg)
}
}
if (cfg->pull_reg)
printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
cfg->pull_name, cfg->pull_reg, pull_orig, pull);
}
......
/*
* linux/arch/arm/mach-omap/ocpi.c
*
* Minimal OCP bus support for OMAP-1610
* Minimal OCP bus support for OMAP-1610 and OMAP-5912
*
* Copyright (C) 2003 - 2004 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
......@@ -58,28 +58,40 @@ int ocpi_enable(void)
unsigned int val;
/* Make sure there's clock for OCPI */
val = __raw_readl(ARM_IDLECT3);
#ifdef CONFIG_ARCH_OMAP1610
if (cpu_is_omap1610()) {
val = omap_readl(OMAP1610_ARM_IDLECT3);
val |= EN_OCPI_CK;
val &= ~IDLOCPI_ARM;
__raw_writel(val, ARM_IDLECT3);
omap_writel(val, OMAP1610_ARM_IDLECT3);
}
#endif
#ifdef CONFIG_ARCH_OMAP5912
if (cpu_is_omap5912()) {
val = omap_readl(OMAP5912_ARM_IDLECT3);
val |= EN_OCPI_CK;
val &= ~IDLOCPI_ARM;
omap_writel(val, OMAP5912_ARM_IDLECT3);
}
#endif
/* Enable access for OHCI in OCPI */
val = __raw_readl(OCPI_PROT);
val = omap_readl(OCPI_PROT);
val &= ~0xff;
//val &= (1 << 0); /* Allow access only to EMIFS */
__raw_writel(val, OCPI_PROT);
omap_writel(val, OCPI_PROT);
val = __raw_readl(OCPI_SEC);
val = omap_readl(OCPI_SEC);
val &= ~0xff;
__raw_writel(val, OCPI_SEC);
omap_writel(val, OCPI_SEC);
val = __raw_readl(OCPI_SEC);
val = omap_readl(OCPI_SEC);
val |= 0;
__raw_writel(val, OCPI_SEC);
omap_writel(val, OCPI_SEC);
val = __raw_readl(OCPI_SINT0);
val = omap_readl(OCPI_SINT0);
val |= 0;
__raw_writel(val, OCPI_SINT1);
omap_writel(val, OCPI_SINT1);
return 0;
}
......@@ -89,8 +101,8 @@ int ocpi_status(void)
{
printk("OCPI: addr: 0x%08x cmd: 0x%08x\n"
" ohci-addr: 0x%08x ohci-status: 0x%08x\n",
__raw_readl(OCPI_FAULT), __raw_readl(OCPI_CMD_FAULT),
__raw_readl(HOSTUEADDR), __raw_readl(HOSTUESTATUS));
omap_readl(OCPI_FAULT), omap_readl(OCPI_CMD_FAULT),
omap_readl(HOSTUEADDR), omap_readl(HOSTUESTATUS));
return 1;
}
......
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