mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: (27 commits) [ARM] 3433/1: ARM: OMAP: 8/8 Update board files [ARM] 3455/1: ARM: OMAP: 7/8 Misc updates, take 2 [ARM] 3454/1: ARM: OMAP: 6/8 Update framebuffer low-level init code, take 2 [ARM] 3430/1: ARM: OMAP: 5/8 Update PM [ARM] 3429/1: ARM: OMAP: 4/8 Update GPIO [ARM] 3428/1: ARM: OMAP: 3/8 Update pin multiplexing [ARM] 3427/1: ARM: OMAP: 2/8 Update timers [ARM] 3426/1: ARM: OMAP: 1/8 Update clock framework [ARM] 3396/2: AT91RM9200 Platform devices update [ARM] 3395/2: AT91RM9200 Dataflash Card vs MMC selection [ARM] 3393/2: AT91RM9200 LED support [ARM] 3453/1: Poodle: Correctly set the memory size [ARM] 3446/1: i.MX: MMC/SD SDHC controller registration for i.MX/MX1 MX1ADS board [ARM] 3444/1: i.MX: Scatter-gather DMA emulation for i.MX/MX1 [ARM] 3451/1: ep93xx: use the m48t86 rtc driver on the ts72xx platform [ARM] 3450/1: ep93xx: use the ep93xx rtc driver [ARM] 3452/1: [S3C2410] RX3715 - add nand information [ARM] 3449/1: [S3C2410] Anubis - fix NAND timings [ARM] 3448/1: [S3C2410] Settle delay when _enabling_ USB PLL [ARM] 3442/1: [S3C2410] SMDK: NAND device setup ...
This commit is contained in:
commit
1810b6cb16
@ -379,7 +379,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_AT91_DATAFLASH=y
|
||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
|
@ -370,7 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_AT91_DATAFLASH=y
|
||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
|
@ -100,23 +100,12 @@ EXPORT_SYMBOL(__raw_writesl);
|
||||
#endif
|
||||
|
||||
/* string / mem functions */
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
EXPORT_SYMBOL(strncpy);
|
||||
EXPORT_SYMBOL(strcat);
|
||||
EXPORT_SYMBOL(strncat);
|
||||
EXPORT_SYMBOL(strcmp);
|
||||
EXPORT_SYMBOL(strncmp);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
EXPORT_SYMBOL(strlen);
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(memcmp);
|
||||
EXPORT_SYMBOL(memscan);
|
||||
EXPORT_SYMBOL(memchr);
|
||||
EXPORT_SYMBOL(__memzero);
|
||||
|
||||
@ -190,8 +179,6 @@ EXPORT_SYMBOL(_find_next_bit_be);
|
||||
|
||||
/* syscalls */
|
||||
EXPORT_SYMBOL(sys_write);
|
||||
EXPORT_SYMBOL(sys_read);
|
||||
EXPORT_SYMBOL(sys_lseek);
|
||||
EXPORT_SYMBOL(sys_open);
|
||||
EXPORT_SYMBOL(sys_exit);
|
||||
EXPORT_SYMBOL(sys_wait4);
|
||||
|
@ -252,6 +252,9 @@ static void __init dump_cpu_info(int cpu)
|
||||
dump_cache("cache", cpu, CACHE_ISIZE(info));
|
||||
}
|
||||
}
|
||||
|
||||
if (arch_is_coherent())
|
||||
printk("Cache coherency enabled\n");
|
||||
}
|
||||
|
||||
int cpu_architecture(void)
|
||||
|
@ -16,11 +16,12 @@ obj-$(CONFIG_MACH_CSB637) += board-csb637.o
|
||||
#obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
|
||||
|
||||
# LEDs support
|
||||
#led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
|
||||
#led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
|
||||
#led-$(CONFIG_MACH_CSB337) += leds.o
|
||||
#led-$(CONFIG_MACH_CSB637) += leds.o
|
||||
led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
|
||||
led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
|
||||
led-$(CONFIG_MACH_CSB337) += leds.o
|
||||
led-$(CONFIG_MACH_CSB637) += leds.o
|
||||
#led-$(CONFIG_MACH_KB9200) += leds.o
|
||||
#led-$(CONFIG_MACH_KAFA) += leds.o
|
||||
obj-$(CONFIG_LEDS) += $(led-y)
|
||||
|
||||
# VGA support
|
||||
|
@ -67,6 +67,9 @@ static void __init csb337_map_io(void)
|
||||
/* Initialize clocks: 3.6864 MHz crystal */
|
||||
at91_clock_init(3686400);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = CSB337_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
|
@ -67,6 +67,9 @@ static void __init csb637_map_io(void)
|
||||
/* Initialize clocks: 3.6864 MHz crystal */
|
||||
at91_clock_init(3686400);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = CSB637_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
|
@ -70,6 +70,9 @@ static void __init dk_map_io(void)
|
||||
/* Initialize clocks: 18.432 MHz crystal */
|
||||
at91_clock_init(18432000);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = DK_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
@ -118,9 +121,14 @@ static void __init dk_board_init(void)
|
||||
at91_add_device_udc(&dk_udc_data);
|
||||
/* Compact Flash */
|
||||
at91_add_device_cf(&dk_cf_data);
|
||||
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
|
||||
/* DataFlash card */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 0);
|
||||
#else
|
||||
/* MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
|
||||
at91_add_device_mmc(&dk_mmc_data);
|
||||
#endif
|
||||
/* VGA */
|
||||
// dk_add_device_video();
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ static void __init ek_map_io(void)
|
||||
/* Initialize clocks: 18.432 MHz crystal */
|
||||
at91_clock_init(18432000);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = EK_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
@ -111,9 +114,14 @@ static void __init ek_board_init(void)
|
||||
at91_add_device_usbh(&ek_usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&ek_udc_data);
|
||||
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
|
||||
/* DataFlash card */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 0);
|
||||
#else
|
||||
/* MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
|
||||
at91_add_device_mmc(&ek_mmc_data);
|
||||
#endif
|
||||
/* VGA */
|
||||
// ek_add_device_video();
|
||||
}
|
||||
|
@ -28,10 +28,10 @@
|
||||
static u64 ohci_dmamask = 0xffffffffUL;
|
||||
static struct at91_usbh_data usbh_data;
|
||||
|
||||
static struct resource at91rm9200_usbh_resource[] = {
|
||||
static struct resource at91_usbh_resource[] = {
|
||||
[0] = {
|
||||
.start = AT91_UHP_BASE,
|
||||
.end = AT91_UHP_BASE + SZ_1M -1,
|
||||
.end = AT91_UHP_BASE + SZ_1M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
@ -49,8 +49,8 @@ static struct platform_device at91rm9200_usbh_device = {
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
.platform_data = &usbh_data,
|
||||
},
|
||||
.resource = at91rm9200_usbh_resource,
|
||||
.num_resources = ARRAY_SIZE(at91rm9200_usbh_resource),
|
||||
.resource = at91_usbh_resource,
|
||||
.num_resources = ARRAY_SIZE(at91_usbh_resource),
|
||||
};
|
||||
|
||||
void __init at91_add_device_usbh(struct at91_usbh_data *data)
|
||||
@ -121,6 +121,19 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
|
||||
static u64 eth_dmamask = 0xffffffffUL;
|
||||
static struct at91_eth_data eth_data;
|
||||
|
||||
static struct resource at91_eth_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_BASE_EMAC,
|
||||
.end = AT91_BASE_EMAC + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = AT91_ID_EMAC,
|
||||
.end = AT91_ID_EMAC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device at91rm9200_eth_device = {
|
||||
.name = "at91_ether",
|
||||
.id = -1,
|
||||
@ -129,7 +142,8 @@ static struct platform_device at91rm9200_eth_device = {
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
.platform_data = ð_data,
|
||||
},
|
||||
.num_resources = 0,
|
||||
.resource = at91_eth_resources,
|
||||
.num_resources = ARRAY_SIZE(at91_eth_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_eth(struct at91_eth_data *data)
|
||||
@ -224,15 +238,20 @@ static u64 mmc_dmamask = 0xffffffffUL;
|
||||
static struct at91_mmc_data mmc_data;
|
||||
|
||||
static struct resource at91_mmc_resources[] = {
|
||||
{
|
||||
[0] = {
|
||||
.start = AT91_BASE_MCI,
|
||||
.end = AT91_BASE_MCI + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.start = AT91_ID_MCI,
|
||||
.end = AT91_ID_MCI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device at91rm9200_mmc_device = {
|
||||
.name = "at91rm9200_mci",
|
||||
.name = "at91_mci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &mmc_dmamask,
|
||||
@ -290,4 +309,123 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
|
||||
void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* NAND / SmartMedia
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
|
||||
static struct at91_nand_data nand_data;
|
||||
|
||||
static struct resource at91_nand_resources[] = {
|
||||
{
|
||||
.start = AT91_SMARTMEDIA_BASE,
|
||||
.end = AT91_SMARTMEDIA_BASE + SZ_8M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device at91_nand_device = {
|
||||
.name = "at91_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.resource = at91_nand_resources,
|
||||
.num_resources = ARRAY_SIZE(at91_nand_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_nand(struct at91_nand_data *data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
/* enable pin */
|
||||
if (data->enable_pin)
|
||||
at91_set_gpio_output(data->enable_pin, 1);
|
||||
|
||||
/* ready/busy pin */
|
||||
if (data->rdy_pin)
|
||||
at91_set_gpio_input(data->rdy_pin, 1);
|
||||
|
||||
/* card detect pin */
|
||||
if (data->det_pin)
|
||||
at91_set_gpio_input(data->det_pin, 1);
|
||||
|
||||
at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */
|
||||
at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */
|
||||
|
||||
nand_data = *data;
|
||||
platform_device_register(&at91_nand_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_nand(struct at91_nand_data *data) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* TWI (i2c)
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
|
||||
static struct platform_device at91rm9200_twi_device = {
|
||||
.name = "at91_i2c",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
void __init at91_add_device_i2c(void)
|
||||
{
|
||||
/* pins used for TWI interface */
|
||||
at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
|
||||
at91_set_multi_drive(AT91_PIN_PA25, 1);
|
||||
|
||||
at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
|
||||
at91_set_multi_drive(AT91_PIN_PA26, 1);
|
||||
|
||||
platform_device_register(&at91rm9200_twi_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_i2c(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* RTC
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE)
|
||||
static struct platform_device at91rm9200_rtc_device = {
|
||||
.name = "at91_rtc",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
void __init at91_add_device_rtc(void)
|
||||
{
|
||||
platform_device_register(&at91rm9200_rtc_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_rtc(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* LEDs
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_LEDS)
|
||||
u8 at91_leds_cpu;
|
||||
u8 at91_leds_timer;
|
||||
|
||||
void __init at91_init_leds(u8 cpu_led, u8 timer_led)
|
||||
{
|
||||
at91_leds_cpu = cpu_led;
|
||||
at91_leds_timer = timer_led;
|
||||
}
|
||||
|
||||
#else
|
||||
void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
100
arch/arm/mach-at91rm9200/leds.c
Normal file
100
arch/arm/mach-at91rm9200/leds.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* LED driver for Atmel AT91-based boards.
|
||||
*
|
||||
* Copyright (C) SAN People (Pty) Ltd
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/leds.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
|
||||
static inline void at91_led_on(unsigned int led)
|
||||
{
|
||||
at91_set_gpio_value(led, 0);
|
||||
}
|
||||
|
||||
static inline void at91_led_off(unsigned int led)
|
||||
{
|
||||
at91_set_gpio_value(led, 1);
|
||||
}
|
||||
|
||||
static inline void at91_led_toggle(unsigned int led)
|
||||
{
|
||||
unsigned long is_off = at91_get_gpio_value(led);
|
||||
if (is_off)
|
||||
at91_led_on(led);
|
||||
else
|
||||
at91_led_off(led);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle LED events.
|
||||
*/
|
||||
static void at91_leds_event(led_event_t evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
switch(evt) {
|
||||
case led_start: /* System startup */
|
||||
at91_led_on(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
case led_stop: /* System stop / suspend */
|
||||
at91_led_off(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_LEDS_TIMER
|
||||
case led_timer: /* Every 50 timer ticks */
|
||||
at91_led_toggle(at91_leds_timer);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LEDS_CPU
|
||||
case led_idle_start: /* Entering idle state */
|
||||
at91_led_off(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
case led_idle_end: /* Exit idle state */
|
||||
at91_led_on(at91_leds_cpu);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
||||
static int __init leds_init(void)
|
||||
{
|
||||
if (!at91_leds_timer || !at91_leds_cpu)
|
||||
return -ENODEV;
|
||||
|
||||
/* Enable PIO to access the LEDs */
|
||||
at91_set_gpio_output(at91_leds_timer, 1);
|
||||
at91_set_gpio_output(at91_leds_cpu, 1);
|
||||
|
||||
leds_event = at91_leds_event;
|
||||
|
||||
leds_event(led_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(leds_init);
|
@ -424,6 +424,14 @@ static struct amba_device uart3_device = {
|
||||
.periphid = 0x00041010,
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device ep93xx_rtc_device = {
|
||||
.name = "ep93xx-rtc",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
|
||||
void __init ep93xx_init_devices(void)
|
||||
{
|
||||
unsigned int v;
|
||||
@ -439,4 +447,6 @@ void __init ep93xx_init_devices(void)
|
||||
amba_device_register(&uart1_device, &iomem_resource);
|
||||
amba_device_register(&uart2_device, &iomem_resource);
|
||||
amba_device_register(&uart3_device, &iomem_resource);
|
||||
|
||||
platform_device_register(&ep93xx_rtc_device);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/m48t86.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -39,6 +41,16 @@ static struct map_desc ts72xx_io_desc[] __initdata = {
|
||||
.pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
|
||||
.length = TS72XX_OPTIONS2_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = TS72XX_RTC_INDEX_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
|
||||
.length = TS72XX_RTC_INDEX_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = TS72XX_RTC_DATA_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
|
||||
.length = TS72XX_RTC_DATA_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}
|
||||
};
|
||||
|
||||
@ -99,11 +111,38 @@ static void __init ts72xx_map_io(void)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char ts72xx_rtc_readb(unsigned long addr)
|
||||
{
|
||||
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
|
||||
return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
|
||||
}
|
||||
|
||||
static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr)
|
||||
{
|
||||
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
|
||||
__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
|
||||
}
|
||||
|
||||
static struct m48t86_ops ts72xx_rtc_ops = {
|
||||
.readb = ts72xx_rtc_readb,
|
||||
.writeb = ts72xx_rtc_writeb,
|
||||
};
|
||||
|
||||
static struct platform_device ts72xx_rtc_device = {
|
||||
.name = "rtc-m48t86",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts72xx_rtc_ops,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
static void __init ts72xx_init_machine(void)
|
||||
{
|
||||
ep93xx_init_devices();
|
||||
if (board_is_ts7200())
|
||||
physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
|
||||
platform_device_register(&ts72xx_rtc_device);
|
||||
}
|
||||
|
||||
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
|
||||
|
@ -7,11 +7,18 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
|
||||
* 2004-03-03 Sascha Hauer <sascha@saschahauer.de>
|
||||
* initial version heavily inspired by
|
||||
* linux/arch/arm/mach-pxa/dma.c
|
||||
*
|
||||
* 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
* Changed to support scatter gather DMA
|
||||
* by taking Russell's code from RiscPC
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -22,69 +29,368 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/arch/imx-dma.h>
|
||||
|
||||
static struct dma_channel {
|
||||
char *name;
|
||||
void (*irq_handler) (int, void *, struct pt_regs *);
|
||||
void (*err_handler) (int, void *, struct pt_regs *);
|
||||
void *data;
|
||||
} dma_channels[11];
|
||||
struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
|
||||
|
||||
/* set err_handler to NULL to have the standard info-only error handler */
|
||||
int
|
||||
imx_request_dma(char *name, imx_dma_prio prio,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *), void *data)
|
||||
/*
|
||||
* imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @lastcount: number of bytes transferred during last transfer
|
||||
*
|
||||
* Functions prepares DMA controller for next sg data chunk transfer.
|
||||
* The @lastcount argument informs function about number of bytes transferred
|
||||
* during last block. Zero value can be used for @lastcount to setup DMA
|
||||
* for the first chunk.
|
||||
*/
|
||||
static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i, found = 0;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned int nextcount;
|
||||
unsigned int nextaddr;
|
||||
|
||||
/* basic sanity checks */
|
||||
if (!name || !irq_handler)
|
||||
return -EINVAL;
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
imxdma->resbytes -= lastcount;
|
||||
|
||||
/* try grabbing a DMA channel with the requested priority */
|
||||
for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) {
|
||||
if (!dma_channels[i].name) {
|
||||
found = 1;
|
||||
break;
|
||||
if (!imxdma->sg) {
|
||||
pr_debug("imxdma%d: no sg data\n", dma_ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
imxdma->sgbc += lastcount;
|
||||
if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) {
|
||||
if ((imxdma->sgcount <= 1) || !imxdma->resbytes) {
|
||||
pr_debug("imxdma%d: sg transfer limit reached\n",
|
||||
dma_ch);
|
||||
imxdma->sgcount=0;
|
||||
imxdma->sg = NULL;
|
||||
return 0;
|
||||
} else {
|
||||
imxdma->sgcount--;
|
||||
imxdma->sg++;
|
||||
imxdma->sgbc = 0;
|
||||
}
|
||||
}
|
||||
nextcount = imxdma->sg->length - imxdma->sgbc;
|
||||
nextaddr = imxdma->sg->dma_address + imxdma->sgbc;
|
||||
|
||||
if (!found) {
|
||||
/* requested prio group is full, try hier priorities */
|
||||
for (i = prio - 1; i >= 0; i--) {
|
||||
if (!dma_channels[i].name) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(imxdma->resbytes < nextcount)
|
||||
nextcount = imxdma->resbytes;
|
||||
|
||||
if (found) {
|
||||
DIMR &= ~(1 << i);
|
||||
dma_channels[i].name = name;
|
||||
dma_channels[i].irq_handler = irq_handler;
|
||||
dma_channels[i].err_handler = err_handler;
|
||||
dma_channels[i].data = data;
|
||||
} else {
|
||||
printk(KERN_WARNING "No more available DMA channels for %s\n",
|
||||
name);
|
||||
i = -ENODEV;
|
||||
}
|
||||
if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
|
||||
DAR(dma_ch) = nextaddr;
|
||||
else
|
||||
SAR(dma_ch) = nextaddr;
|
||||
|
||||
local_irq_restore(flags);
|
||||
return i;
|
||||
CNTR(dma_ch) = nextcount;
|
||||
pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n",
|
||||
dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch));
|
||||
|
||||
return nextcount;
|
||||
}
|
||||
|
||||
void
|
||||
imx_free_dma(int dma_ch)
|
||||
/*
|
||||
* imx_dma_setup_sg_base - scatter-gather DMA emulation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @sg: pointer to the scatter-gather list/vector
|
||||
* @sgcount: scatter-gather list hungs count
|
||||
*
|
||||
* Functions sets up i.MX DMA state for emulated scatter-gather transfer
|
||||
* and sets up channel registers to be ready for the first chunk
|
||||
*/
|
||||
static int
|
||||
imx_dma_setup_sg_base(imx_dmach_t dma_ch,
|
||||
struct scatterlist *sg, unsigned int sgcount)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = sg;
|
||||
imxdma->sgcount = sgcount;
|
||||
imxdma->sgbc = 0;
|
||||
return imx_dma_sg_next(dma_ch, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @dma_address: the DMA/physical memory address of the linear data block
|
||||
* to transfer
|
||||
* @dma_length: length of the data block in bytes
|
||||
* @dev_addr: physical device port address
|
||||
* @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
|
||||
* or %DMA_MODE_WRITE from memory to the device
|
||||
*
|
||||
* The function setups DMA channel source and destination addresses for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is disabled,
|
||||
* because linear data block
|
||||
* form the physical address range is transfered.
|
||||
* Return value: if incorrect parameters are provided -%EINVAL.
|
||||
* Zero indicates success.
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
|
||||
unsigned int dma_length, unsigned int dev_addr,
|
||||
dmamode_t dmamode)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = NULL;
|
||||
imxdma->sgcount = 0;
|
||||
imxdma->dma_mode = dmamode;
|
||||
imxdma->resbytes = dma_length;
|
||||
|
||||
if (!dma_address) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dma_length) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n",
|
||||
dma_ch, (unsigned int)dma_address, dma_length,
|
||||
dev_addr);
|
||||
SAR(dma_ch) = dev_addr;
|
||||
DAR(dma_ch) = (unsigned int)dma_address;
|
||||
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n",
|
||||
dma_ch, (unsigned int)dma_address, dma_length,
|
||||
dev_addr);
|
||||
SAR(dma_ch) = (unsigned int)dma_address;
|
||||
DAR(dma_ch) = dev_addr;
|
||||
} else {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CNTR(dma_ch) = dma_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @sg: pointer to the scatter-gather list/vector
|
||||
* @sgcount: scatter-gather list hungs count
|
||||
* @dma_length: total length of the transfer request in bytes
|
||||
* @dev_addr: physical device port address
|
||||
* @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
|
||||
* or %DMA_MODE_WRITE from memory to the device
|
||||
*
|
||||
* The function setups DMA channel state and registers to be ready for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is set up
|
||||
* according to the parameters.
|
||||
*
|
||||
* The full preparation of the transfer requires setup of more register
|
||||
* by the caller before imx_dma_enable() can be called.
|
||||
*
|
||||
* %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes
|
||||
*
|
||||
* %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx
|
||||
*
|
||||
* %CCR(dma_ch) has to specify transfer parameters, the next settings is typical
|
||||
* for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified
|
||||
*
|
||||
* %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
|
||||
*
|
||||
* The typical setup for %DMA_MODE_WRITE is specified by next options combination
|
||||
*
|
||||
* %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
|
||||
*
|
||||
* Be carefull there and do not mistakenly mix source and target device
|
||||
* port sizes constants, they are really different:
|
||||
* %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
|
||||
* %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
|
||||
*
|
||||
* Return value: if incorrect parameters are provided -%EINVAL.
|
||||
* Zero indicates success.
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_sg(imx_dmach_t dma_ch,
|
||||
struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
|
||||
unsigned int dev_addr, dmamode_t dmamode)
|
||||
{
|
||||
int res;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = NULL;
|
||||
imxdma->sgcount = 0;
|
||||
imxdma->dma_mode = dmamode;
|
||||
imxdma->resbytes = dma_length;
|
||||
|
||||
if (!sg || !sgcount) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sg->length) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n",
|
||||
dma_ch, sg, sgcount, dma_length, dev_addr);
|
||||
SAR(dma_ch) = dev_addr;
|
||||
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n",
|
||||
dma_ch, sg, sgcount, dma_length, dev_addr);
|
||||
DAR(dma_ch) = dev_addr;
|
||||
} else {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = imx_dma_setup_sg_base(dma_ch, sg, sgcount);
|
||||
if (res <= 0) {
|
||||
printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @irq_handler: the pointer to the function called if the transfer
|
||||
* ends successfully
|
||||
* @err_handler: the pointer to the function called if the premature
|
||||
* end caused by error occurs
|
||||
* @data: user specified value to be passed to the handlers
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_handlers(imx_dmach_t dma_ch,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *),
|
||||
void *data)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DISR = (1 << dma_ch);
|
||||
imxdma->irq_handler = irq_handler;
|
||||
imxdma->err_handler = err_handler;
|
||||
imxdma->data = data;
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_enable - function to start i.MX DMA channel operation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*
|
||||
* The channel has to be allocated by driver through imx_dma_request()
|
||||
* or imx_dma_request_by_prio() function.
|
||||
* The transfer parameters has to be set to the channel registers through
|
||||
* call of the imx_dma_setup_single() or imx_dma_setup_sg() function
|
||||
* and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to
|
||||
* be set prior this function call by the channel user.
|
||||
*/
|
||||
void imx_dma_enable(imx_dmach_t dma_ch)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("imxdma%d: imx_dma_enable\n", dma_ch);
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DISR = (1 << dma_ch);
|
||||
DIMR &= ~(1 << dma_ch);
|
||||
CCR(dma_ch) |= CCR_CEN;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_disable - stop, finish i.MX DMA channel operatin
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*/
|
||||
void imx_dma_disable(imx_dmach_t dma_ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!dma_channels[dma_ch].name) {
|
||||
pr_debug("imxdma%d: imx_dma_disable\n", dma_ch);
|
||||
|
||||
local_irq_save(flags);
|
||||
DIMR |= (1 << dma_ch);
|
||||
CCR(dma_ch) &= ~CCR_CEN;
|
||||
DISR = (1 << dma_ch);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_request - request/allocate specified channel number
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @name: the driver/caller own non-%NULL identification
|
||||
*/
|
||||
int imx_dma_request(imx_dmach_t dma_ch, const char *name)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
/* basic sanity checks */
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
|
||||
if (dma_ch >= IMX_DMA_CHANNELS) {
|
||||
printk(KERN_CRIT "%s: called for non-existed channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
if (imxdma->name) {
|
||||
local_irq_restore(flags);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
imxdma->name = name;
|
||||
imxdma->irq_handler = NULL;
|
||||
imxdma->err_handler = NULL;
|
||||
imxdma->data = NULL;
|
||||
imxdma->sg = NULL;
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_free - release previously acquired channel
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*/
|
||||
void imx_dma_free(imx_dmach_t dma_ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT
|
||||
"%s: trying to free channel %d which is already freed\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
@ -92,27 +398,84 @@ imx_free_dma(int dma_ch)
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DIMR &= ~(1 << dma_ch);
|
||||
dma_channels[dma_ch].name = NULL;
|
||||
/* Disable interrupts */
|
||||
DIMR |= (1 << dma_ch);
|
||||
CCR(dma_ch) &= ~CCR_CEN;
|
||||
imxdma->name = NULL;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
/**
|
||||
* imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @name: the driver/caller own non-%NULL identification
|
||||
* @prio: one of the hardware distinguished priority level:
|
||||
* %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW
|
||||
*
|
||||
* This function tries to find free channel in the specified priority group
|
||||
* if the priority cannot be achieved it tries to look for free channel
|
||||
* in the higher and then even lower priority groups.
|
||||
*
|
||||
* Return value: If there is no free channel to allocate, -%ENODEV is returned.
|
||||
* Zero value indicates successful channel allocation.
|
||||
*/
|
||||
int
|
||||
imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
|
||||
imx_dma_prio prio)
|
||||
{
|
||||
int i;
|
||||
int best;
|
||||
|
||||
switch (prio) {
|
||||
case (DMA_PRIO_HIGH):
|
||||
best = 8;
|
||||
break;
|
||||
case (DMA_PRIO_MEDIUM):
|
||||
best = 4;
|
||||
break;
|
||||
case (DMA_PRIO_LOW):
|
||||
default:
|
||||
best = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = best; i < IMX_DMA_CHANNELS; i++) {
|
||||
if (!imx_dma_request(i, name)) {
|
||||
*pdma_ch = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = best - 1; i >= 0; i--) {
|
||||
if (!imx_dma_request(i, name)) {
|
||||
*pdma_ch = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int i, disr = DISR;
|
||||
struct dma_channel *channel;
|
||||
struct imx_dma_channel *channel;
|
||||
unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
|
||||
|
||||
DISR = disr;
|
||||
for (i = 0; i < 11; i++) {
|
||||
channel = &dma_channels[i];
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
channel = &imx_dma_channels[i];
|
||||
|
||||
if ( (err_mask & 1<<i) && channel->name && channel->err_handler) {
|
||||
if ((err_mask & 1 << i) && channel->name
|
||||
&& channel->err_handler) {
|
||||
channel->err_handler(i, channel->data, regs);
|
||||
continue;
|
||||
}
|
||||
|
||||
imx_dma_channels[i].sg = NULL;
|
||||
|
||||
if (DBTOSR & (1 << i)) {
|
||||
printk(KERN_WARNING
|
||||
"Burst timeout on channel %d (%s)\n",
|
||||
@ -141,17 +504,27 @@ dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int i, disr = DISR;
|
||||
|
||||
pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
|
||||
disr);
|
||||
|
||||
DISR = disr;
|
||||
for (i = 0; i < 11; i++) {
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
if (disr & (1 << i)) {
|
||||
struct dma_channel *channel = &dma_channels[i];
|
||||
if (channel->name && channel->irq_handler) {
|
||||
channel->irq_handler(i, channel->data, regs);
|
||||
struct imx_dma_channel *channel = &imx_dma_channels[i];
|
||||
if (channel->name) {
|
||||
if (imx_dma_sg_next(i, CNTR(i))) {
|
||||
CCR(i) &= ~CCR_CEN;
|
||||
mb();
|
||||
CCR(i) |= CCR_CEN;
|
||||
} else {
|
||||
if (channel->irq_handler)
|
||||
channel->irq_handler(i,
|
||||
channel->data, regs);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* IRQ for an unregistered DMA channel:
|
||||
@ -165,10 +538,10 @@ dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init
|
||||
imx_dma_init(void)
|
||||
static int __init imx_dma_init(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* reset DMA module */
|
||||
DCR = DCR_DRST;
|
||||
@ -189,15 +562,27 @@ imx_dma_init(void)
|
||||
DCR = DCR_DEN;
|
||||
|
||||
/* clear all interrupts */
|
||||
DISR = 0x3ff;
|
||||
DISR = (1 << IMX_DMA_CHANNELS) - 1;
|
||||
|
||||
/* enable interrupts */
|
||||
DIMR = 0;
|
||||
DIMR = (1 << IMX_DMA_CHANNELS) - 1;
|
||||
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
imx_dma_channels[i].sg = NULL;
|
||||
imx_dma_channels[i].dma_num = i;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_initcall(imx_dma_init);
|
||||
|
||||
EXPORT_SYMBOL(imx_request_dma);
|
||||
EXPORT_SYMBOL(imx_free_dma);
|
||||
EXPORT_SYMBOL(imx_dma_setup_single);
|
||||
EXPORT_SYMBOL(imx_dma_setup_sg);
|
||||
EXPORT_SYMBOL(imx_dma_setup_handlers);
|
||||
EXPORT_SYMBOL(imx_dma_enable);
|
||||
EXPORT_SYMBOL(imx_dma_disable);
|
||||
EXPORT_SYMBOL(imx_dma_request);
|
||||
EXPORT_SYMBOL(imx_dma_free);
|
||||
EXPORT_SYMBOL(imx_dma_request_by_prio);
|
||||
EXPORT_SYMBOL(imx_dma_channels);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "generic.h"
|
||||
|
||||
@ -51,11 +52,28 @@ static struct platform_device *devices[] __initdata = {
|
||||
&cs89x0_device,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MMC_IMX
|
||||
static int mx1ads_mmc_card_present(void)
|
||||
{
|
||||
/* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
|
||||
return (SSR(1) & (1 << 20) ? 0 : 1);
|
||||
}
|
||||
|
||||
static struct imxmmc_platform_data mx1ads_mmc_info = {
|
||||
.card_present = mx1ads_mmc_card_present,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init
|
||||
mx1ads_init(void)
|
||||
{
|
||||
#ifdef CONFIG_LEDS
|
||||
imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
|
||||
#endif
|
||||
#ifdef CONFIG_MMC_IMX
|
||||
/* SD/MMC card detect */
|
||||
imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
|
||||
imx_set_mmc_info(&mx1ads_mmc_info);
|
||||
#endif
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
@ -44,6 +44,15 @@
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
static int __init espresso_pci_init(void)
|
||||
{
|
||||
if (machine_is_espresso())
|
||||
ixp23xx_pci_slave_init();
|
||||
|
||||
return 0;
|
||||
};
|
||||
subsys_initcall(espresso_pci_init);
|
||||
|
||||
static void __init espresso_init(void)
|
||||
{
|
||||
physmap_configure(0x90000000, 0x02000000, 2, NULL);
|
||||
|
@ -201,7 +201,7 @@ int clear_master_aborts(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init ixp23xx_pci_preinit(void)
|
||||
static void __init ixp23xx_pci_common_init(void)
|
||||
{
|
||||
#ifdef __ARMEB__
|
||||
*IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */
|
||||
@ -219,7 +219,18 @@ void __init ixp23xx_pci_preinit(void)
|
||||
*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
|
||||
} else {
|
||||
*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
|
||||
|
||||
/*
|
||||
* Enable coherency on A2 silicon.
|
||||
*/
|
||||
if (arch_is_coherent())
|
||||
*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void __init ixp23xx_pci_preinit(void)
|
||||
{
|
||||
ixp23xx_pci_common_init();
|
||||
|
||||
hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
|
||||
"PCI config cycle to non-existent device");
|
||||
@ -273,3 +284,8 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ixp23xx_pci_slave_init(void)
|
||||
{
|
||||
ixp23xx_pci_common_init();
|
||||
}
|
||||
|
@ -69,12 +69,6 @@ config MACH_VOICEBLUE
|
||||
Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
|
||||
such a board.
|
||||
|
||||
config MACH_NETSTAR
|
||||
bool "NetStar"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for NetStar PBX. Say Y here if you have such a board.
|
||||
|
||||
config MACH_OMAP_PALMTE
|
||||
bool "Palm Tungsten E"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
@ -85,6 +79,20 @@ config MACH_OMAP_PALMTE
|
||||
informations.
|
||||
Say Y here if you have such a PDA, say NO otherwise.
|
||||
|
||||
config MACH_NOKIA770
|
||||
bool "Nokia 770"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP16XX
|
||||
help
|
||||
Support for the Nokia 770 Internet Tablet. Say Y here if you
|
||||
have such a device.
|
||||
|
||||
config MACH_AMS_DELTA
|
||||
bool "Amstrad E3 (Delta)"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for the Amstrad E3 (codename Delta) videophone. Say Y here
|
||||
if you have such a device.
|
||||
|
||||
config MACH_OMAP_GENERIC
|
||||
bool "Generic OMAP board"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
|
||||
|
@ -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
|
||||
|
116
arch/arm/mach-omap1/board-ams-delta.c
Normal file
116
arch/arm/mach-omap1/board-ams-delta.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/board-ams-delta.c
|
||||
*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* Board specific inits for the Amstrad E3 (codename Delta) videophone
|
||||
*
|
||||
* Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
|
||||
*
|
||||
* 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/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/board-ams-delta.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static u8 ams_delta_latch1_reg;
|
||||
static u16 ams_delta_latch2_reg;
|
||||
|
||||
void ams_delta_latch1_write(u8 mask, u8 value)
|
||||
{
|
||||
ams_delta_latch1_reg &= ~mask;
|
||||
ams_delta_latch1_reg |= value;
|
||||
*(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
|
||||
}
|
||||
|
||||
void ams_delta_latch2_write(u16 mask, u16 value)
|
||||
{
|
||||
ams_delta_latch2_reg &= ~mask;
|
||||
ams_delta_latch2_reg |= value;
|
||||
*(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
|
||||
}
|
||||
|
||||
static void __init ams_delta_init_irq(void)
|
||||
{
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
}
|
||||
|
||||
static struct map_desc ams_delta_io_desc[] __initdata = {
|
||||
// AMS_DELTA_LATCH1
|
||||
{
|
||||
.virtual = AMS_DELTA_LATCH1_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
// AMS_DELTA_LATCH2
|
||||
{
|
||||
.virtual = AMS_DELTA_LATCH2_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
// AMS_DELTA_MODEM
|
||||
{
|
||||
.virtual = AMS_DELTA_MODEM_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
static struct omap_uart_config ams_delta_uart_config __initdata = {
|
||||
.enabled_uarts = 1,
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel ams_delta_config[] = {
|
||||
{ OMAP_TAG_UART, &ams_delta_uart_config },
|
||||
};
|
||||
|
||||
static void __init ams_delta_init(void)
|
||||
{
|
||||
iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
|
||||
|
||||
omap_board_config = ams_delta_config;
|
||||
omap_board_config_size = ARRAY_SIZE(ams_delta_config);
|
||||
omap_serial_init();
|
||||
|
||||
/* Clear latch2 (NAND, LCD, modem enable) */
|
||||
ams_delta_latch2_write(~0, 0);
|
||||
}
|
||||
|
||||
static void __init ams_delta_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
|
||||
/* Maintainer: Jonathan McDowell <noodles@earth.li> */
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = ams_delta_map_io,
|
||||
.init_irq = ams_delta_init_irq,
|
||||
.init_machine = ams_delta_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
||||
|
||||
EXPORT_SYMBOL(ams_delta_latch1_write);
|
||||
EXPORT_SYMBOL(ams_delta_latch2_write);
|
@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = {
|
||||
static void __init omap_generic_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
generic_config[0].data = &generic1510_usb_config;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,7 +24,9 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -35,12 +37,55 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/mcbsp.h>
|
||||
#include <asm/arch/omap-alsa.h>
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct mtd_partition h2_partitions[] = {
|
||||
static int h2_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_3),
|
||||
KEY(0, 3, KEY_F10),
|
||||
KEY(0, 4, KEY_F5),
|
||||
KEY(0, 5, KEY_9),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_2),
|
||||
KEY(1, 3, KEY_F9),
|
||||
KEY(1, 4, KEY_F7),
|
||||
KEY(1, 5, KEY_0),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_6),
|
||||
KEY(2, 2, KEY_1),
|
||||
KEY(2, 3, KEY_F2),
|
||||
KEY(2, 4, KEY_F6),
|
||||
KEY(2, 5, KEY_HOME),
|
||||
KEY(3, 0, KEY_8),
|
||||
KEY(3, 1, KEY_5),
|
||||
KEY(3, 2, KEY_F12),
|
||||
KEY(3, 3, KEY_F3),
|
||||
KEY(3, 4, KEY_F8),
|
||||
KEY(3, 5, KEY_END),
|
||||
KEY(4, 0, KEY_7),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_F11),
|
||||
KEY(4, 3, KEY_F1),
|
||||
KEY(4, 4, KEY_F4),
|
||||
KEY(4, 5, KEY_ESC),
|
||||
KEY(5, 0, KEY_F13),
|
||||
KEY(5, 1, KEY_F14),
|
||||
KEY(5, 2, KEY_F15),
|
||||
KEY(5, 3, KEY_F16),
|
||||
KEY(5, 4, KEY_SLEEP),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition h2_nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -71,26 +116,26 @@ static struct mtd_partition h2_partitions[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct flash_platform_data h2_flash_data = {
|
||||
static struct flash_platform_data h2_nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = h2_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h2_partitions),
|
||||
.parts = h2_nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h2_nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource h2_flash_resource = {
|
||||
static struct resource h2_nor_resource = {
|
||||
/* This is on CS3, wherever it's mapped */
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device h2_flash_device = {
|
||||
static struct platform_device h2_nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h2_flash_data,
|
||||
.platform_data = &h2_nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &h2_flash_resource,
|
||||
.resource = &h2_nor_resource,
|
||||
};
|
||||
|
||||
static struct resource h2_smc91x_resources[] = {
|
||||
@ -113,9 +158,119 @@ static struct platform_device h2_smc91x_device = {
|
||||
.resource = h2_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct resource h2_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h2_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = h2_keymap,
|
||||
.rep = 1,
|
||||
};
|
||||
|
||||
static struct platform_device h2_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h2_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h2_kp_resources),
|
||||
.resource = h2_kp_resources,
|
||||
};
|
||||
|
||||
#define H2_IRDA_FIRSEL_GPIO_PIN 17
|
||||
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
static int h2_transceiver_mode(struct device *dev, int state)
|
||||
{
|
||||
if (state & IR_SIRMODE)
|
||||
omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0);
|
||||
else /* MIR/FIR */
|
||||
omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct omap_irda_config h2_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.rx_channel = OMAP_DMA_UART3_RX,
|
||||
.tx_channel = OMAP_DMA_UART3_TX,
|
||||
.dest_start = UART3_THR,
|
||||
.src_start = UART3_RHR,
|
||||
.tx_trigger = 0,
|
||||
.rx_trigger = 0,
|
||||
};
|
||||
|
||||
static struct resource h2_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_UART3,
|
||||
.end = INT_UART3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
static struct platform_device h2_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h2_irda_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h2_irda_resources),
|
||||
.resource = h2_irda_resources,
|
||||
};
|
||||
|
||||
static struct platform_device h2_lcd_device = {
|
||||
.name = "lcd_h2",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct omap_mcbsp_reg_cfg mcbsp_regs = {
|
||||
.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
|
||||
.spcr1 = RINTM(3) | RRST,
|
||||
.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
|
||||
.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
|
||||
.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.srgr1 = FWID(15),
|
||||
.srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
|
||||
|
||||
.pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
|
||||
//.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
|
||||
};
|
||||
|
||||
static struct omap_alsa_codec_config alsa_config = {
|
||||
.name = "H2 TSC2101",
|
||||
.mcbsp_regs_alsa = &mcbsp_regs,
|
||||
.codec_configure_dev = NULL, // tsc2101_configure,
|
||||
.codec_set_samplerate = NULL, // tsc2101_set_samplerate,
|
||||
.codec_clock_setup = NULL, // tsc2101_clock_setup,
|
||||
.codec_clock_on = NULL, // tsc2101_clock_on,
|
||||
.codec_clock_off = NULL, // tsc2101_clock_off,
|
||||
.get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
|
||||
};
|
||||
|
||||
static struct platform_device h2_mcbsp1_device = {
|
||||
.name = "omap_alsa_mcbsp",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &alsa_config,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *h2_devices[] __initdata = {
|
||||
&h2_flash_device,
|
||||
&h2_nor_device,
|
||||
&h2_smc91x_device,
|
||||
&h2_irda_device,
|
||||
&h2_kp_device,
|
||||
&h2_lcd_device,
|
||||
&h2_mcbsp1_device,
|
||||
};
|
||||
|
||||
static void __init h2_init_smc91x(void)
|
||||
@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h2_lcd_config __initdata = {
|
||||
.panel_name = "h2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -177,16 +331,34 @@ static struct omap_board_config_kernel h2_config[] = {
|
||||
|
||||
static void __init h2_init(void)
|
||||
{
|
||||
/* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
|
||||
* and NAND (either 16bit or 8bit) on CS3.
|
||||
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
|
||||
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
|
||||
* notice whether a NAND chip is enabled at probe time.
|
||||
*
|
||||
* FIXME revC boards (and H3) support NAND-boot, with a dip switch to
|
||||
* put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
|
||||
* detecting that in code here, to avoid probing every possible flash
|
||||
* configuration...
|
||||
*/
|
||||
h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
|
||||
h2_flash_resource.end += SZ_32M - 1;
|
||||
h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
|
||||
h2_nor_resource.end += SZ_32M - 1;
|
||||
|
||||
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
|
||||
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
|
||||
|
||||
/* MMC: card detect and WP */
|
||||
// omap_cfg_reg(U19_ARMIO1); /* CD */
|
||||
omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
|
||||
|
||||
/* Irda */
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
|
||||
if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) {
|
||||
omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0);
|
||||
h2_irda_data.transceiver_mode = h2_transceiver_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
|
||||
omap_board_config = h2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h2_config);
|
||||
|
@ -21,8 +21,11 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/page.h>
|
||||
@ -33,15 +36,59 @@
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/gpioexpander.h>
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct mtd_partition h3_partitions[] = {
|
||||
static int h3_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_3),
|
||||
KEY(0, 3, KEY_F10),
|
||||
KEY(0, 4, KEY_F5),
|
||||
KEY(0, 5, KEY_9),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_2),
|
||||
KEY(1, 3, KEY_F9),
|
||||
KEY(1, 4, KEY_F7),
|
||||
KEY(1, 5, KEY_0),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_6),
|
||||
KEY(2, 2, KEY_1),
|
||||
KEY(2, 3, KEY_F2),
|
||||
KEY(2, 4, KEY_F6),
|
||||
KEY(2, 5, KEY_HOME),
|
||||
KEY(3, 0, KEY_8),
|
||||
KEY(3, 1, KEY_5),
|
||||
KEY(3, 2, KEY_F12),
|
||||
KEY(3, 3, KEY_F3),
|
||||
KEY(3, 4, KEY_F8),
|
||||
KEY(3, 5, KEY_END),
|
||||
KEY(4, 0, KEY_7),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_F11),
|
||||
KEY(4, 3, KEY_F1),
|
||||
KEY(4, 4, KEY_F4),
|
||||
KEY(4, 5, KEY_ESC),
|
||||
KEY(5, 0, KEY_F13),
|
||||
KEY(5, 1, KEY_F14),
|
||||
KEY(5, 2, KEY_F15),
|
||||
KEY(5, 3, KEY_F16),
|
||||
KEY(5, 4, KEY_SLEEP),
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static struct mtd_partition nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -72,26 +119,80 @@ static struct mtd_partition h3_partitions[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct flash_platform_data h3_flash_data = {
|
||||
static struct flash_platform_data nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = h3_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h3_partitions),
|
||||
.parts = nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource h3_flash_resource = {
|
||||
static struct resource nor_resource = {
|
||||
/* This is on CS3, wherever it's mapped */
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device flash_device = {
|
||||
static struct platform_device nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h3_flash_data,
|
||||
.platform_data = &nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &h3_flash_resource,
|
||||
.resource = &nor_resource,
|
||||
};
|
||||
|
||||
static struct mtd_partition nand_partitions[] = {
|
||||
#if 0
|
||||
/* REVISIT: enable these partitions if you make NAND BOOT work */
|
||||
{
|
||||
.name = "xloader",
|
||||
.offset = 0,
|
||||
.size = 64 * 1024,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
{
|
||||
.name = "bootloader",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 256 * 1024,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
{
|
||||
.name = "params",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 192 * 1024,
|
||||
},
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 2 * SZ_1M,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "filesystem",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
},
|
||||
};
|
||||
|
||||
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
|
||||
static struct nand_platform_data nand_data = {
|
||||
.options = NAND_SAMSUNG_LP_OPTIONS,
|
||||
.parts = nand_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nand_partitions),
|
||||
};
|
||||
|
||||
static struct resource nand_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device nand_device = {
|
||||
.name = "omapnand",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &nand_resource,
|
||||
};
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
@ -138,10 +239,136 @@ static struct platform_device intlat_device = {
|
||||
.resource = intlat_resources,
|
||||
};
|
||||
|
||||
static struct resource h3_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h3_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = h3_keymap,
|
||||
.rep = 1,
|
||||
};
|
||||
|
||||
static struct platform_device h3_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h3_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h3_kp_resources),
|
||||
.resource = h3_kp_resources,
|
||||
};
|
||||
|
||||
|
||||
/* Select between the IrDA and aGPS module
|
||||
*/
|
||||
static int h3_select_irda(struct device *dev, int state)
|
||||
{
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x26))) {
|
||||
printk(KERN_ERR "Error reading from I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 'P6' enable/disable IRDA_TX and IRDA_RX */
|
||||
if (state & IR_SEL) { /* IrDA */
|
||||
if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
|
||||
printk(KERN_ERR "Error writing to I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
|
||||
printk(KERN_ERR "Error writing to I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void set_trans_mode(void *data)
|
||||
{
|
||||
int *mode = data;
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
}
|
||||
|
||||
expa &= ~0x03;
|
||||
|
||||
if (*mode & IR_SIRMODE) {
|
||||
expa |= 0x01;
|
||||
} else { /* MIR/FIR */
|
||||
expa |= 0x03;
|
||||
}
|
||||
|
||||
if ((err = write_gpio_expa(expa, 0x27)) != 0) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int h3_transceiver_mode(struct device *dev, int mode)
|
||||
{
|
||||
struct omap_irda_config *irda_config = dev->platform_data;
|
||||
|
||||
cancel_delayed_work(&irda_config->gpio_expa);
|
||||
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
|
||||
schedule_work(&irda_config->gpio_expa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct omap_irda_config h3_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.transceiver_mode = h3_transceiver_mode,
|
||||
.select_irda = h3_select_irda,
|
||||
.rx_channel = OMAP_DMA_UART3_RX,
|
||||
.tx_channel = OMAP_DMA_UART3_TX,
|
||||
.dest_start = UART3_THR,
|
||||
.src_start = UART3_RHR,
|
||||
.tx_trigger = 0,
|
||||
.rx_trigger = 0,
|
||||
};
|
||||
|
||||
static struct resource h3_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_UART3,
|
||||
.end = INT_UART3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h3_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h3_irda_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h3_irda_resources),
|
||||
.resource = h3_irda_resources,
|
||||
};
|
||||
|
||||
static struct platform_device h3_lcd_device = {
|
||||
.name = "lcd_h3",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&flash_device,
|
||||
&nor_device,
|
||||
&nand_device,
|
||||
&smc91x_device,
|
||||
&intlat_device,
|
||||
&h3_irda_device,
|
||||
&h3_kp_device,
|
||||
&h3_lcd_device,
|
||||
};
|
||||
|
||||
static struct omap_usb_config h3_usb_config __initdata = {
|
||||
@ -171,7 +398,6 @@ static struct omap_uart_config h3_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h3_lcd_config __initdata = {
|
||||
.panel_name = "h3",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -182,11 +408,36 @@ static struct omap_board_config_kernel h3_config[] = {
|
||||
{ OMAP_TAG_LCD, &h3_lcd_config },
|
||||
};
|
||||
|
||||
#define H3_NAND_RB_GPIO_PIN 10
|
||||
|
||||
static int nand_dev_ready(struct nand_platform_data *data)
|
||||
{
|
||||
return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
|
||||
}
|
||||
|
||||
static void __init h3_init(void)
|
||||
{
|
||||
h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
|
||||
h3_flash_resource.end += OMAP_CS3_SIZE - 1;
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
|
||||
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
|
||||
* notice whether a NAND chip is enabled at probe time.
|
||||
*
|
||||
* H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
|
||||
* (which on H2 may be 16bit) on CS3. Try detecting that in code here,
|
||||
* to avoid probing every possible flash configuration...
|
||||
*/
|
||||
nor_resource.end = nor_resource.start = omap_cs3_phys();
|
||||
nor_resource.end += SZ_32M - 1;
|
||||
|
||||
nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
|
||||
nand_resource.end += SZ_4K - 1;
|
||||
if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
|
||||
nand_data.dev_ready = nand_dev_ready;
|
||||
|
||||
/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
|
||||
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
|
||||
omap_cfg_reg(V2_1710_GPIO10);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
omap_board_config = h3_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h3_config);
|
||||
omap_serial_init();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -34,8 +35,22 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static int innovator_keymap[] = {
|
||||
KEY(0, 0, KEY_F1),
|
||||
KEY(0, 3, KEY_DOWN),
|
||||
KEY(1, 1, KEY_F2),
|
||||
KEY(1, 2, KEY_RIGHT),
|
||||
KEY(2, 0, KEY_F3),
|
||||
KEY(2, 1, KEY_F4),
|
||||
KEY(2, 2, KEY_UP),
|
||||
KEY(3, 2, KEY_ENTER),
|
||||
KEY(3, 3, KEY_LEFT),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition innovator_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -97,6 +112,31 @@ static struct platform_device innovator_flash_device = {
|
||||
.resource = &innovator_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource innovator_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data innovator_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = innovator_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device innovator_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &innovator_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(innovator_kp_resources),
|
||||
.resource = innovator_kp_resources,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
|
||||
/* Only FPGA needs to be mapped here. All others are done with ioremap */
|
||||
@ -129,9 +169,16 @@ static struct platform_device innovator1510_smc91x_device = {
|
||||
.resource = innovator1510_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device innovator1510_lcd_device = {
|
||||
.name = "lcd_inn1510",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *innovator1510_devices[] __initdata = {
|
||||
&innovator_flash_device,
|
||||
&innovator1510_smc91x_device,
|
||||
&innovator_kp_device,
|
||||
&innovator1510_lcd_device,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP15XX */
|
||||
@ -158,9 +205,16 @@ static struct platform_device innovator1610_smc91x_device = {
|
||||
.resource = innovator1610_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device innovator1610_lcd_device = {
|
||||
.name = "inn1610_lcd",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *innovator1610_devices[] __initdata = {
|
||||
&innovator_flash_device,
|
||||
&innovator1610_smc91x_device,
|
||||
&innovator_kp_device,
|
||||
&innovator1610_lcd_device,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP16XX */
|
||||
@ -206,7 +260,6 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1510_lcd_config __initdata = {
|
||||
.panel_name = "inn1510",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
@ -228,7 +281,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1610_lcd_config __initdata = {
|
||||
.panel_name = "inn1610",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
|
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
|
||||
*
|
||||
* Code for Netstar OMAP board.
|
||||
*
|
||||
* 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/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
extern void __init omap_init_time(void);
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct resource netstar_smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = OMAP_CS1_PHYS + 0x300,
|
||||
.end = OMAP_CS1_PHYS + 0x300 + 16,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = OMAP_GPIO_IRQ(8),
|
||||
.end = OMAP_GPIO_IRQ(8),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device netstar_smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(netstar_smc91x_resources),
|
||||
.resource = netstar_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *netstar_devices[] __initdata = {
|
||||
&netstar_smc91x_device,
|
||||
};
|
||||
|
||||
static struct omap_uart_config netstar_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel netstar_config[] = {
|
||||
{ OMAP_TAG_UART, &netstar_uart_config },
|
||||
};
|
||||
|
||||
static void __init netstar_init_irq(void)
|
||||
{
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
}
|
||||
|
||||
static void __init netstar_init(void)
|
||||
{
|
||||
/* green LED */
|
||||
omap_request_gpio(4);
|
||||
omap_set_gpio_direction(4, 0);
|
||||
/* smc91x reset */
|
||||
omap_request_gpio(7);
|
||||
omap_set_gpio_direction(7, 0);
|
||||
omap_set_gpio_dataout(7, 1);
|
||||
udelay(2); /* wait at least 100ns */
|
||||
omap_set_gpio_dataout(7, 0);
|
||||
mdelay(50); /* 50ms until PHY ready */
|
||||
/* smc91x interrupt pin */
|
||||
omap_request_gpio(8);
|
||||
|
||||
omap_request_gpio(12);
|
||||
omap_request_gpio(13);
|
||||
omap_request_gpio(14);
|
||||
omap_request_gpio(15);
|
||||
set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
|
||||
|
||||
platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
|
||||
|
||||
/* Switch on green LED */
|
||||
omap_set_gpio_dataout(4, 0);
|
||||
/* Switch off red LED */
|
||||
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
|
||||
omap_writeb(0x80, OMAP_LPG1_LCR);
|
||||
|
||||
omap_board_config = netstar_config;
|
||||
omap_board_config_size = ARRAY_SIZE(netstar_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init netstar_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
#define MACHINE_PANICED 1
|
||||
#define MACHINE_REBOOTING 2
|
||||
#define MACHINE_REBOOT 4
|
||||
static unsigned long machine_state;
|
||||
|
||||
static int panic_event(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
if (test_and_set_bit(MACHINE_PANICED, &machine_state))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Switch off green LED */
|
||||
omap_set_gpio_dataout(4, 1);
|
||||
/* Flash red LED */
|
||||
omap_writeb(0x78, OMAP_LPG1_LCR);
|
||||
omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block panic_block = {
|
||||
.notifier_call = panic_event,
|
||||
};
|
||||
|
||||
static int __init netstar_late_init(void)
|
||||
{
|
||||
/* TODO: Setup front panel switch here */
|
||||
|
||||
/* Setup panic notifier */
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(netstar_late_init);
|
||||
|
||||
MACHINE_START(NETSTAR, "NetStar OMAP5910")
|
||||
/* Maintainer: Ladislav Michl <michl@2n.cz> */
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = netstar_map_io,
|
||||
.init_irq = netstar_init_irq,
|
||||
.init_machine = netstar_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
268
arch/arm/mach-omap1/board-nokia770.c
Normal file
268
arch/arm/mach-omap1/board-nokia770.c
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/board-nokia770.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/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/dsp_common.h>
|
||||
#include <asm/arch/aic23.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
static void __init omap_nokia770_init_irq(void)
|
||||
{
|
||||
/* On Nokia 770, the SleepX signal is masked with an
|
||||
* MPUIO line by default. It has to be unmasked for it
|
||||
* to become functional */
|
||||
|
||||
/* SleepX mask direction */
|
||||
omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
|
||||
/* Unmask SleepX signal */
|
||||
omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
|
||||
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static int nokia770_keymap[] = {
|
||||
KEY(0, 1, GROUP_0 | KEY_UP),
|
||||
KEY(0, 2, GROUP_1 | KEY_F5),
|
||||
KEY(1, 0, GROUP_0 | KEY_LEFT),
|
||||
KEY(1, 1, GROUP_0 | KEY_ENTER),
|
||||
KEY(1, 2, GROUP_0 | KEY_RIGHT),
|
||||
KEY(2, 0, GROUP_1 | KEY_ESC),
|
||||
KEY(2, 1, GROUP_0 | KEY_DOWN),
|
||||
KEY(2, 2, GROUP_1 | KEY_F4),
|
||||
KEY(3, 0, GROUP_2 | KEY_F7),
|
||||
KEY(3, 1, GROUP_2 | KEY_F8),
|
||||
KEY(3, 2, GROUP_2 | KEY_F6),
|
||||
0
|
||||
};
|
||||
|
||||
static struct resource nokia770_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data nokia770_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = nokia770_keymap
|
||||
};
|
||||
|
||||
static struct platform_device nokia770_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &nokia770_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(nokia770_kp_resources),
|
||||
.resource = nokia770_kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *nokia770_devices[] __initdata = {
|
||||
&nokia770_kp_device,
|
||||
};
|
||||
|
||||
static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
|
||||
.x_max = 0x0fff,
|
||||
.y_max = 0x0fff,
|
||||
.x_plate_ohms = 180,
|
||||
.pressure_max = 255,
|
||||
.debounce_max = 10,
|
||||
.debounce_tol = 3,
|
||||
};
|
||||
|
||||
static struct spi_board_info nokia770_spi_board_info[] __initdata = {
|
||||
[0] = {
|
||||
.modalias = "lcd_lph8923",
|
||||
.bus_num = 2,
|
||||
.chip_select = 3,
|
||||
.max_speed_hz = 12000000,
|
||||
},
|
||||
[1] = {
|
||||
.modalias = "ads7846",
|
||||
.bus_num = 2,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 2500000,
|
||||
.irq = OMAP_GPIO_IRQ(15),
|
||||
.platform_data = &nokia770_ads7846_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* assume no Mini-AB port */
|
||||
|
||||
static struct omap_usb_config nokia770_usb_config __initdata = {
|
||||
.otg = 1,
|
||||
.register_host = 1,
|
||||
.register_dev = 1,
|
||||
.hmc_mode = 16,
|
||||
.pins[0] = 6,
|
||||
};
|
||||
|
||||
static struct omap_mmc_config nokia770_mmc_config __initdata = {
|
||||
.mmc[0] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
.mmc[1] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel nokia770_config[] = {
|
||||
{ OMAP_TAG_USB, NULL },
|
||||
{ OMAP_TAG_MMC, &nokia770_mmc_config },
|
||||
};
|
||||
|
||||
/*
|
||||
* audio power control
|
||||
*/
|
||||
#define HEADPHONE_GPIO 14
|
||||
#define AMPLIFIER_CTRL_GPIO 58
|
||||
|
||||
static struct clk *dspxor_ck;
|
||||
static DECLARE_MUTEX(audio_pwr_sem);
|
||||
/*
|
||||
* audio_pwr_state
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* |-1|down |power-up request -> 0 |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* | 0|up |power-down(1) request -> 1 |
|
||||
* | | |power-down(2) request -> (ignore) |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* | 1|up, |power-up request -> 0 |
|
||||
* | |received down(1) request |power-down(2) request -> -1 |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
*/
|
||||
static int audio_pwr_state = -1;
|
||||
|
||||
/*
|
||||
* audio_pwr_up / down should be called under audio_pwr_sem
|
||||
*/
|
||||
static void nokia770_audio_pwr_up(void)
|
||||
{
|
||||
clk_enable(dspxor_ck);
|
||||
|
||||
/* Turn on codec */
|
||||
tlv320aic23_power_up();
|
||||
|
||||
if (omap_get_gpio_datain(HEADPHONE_GPIO))
|
||||
/* HP not connected, turn on amplifier */
|
||||
omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1);
|
||||
else
|
||||
/* HP connected, do not turn on amplifier */
|
||||
printk("HP connected\n");
|
||||
}
|
||||
|
||||
static void codec_delayed_power_down(void *arg)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
if (audio_pwr_state == -1)
|
||||
tlv320aic23_power_down();
|
||||
clk_disable(dspxor_ck);
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
|
||||
|
||||
static void nokia770_audio_pwr_down(void)
|
||||
{
|
||||
/* Turn off amplifier */
|
||||
omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0);
|
||||
|
||||
/* Turn off codec: schedule delayed work */
|
||||
schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
|
||||
}
|
||||
|
||||
void nokia770_audio_pwr_up_request(int stage)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
if (audio_pwr_state == -1)
|
||||
nokia770_audio_pwr_up();
|
||||
/* force audio_pwr_state = 0, even if it was 1. */
|
||||
audio_pwr_state = 0;
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
void nokia770_audio_pwr_down_request(int stage)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
switch (stage) {
|
||||
case 1:
|
||||
if (audio_pwr_state == 0)
|
||||
audio_pwr_state = 1;
|
||||
break;
|
||||
case 2:
|
||||
if (audio_pwr_state == 1) {
|
||||
nokia770_audio_pwr_down();
|
||||
audio_pwr_state = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
static void __init omap_nokia770_init(void)
|
||||
{
|
||||
nokia770_config[0].data = &nokia770_usb_config;
|
||||
|
||||
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
|
||||
spi_register_board_info(nokia770_spi_board_info,
|
||||
ARRAY_SIZE(nokia770_spi_board_info));
|
||||
omap_board_config = nokia770_config;
|
||||
omap_board_config_size = ARRAY_SIZE(nokia770_config);
|
||||
omap_serial_init();
|
||||
omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
|
||||
omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
|
||||
dspxor_ck = clk_get(0, "dspxor_ck");
|
||||
}
|
||||
|
||||
static void __init omap_nokia770_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(NOKIA770, "Nokia 770")
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = omap_nokia770_map_io,
|
||||
.init_irq = omap_nokia770_init_irq,
|
||||
.init_machine = omap_nokia770_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -44,7 +45,24 @@
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/mcbsp.h>
|
||||
#include <asm/arch/omap-alsa.h>
|
||||
|
||||
static int osk_keymap[] = {
|
||||
KEY(0, 0, KEY_F1),
|
||||
KEY(0, 3, KEY_UP),
|
||||
KEY(1, 1, KEY_LEFTCTRL),
|
||||
KEY(1, 2, KEY_LEFT),
|
||||
KEY(2, 0, KEY_SPACE),
|
||||
KEY(2, 1, KEY_ESC),
|
||||
KEY(2, 2, KEY_DOWN),
|
||||
KEY(3, 2, KEY_ENTER),
|
||||
KEY(3, 3, KEY_RIGHT),
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static struct mtd_partition osk_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
@ -133,9 +151,69 @@ static struct platform_device osk5912_cf_device = {
|
||||
.resource = osk5912_cf_resources,
|
||||
};
|
||||
|
||||
#define DEFAULT_BITPERSAMPLE 16
|
||||
|
||||
static struct omap_mcbsp_reg_cfg mcbsp_regs = {
|
||||
.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
|
||||
.spcr1 = RINTM(3) | RRST,
|
||||
.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
|
||||
.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
|
||||
.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
|
||||
.srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
|
||||
/*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */
|
||||
.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
|
||||
};
|
||||
|
||||
static struct omap_alsa_codec_config alsa_config = {
|
||||
.name = "OSK AIC23",
|
||||
.mcbsp_regs_alsa = &mcbsp_regs,
|
||||
.codec_configure_dev = NULL, // aic23_configure,
|
||||
.codec_set_samplerate = NULL, // aic23_set_samplerate,
|
||||
.codec_clock_setup = NULL, // aic23_clock_setup,
|
||||
.codec_clock_on = NULL, // aic23_clock_on,
|
||||
.codec_clock_off = NULL, // aic23_clock_off,
|
||||
.get_default_samplerate = NULL, // aic23_get_default_samplerate,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_mcbsp1_device = {
|
||||
.name = "omap_mcbsp",
|
||||
.id = 1,
|
||||
.name = "omap_alsa_mcbsp",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &alsa_config,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource osk5912_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data osk_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = osk_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &osk_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(osk5912_kp_resources),
|
||||
.resource = osk5912_kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_lcd_device = {
|
||||
.name = "lcd_osk",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *osk5912_devices[] __initdata = {
|
||||
@ -143,6 +221,8 @@ static struct platform_device *osk5912_devices[] __initdata = {
|
||||
&osk5912_smc91x_device,
|
||||
&osk5912_cf_device,
|
||||
&osk5912_mcbsp1_device,
|
||||
&osk5912_kp_device,
|
||||
&osk5912_lcd_device,
|
||||
};
|
||||
|
||||
static void __init osk_init_smc91x(void)
|
||||
@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config osk_lcd_config __initdata = {
|
||||
.panel_name = "osk",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -255,8 +334,18 @@ static void __init osk_mistral_init(void)
|
||||
static void __init osk_mistral_init(void) { }
|
||||
#endif
|
||||
|
||||
#define EMIFS_CS3_VAL (0x88013141)
|
||||
|
||||
static void __init osk_init(void)
|
||||
{
|
||||
/* Workaround for wrong CS3 (NOR flash) timing
|
||||
* There are some U-Boot versions out there which configure
|
||||
* wrong CS3 memory timings. This mainly leads to CRC
|
||||
* or similiar errors if you use NOR flash (e.g. with JFFS2)
|
||||
*/
|
||||
if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
|
||||
EMIFS_CCS(3) = EMIFS_CS3_VAL;
|
||||
|
||||
osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
|
||||
osk_flash_resource.end += SZ_32M - 1;
|
||||
platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
|
||||
|
@ -38,6 +38,15 @@ static void __init omap_generic_init_irq(void)
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static struct platform_device palmte_lcd_device = {
|
||||
.name = "lcd_palmte",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&palmte_lcd_device,
|
||||
};
|
||||
|
||||
static struct omap_usb_config palmte_usb_config __initdata = {
|
||||
.register_dev = 1,
|
||||
.hmc_mode = 0,
|
||||
@ -55,7 +64,6 @@ static struct omap_mmc_config palmte_mmc_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config palmte_lcd_config __initdata = {
|
||||
.panel_name = "palmte",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -69,6 +77,8 @@ static void __init omap_generic_init(void)
|
||||
{
|
||||
omap_board_config = palmte_config;
|
||||
omap_board_config_size = ARRAY_SIZE(palmte_config);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
||||
static void __init omap_generic_map_io(void)
|
||||
|
@ -16,7 +16,9 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -28,9 +30,44 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/fpga.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
static int p2_keymap[] = {
|
||||
KEY(0,0,KEY_UP),
|
||||
KEY(0,1,KEY_RIGHT),
|
||||
KEY(0,2,KEY_LEFT),
|
||||
KEY(0,3,KEY_DOWN),
|
||||
KEY(0,4,KEY_CENTER),
|
||||
KEY(0,5,KEY_0_5),
|
||||
KEY(1,0,KEY_SOFT2),
|
||||
KEY(1,1,KEY_SEND),
|
||||
KEY(1,2,KEY_END),
|
||||
KEY(1,3,KEY_VOLUMEDOWN),
|
||||
KEY(1,4,KEY_VOLUMEUP),
|
||||
KEY(1,5,KEY_RECORD),
|
||||
KEY(2,0,KEY_SOFT1),
|
||||
KEY(2,1,KEY_3),
|
||||
KEY(2,2,KEY_6),
|
||||
KEY(2,3,KEY_9),
|
||||
KEY(2,4,KEY_SHARP),
|
||||
KEY(2,5,KEY_2_5),
|
||||
KEY(3,0,KEY_BACK),
|
||||
KEY(3,1,KEY_2),
|
||||
KEY(3,2,KEY_5),
|
||||
KEY(3,3,KEY_8),
|
||||
KEY(3,4,KEY_0),
|
||||
KEY(3,5,KEY_HEADSETHOOK),
|
||||
KEY(4,0,KEY_HOME),
|
||||
KEY(4,1,KEY_1),
|
||||
KEY(4,2,KEY_4),
|
||||
KEY(4,3,KEY_7),
|
||||
KEY(4,4,KEY_STAR),
|
||||
KEY(4,5,KEY_POWER),
|
||||
0
|
||||
};
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
|
||||
@ -44,7 +81,7 @@ static struct resource smc91x_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition p2_partitions[] = {
|
||||
static struct mtd_partition nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -75,27 +112,47 @@ static struct mtd_partition p2_partitions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct flash_platform_data p2_flash_data = {
|
||||
static struct flash_platform_data nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = p2_partitions,
|
||||
.nr_parts = ARRAY_SIZE(p2_partitions),
|
||||
.parts = nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource p2_flash_resource = {
|
||||
static struct resource nor_resource = {
|
||||
.start = OMAP_CS0_PHYS,
|
||||
.end = OMAP_CS0_PHYS + SZ_32M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device p2_flash_device = {
|
||||
static struct platform_device nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &p2_flash_data,
|
||||
.platform_data = &nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &p2_flash_resource,
|
||||
.resource = &nor_resource,
|
||||
};
|
||||
|
||||
static struct nand_platform_data nand_data = {
|
||||
.options = NAND_SAMSUNG_LP_OPTIONS,
|
||||
};
|
||||
|
||||
static struct resource nand_resource = {
|
||||
.start = OMAP_CS3_PHYS,
|
||||
.end = OMAP_CS3_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device nand_device = {
|
||||
.name = "omapnand",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &nand_resource,
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
@ -105,17 +162,55 @@ static struct platform_device smc91x_device = {
|
||||
.resource = smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&p2_flash_device,
|
||||
&smc91x_device,
|
||||
static struct resource kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_730_MPUIO_KEYPAD,
|
||||
.end = INT_730_MPUIO_KEYPAD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = p2_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(kp_resources),
|
||||
.resource = kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device lcd_device = {
|
||||
.name = "lcd_p2",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&nor_device,
|
||||
&nand_device,
|
||||
&smc91x_device,
|
||||
&kp_device,
|
||||
&lcd_device,
|
||||
};
|
||||
|
||||
#define P2_NAND_RB_GPIO_PIN 62
|
||||
|
||||
static int nand_dev_ready(struct nand_platform_data *data)
|
||||
{
|
||||
return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
|
||||
}
|
||||
|
||||
static struct omap_uart_config perseus2_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1)),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config perseus2_lcd_config __initdata = {
|
||||
.panel_name = "p2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -126,7 +221,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
|
||||
|
||||
static void __init omap_perseus2_init(void)
|
||||
{
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
|
||||
nand_data.dev_ready = nand_dev_ready;
|
||||
|
||||
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
|
||||
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
omap_board_config = perseus2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(perseus2_config);
|
||||
|
@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel voiceblue_config[] = {
|
||||
{ OMAP_TAG_USB, &voiceblue_usb_config },
|
||||
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
|
||||
{ OMAP_TAG_UART, &voiceblue_uart_config },
|
||||
{ OMAP_TAG_USB, &voiceblue_usb_config },
|
||||
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
|
||||
{ OMAP_TAG_UART, &voiceblue_uart_config },
|
||||
};
|
||||
|
||||
static void __init voiceblue_init_irq(void)
|
||||
@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
|
||||
static int __init voiceblue_setup(void)
|
||||
{
|
||||
/* Setup panic notifier */
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate)
|
||||
*/
|
||||
for (dsor = 2; dsor < 96; ++dsor) {
|
||||
if ((dsor & 1) && dsor > 8)
|
||||
continue;
|
||||
continue;
|
||||
if (rate >= 96000000 / dsor)
|
||||
break;
|
||||
}
|
||||
@ -687,6 +687,11 @@ int __init omap1_clk_init(void)
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
|
||||
@ -784,7 +789,7 @@ int __init omap1_clk_init(void)
|
||||
clk_enable(&armxor_ck.clk);
|
||||
clk_enable(&armtim_ck.clk); /* This should be done by timer code */
|
||||
|
||||
if (cpu_is_omap1510())
|
||||
if (cpu_is_omap15xx())
|
||||
clk_enable(&arm_gpio_ck);
|
||||
|
||||
return 0;
|
||||
|
@ -151,7 +151,7 @@ static struct clk ck_ref = {
|
||||
.name = "ck_ref",
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -160,7 +160,7 @@ static struct clk ck_dpll1 = {
|
||||
.name = "ck_dpll1",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -183,7 +183,8 @@ static struct clk arm_ck = {
|
||||
.name = "arm_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
|
||||
ALWAYS_ENABLED,
|
||||
.rate_offset = CKCTL_ARMDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -195,7 +196,8 @@ static struct arm_idlect1_clk armper_ck = {
|
||||
.name = "armper_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | RATE_CKCTL |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_PERCK,
|
||||
.rate_offset = CKCTL_PERDIV_OFFSET,
|
||||
@ -209,7 +211,7 @@ static struct arm_idlect1_clk armper_ck = {
|
||||
static struct clk arm_gpio_ck = {
|
||||
.name = "arm_gpio_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_GPIOCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -222,7 +224,7 @@ static struct arm_idlect1_clk armxor_ck = {
|
||||
.name = "armxor_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_XORPCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -237,7 +239,7 @@ static struct arm_idlect1_clk armtim_ck = {
|
||||
.name = "armtim_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_TIMCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -252,7 +254,7 @@ static struct arm_idlect1_clk armwdt_ck = {
|
||||
.name = "armwdt_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_WDTCK,
|
||||
.recalc = &omap1_watchdog_recalc,
|
||||
@ -344,9 +346,9 @@ static struct arm_idlect1_clk tc_ck = {
|
||||
.name = "tc_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IN_OMAP730 | RATE_CKCTL |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
|
||||
RATE_CKCTL | RATE_PROPAGATES |
|
||||
ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
|
||||
.rate_offset = CKCTL_TCDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -358,7 +360,8 @@ static struct arm_idlect1_clk tc_ck = {
|
||||
static struct clk arminth_ck1510 = {
|
||||
.name = "arminth_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
/* Note: On 1510 the frequency follows TC_CK
|
||||
*
|
||||
@ -372,7 +375,8 @@ static struct clk tipb_ck = {
|
||||
/* No-idle controlled by "tc_ck" */
|
||||
.name = "tibp_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
@ -417,7 +421,7 @@ static struct clk dma_ck = {
|
||||
.name = "dma_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
@ -437,7 +441,7 @@ static struct arm_idlect1_clk api_ck = {
|
||||
.name = "api_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_APICK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -451,7 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
|
||||
.clk = {
|
||||
.name = "lb_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LBCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -495,8 +500,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
|
||||
.clk = {
|
||||
.name = "lcd_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_CKCTL |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
RATE_CKCTL | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LCDCK,
|
||||
.rate_offset = CKCTL_LCDDIV_OFFSET,
|
||||
@ -512,8 +517,9 @@ static struct clk uart1_1510 = {
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -544,8 +550,8 @@ static struct clk uart2_ck = {
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -559,8 +565,9 @@ static struct clk uart3_1510 = {
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -590,7 +597,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 6000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
|
||||
.enable_bit = USB_MCLK_EN_BIT,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -601,7 +608,7 @@ static struct clk usb_hhc_ck1510 = {
|
||||
.name = "usb_hhc_ck",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
|
||||
.flags = CLOCK_IN_OMAP1510 |
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = USB_HOST_HHC_UHOST_EN,
|
||||
@ -637,7 +644,9 @@ static struct clk mclk_1510 = {
|
||||
.name = "mclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
|
||||
.enable_reg = (void __iomem *)SOFT_REQ_REG,
|
||||
.enable_bit = 6,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -659,7 +668,7 @@ static struct clk bclk_1510 = {
|
||||
.name = "bclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -678,12 +687,14 @@ static struct clk bclk_16xx = {
|
||||
};
|
||||
|
||||
static struct clk mmc1_ck = {
|
||||
.name = "mmc1_ck",
|
||||
.name = "mmc_ck",
|
||||
.id = 1,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 23,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -691,7 +702,8 @@ static struct clk mmc1_ck = {
|
||||
};
|
||||
|
||||
static struct clk mmc2_ck = {
|
||||
.name = "mmc2_ck",
|
||||
.name = "mmc_ck",
|
||||
.id = 2,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
@ -706,7 +718,7 @@ static struct clk mmc2_ck = {
|
||||
static struct clk virtual_ck_mpu = {
|
||||
.name = "mpu",
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_CLOCK | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
|
||||
.parent = &arm_ck, /* Is smarter alias for */
|
||||
.recalc = &followparent_recalc,
|
||||
.set_rate = &omap1_select_table_rate,
|
||||
@ -715,6 +727,20 @@ static struct clk virtual_ck_mpu = {
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
|
||||
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
|
||||
remains active during MPU idle whenever this is enabled */
|
||||
static struct clk i2c_fck = {
|
||||
.name = "i2c_fck",
|
||||
.id = 1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
|
||||
ALWAYS_ENABLED,
|
||||
.parent = &armxor_ck.clk,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
|
||||
static struct clk * onchip_clks[] = {
|
||||
/* non-ULPD clocks */
|
||||
&ck_ref,
|
||||
@ -763,6 +789,7 @@ static struct clk * onchip_clks[] = {
|
||||
&mmc2_ck,
|
||||
/* Virtual clocks */
|
||||
&virtual_ck_mpu,
|
||||
&i2c_fck,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -99,6 +99,45 @@ static void omap_init_rtc(void)
|
||||
static inline void omap_init_rtc(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_STI)
|
||||
|
||||
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
|
||||
#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
|
||||
|
||||
static struct resource sti_resources[] = {
|
||||
{
|
||||
.start = OMAP1_STI_BASE,
|
||||
.end = OMAP1_STI_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP1_STI_CHANNEL_BASE,
|
||||
.end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_1610_STI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sti_device = {
|
||||
.name = "sti",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(sti_resources),
|
||||
.resource = sti_resources,
|
||||
};
|
||||
|
||||
static inline void omap_init_sti(void)
|
||||
{
|
||||
platform_device_register(&sti_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@ -129,6 +168,7 @@ static int __init omap1_init_devices(void)
|
||||
*/
|
||||
omap_init_irda();
|
||||
omap_init_rtc();
|
||||
omap_init_sti();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 },
|
||||
};
|
||||
|
@ -35,16 +35,20 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP730
|
||||
struct pin_config __initdata_or_module omap730_pins[] = {
|
||||
MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0)
|
||||
MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0)
|
||||
MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0)
|
||||
MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0)
|
||||
MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0)
|
||||
MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0)
|
||||
MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0)
|
||||
MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0)
|
||||
MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0)
|
||||
MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0)
|
||||
MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0)
|
||||
|
||||
MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0)
|
||||
MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0)
|
||||
MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0)
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -73,8 +77,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
|
||||
MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
|
||||
|
||||
/* PWT & PWL, conflicts with UART3 */
|
||||
MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
|
||||
MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
|
||||
|
||||
/* USB internal master generic */
|
||||
MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
|
||||
@ -151,7 +155,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
|
||||
|
||||
/* Misc ballouts */
|
||||
MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
|
||||
MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
|
||||
MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
|
||||
|
||||
/* OMAP-1610 MMC2 */
|
||||
MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
|
||||
|
770
arch/arm/mach-omap1/pm.c
Normal file
770
arch/arm/mach-omap1/pm.c
Normal file
@ -0,0 +1,770 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/pm.c
|
||||
*
|
||||
* OMAP Power Management Routines
|
||||
*
|
||||
* Original code for the SA11x0:
|
||||
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
|
||||
*
|
||||
* Modified for the PXA250 by Nicolas Pitre:
|
||||
* Copyright (c) 2002 Monta Vista Software, Inc.
|
||||
*
|
||||
* Modified for the OMAP1510 by David Singleton:
|
||||
* Copyright (c) 2002 Monta Vista Software, Inc.
|
||||
*
|
||||
* Cleanup 2004 for OMAP1510/1610 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/pm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/pm.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tps65010.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include <asm/arch/dsp_common.h>
|
||||
#include <asm/arch/dmtimer.h>
|
||||
|
||||
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
|
||||
static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
|
||||
static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
|
||||
|
||||
static unsigned short enable_dyn_sleep = 1;
|
||||
|
||||
static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%hu\n", enable_dyn_sleep);
|
||||
}
|
||||
|
||||
static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
|
||||
const char * buf,
|
||||
size_t n)
|
||||
{
|
||||
unsigned short value;
|
||||
if (sscanf(buf, "%hu", &value) != 1 ||
|
||||
(value != 0 && value != 1)) {
|
||||
printk(KERN_ERR "idle_sleep_store: Invalid value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
enable_dyn_sleep = value;
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct subsys_attribute sleep_while_idle_attr = {
|
||||
.attr = {
|
||||
.name = __stringify(sleep_while_idle),
|
||||
.mode = 0644,
|
||||
},
|
||||
.show = omap_pm_sleep_while_idle_show,
|
||||
.store = omap_pm_sleep_while_idle_store,
|
||||
};
|
||||
|
||||
extern struct subsystem power_subsys;
|
||||
static void (*omap_sram_idle)(void) = NULL;
|
||||
static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
|
||||
|
||||
/*
|
||||
* Let's power down on idle, but only if we are really
|
||||
* idle, because once we start down the path of
|
||||
* going idle we continue to do idle even if we get
|
||||
* a clock tick interrupt . .
|
||||
*/
|
||||
void omap_pm_idle(void)
|
||||
{
|
||||
extern __u32 arm_idlect1_mask;
|
||||
__u32 use_idlect1 = arm_idlect1_mask;
|
||||
#ifndef CONFIG_OMAP_MPU_TIMER
|
||||
int do_sleep;
|
||||
#endif
|
||||
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
if (need_resched()) {
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since an interrupt may set up a timer, we don't want to
|
||||
* reprogram the hardware timer with interrupts enabled.
|
||||
* Re-enable interrupts only after returning from idle.
|
||||
*/
|
||||
timer_dyn_reprogram();
|
||||
|
||||
#ifdef CONFIG_OMAP_MPU_TIMER
|
||||
#warning Enable 32kHz OS timer in order to allow sleep states in idle
|
||||
use_idlect1 = use_idlect1 & ~(1 << 9);
|
||||
#else
|
||||
|
||||
do_sleep = 0;
|
||||
while (enable_dyn_sleep) {
|
||||
|
||||
#ifdef CONFIG_CBUS_TAHVO_USB
|
||||
extern int vbus_active;
|
||||
/* Clock requirements? */
|
||||
if (vbus_active)
|
||||
break;
|
||||
#endif
|
||||
do_sleep = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP_DM_TIMER
|
||||
use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
|
||||
#endif
|
||||
|
||||
if (omap_dma_running()) {
|
||||
use_idlect1 &= ~(1 << 6);
|
||||
if (omap_lcd_dma_ext_running())
|
||||
use_idlect1 &= ~(1 << 12);
|
||||
}
|
||||
|
||||
/* We should be able to remove the do_sleep variable and multiple
|
||||
* tests above as soon as drivers, timer and DMA code have been fixed.
|
||||
* Even the sleep block count should become obsolete. */
|
||||
if ((use_idlect1 != ~0) || !do_sleep) {
|
||||
|
||||
__u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
|
||||
if (cpu_is_omap15xx())
|
||||
use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
|
||||
else
|
||||
use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
|
||||
omap_writel(use_idlect1, ARM_IDLECT1);
|
||||
__asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
|
||||
omap_writel(saved_idlect1, ARM_IDLECT1);
|
||||
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
omap_sram_suspend(omap_readl(ARM_IDLECT1),
|
||||
omap_readl(ARM_IDLECT2));
|
||||
#endif
|
||||
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration of the wakeup event is board specific. For the
|
||||
* moment we put it into this helper function. Later it may move
|
||||
* to board specific files.
|
||||
*/
|
||||
static void omap_pm_wakeup_setup(void)
|
||||
{
|
||||
u32 level1_wake = 0;
|
||||
u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
|
||||
|
||||
/*
|
||||
* Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
|
||||
* and the L2 wakeup interrupts: keypad and UART2. Note that the
|
||||
* drivers must still separately call omap_set_gpio_wakeup() to
|
||||
* wake up to a GPIO interrupt.
|
||||
*/
|
||||
if (cpu_is_omap730())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_730_IH2_IRQ);
|
||||
else if (cpu_is_omap15xx())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
|
||||
else if (cpu_is_omap16xx())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
|
||||
|
||||
omap_writel(~level1_wake, OMAP_IH1_MIR);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
|
||||
OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
|
||||
OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_MIR);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
|
||||
/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
|
||||
omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
|
||||
OMAP_IH2_1_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_2_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_3_MIR);
|
||||
}
|
||||
|
||||
/* New IRQ agreement, recalculate in cascade order */
|
||||
omap_writel(1, OMAP_IH2_CONTROL);
|
||||
omap_writel(1, OMAP_IH1_CONTROL);
|
||||
}
|
||||
|
||||
#define EN_DSPCK 13 /* ARM_CKCTL */
|
||||
#define EN_APICK 6 /* ARM_IDLECT2 */
|
||||
#define DSP_EN 1 /* ARM_RSTCT1 */
|
||||
|
||||
void omap_pm_suspend(void)
|
||||
{
|
||||
unsigned long arg0 = 0, arg1 = 0;
|
||||
|
||||
printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
|
||||
|
||||
omap_serial_wake_trigger(1);
|
||||
|
||||
if (machine_is_omap_osk()) {
|
||||
/* Stop LED1 (D9) blink */
|
||||
tps65010_set_led(LED1, OFF);
|
||||
}
|
||||
|
||||
omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
|
||||
|
||||
/*
|
||||
* Step 1: turn off interrupts (FIXME: NOTE: already disabled)
|
||||
*/
|
||||
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
/*
|
||||
* Step 2: save registers
|
||||
*
|
||||
* The omap is a strange/beautiful device. The caches, memory
|
||||
* and register state are preserved across power saves.
|
||||
* We have to save and restore very little register state to
|
||||
* idle the omap.
|
||||
*
|
||||
* Save interrupt, MPUI, ARM and UPLD control registers.
|
||||
*/
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(OMAP_IH1_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_0_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_1_MIR);
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_SAVE(OMAP_IH1_MIR);
|
||||
MPUI1510_SAVE(OMAP_IH2_MIR);
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_SAVE(EMIFS_CONFIG);
|
||||
MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_SAVE(OMAP_IH1_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_0_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_1_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_2_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_3_MIR);
|
||||
MPUI1610_SAVE(MPUI_CTRL);
|
||||
MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_SAVE(EMIFS_CONFIG);
|
||||
MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
}
|
||||
|
||||
ARM_SAVE(ARM_CKCTL);
|
||||
ARM_SAVE(ARM_IDLECT1);
|
||||
ARM_SAVE(ARM_IDLECT2);
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_SAVE(ARM_IDLECT3);
|
||||
ARM_SAVE(ARM_EWUPCT);
|
||||
ARM_SAVE(ARM_RSTCT1);
|
||||
ARM_SAVE(ARM_RSTCT2);
|
||||
ARM_SAVE(ARM_SYSST);
|
||||
ULPD_SAVE(ULPD_CLOCK_CTRL);
|
||||
ULPD_SAVE(ULPD_STATUS_REQ);
|
||||
|
||||
/* (Step 3 removed - we now allow deep sleep by default) */
|
||||
|
||||
/*
|
||||
* Step 4: OMAP DSP Shutdown
|
||||
*/
|
||||
|
||||
/* stop DSP */
|
||||
omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
|
||||
|
||||
/* shut down dsp_ck */
|
||||
omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
|
||||
|
||||
/* temporarily enabling api_ck to access DSP registers */
|
||||
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
|
||||
|
||||
/* save DSP registers */
|
||||
DSP_SAVE(DSP_IDLECT2);
|
||||
|
||||
/* Stop all DSP domain clocks */
|
||||
__raw_writew(0, DSP_IDLECT2);
|
||||
|
||||
/*
|
||||
* Step 5: Wakeup Event Setup
|
||||
*/
|
||||
|
||||
omap_pm_wakeup_setup();
|
||||
|
||||
/*
|
||||
* Step 6: ARM and Traffic controller shutdown
|
||||
*/
|
||||
|
||||
/* disable ARM watchdog */
|
||||
omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
|
||||
omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
|
||||
|
||||
/*
|
||||
* Step 6b: ARM and Traffic controller shutdown
|
||||
*
|
||||
* Step 6 continues here. Prepare jump to power management
|
||||
* assembly code in internal SRAM.
|
||||
*
|
||||
* Since the omap_cpu_suspend routine has been copied to
|
||||
* SRAM, we'll do an indirect procedure call to it and pass the
|
||||
* contents of arm_idlect1 and arm_idlect2 so it can restore
|
||||
* them when it wakes up and it will return.
|
||||
*/
|
||||
|
||||
arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
|
||||
arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
|
||||
|
||||
/*
|
||||
* Step 6c: ARM and Traffic controller shutdown
|
||||
*
|
||||
* Jump to assembly code. The processor will stay there
|
||||
* until wake up.
|
||||
*/
|
||||
omap_sram_suspend(arg0, arg1);
|
||||
|
||||
/*
|
||||
* If we are here, processor is woken up!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Restore DSP clocks
|
||||
*/
|
||||
|
||||
/* again temporarily enabling api_ck to access DSP registers */
|
||||
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
|
||||
|
||||
/* Restore DSP domain clocks */
|
||||
DSP_RESTORE(DSP_IDLECT2);
|
||||
|
||||
/*
|
||||
* Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
|
||||
*/
|
||||
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_RESTORE(ARM_IDLECT3);
|
||||
ARM_RESTORE(ARM_CKCTL);
|
||||
ARM_RESTORE(ARM_EWUPCT);
|
||||
ARM_RESTORE(ARM_RSTCT1);
|
||||
ARM_RESTORE(ARM_RSTCT2);
|
||||
ARM_RESTORE(ARM_SYSST);
|
||||
ULPD_RESTORE(ULPD_CLOCK_CTRL);
|
||||
ULPD_RESTORE(ULPD_STATUS_REQ);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_RESTORE(EMIFS_CONFIG);
|
||||
MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_0_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_RESTORE(MPUI_CTRL);
|
||||
MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_RESTORE(EMIFS_CONFIG);
|
||||
MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1510_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI1510_RESTORE(OMAP_IH2_MIR);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_RESTORE(MPUI_CTRL);
|
||||
MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_RESTORE(EMIFS_CONFIG);
|
||||
MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
|
||||
MPUI1610_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_0_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_1_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_2_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_3_MIR);
|
||||
}
|
||||
|
||||
omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
|
||||
|
||||
/*
|
||||
* Reenable interrupts
|
||||
*/
|
||||
|
||||
local_irq_enable();
|
||||
local_fiq_enable();
|
||||
|
||||
omap_serial_wake_trigger(0);
|
||||
|
||||
printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
|
||||
|
||||
if (machine_is_omap_osk()) {
|
||||
/* Let LED1 (D9) blink again */
|
||||
tps65010_set_led(LED1, BLINK);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
|
||||
static int g_read_completed;
|
||||
|
||||
/*
|
||||
* Read system PM registers for debugging
|
||||
*/
|
||||
static int omap_pm_read_proc(
|
||||
char *page_buffer,
|
||||
char **my_first_byte,
|
||||
off_t virtual_start,
|
||||
int length,
|
||||
int *eof,
|
||||
void *data)
|
||||
{
|
||||
int my_buffer_offset = 0;
|
||||
char * const my_base = page_buffer;
|
||||
|
||||
ARM_SAVE(ARM_CKCTL);
|
||||
ARM_SAVE(ARM_IDLECT1);
|
||||
ARM_SAVE(ARM_IDLECT2);
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_SAVE(ARM_IDLECT3);
|
||||
ARM_SAVE(ARM_EWUPCT);
|
||||
ARM_SAVE(ARM_RSTCT1);
|
||||
ARM_SAVE(ARM_RSTCT2);
|
||||
ARM_SAVE(ARM_SYSST);
|
||||
|
||||
ULPD_SAVE(ULPD_IT_STATUS);
|
||||
ULPD_SAVE(ULPD_CLOCK_CTRL);
|
||||
ULPD_SAVE(ULPD_SOFT_REQ);
|
||||
ULPD_SAVE(ULPD_STATUS_REQ);
|
||||
ULPD_SAVE(ULPD_DPLL_CTRL);
|
||||
ULPD_SAVE(ULPD_POWER_CTRL);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
MPUI1510_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1510_SAVE(EMIFS_CONFIG);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_SAVE(MPUI_CTRL);
|
||||
MPUI1610_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1610_SAVE(EMIFS_CONFIG);
|
||||
}
|
||||
|
||||
if (virtual_start == 0) {
|
||||
g_read_completed = 0;
|
||||
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"ARM_CKCTL_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT1_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT2_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT3_REG: 0x%-8x \n"
|
||||
"ARM_EWUPCT_REG: 0x%-8x \n"
|
||||
"ARM_RSTCT1_REG: 0x%-8x \n"
|
||||
"ARM_RSTCT2_REG: 0x%-8x \n"
|
||||
"ARM_SYSST_REG: 0x%-8x \n"
|
||||
"ULPD_IT_STATUS_REG: 0x%-4x \n"
|
||||
"ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
|
||||
"ULPD_SOFT_REQ_REG: 0x%-4x \n"
|
||||
"ULPD_DPLL_CTRL_REG: 0x%-4x \n"
|
||||
"ULPD_STATUS_REQ_REG: 0x%-4x \n"
|
||||
"ULPD_POWER_CTRL_REG: 0x%-4x \n",
|
||||
ARM_SHOW(ARM_CKCTL),
|
||||
ARM_SHOW(ARM_IDLECT1),
|
||||
ARM_SHOW(ARM_IDLECT2),
|
||||
ARM_SHOW(ARM_IDLECT3),
|
||||
ARM_SHOW(ARM_EWUPCT),
|
||||
ARM_SHOW(ARM_RSTCT1),
|
||||
ARM_SHOW(ARM_RSTCT2),
|
||||
ARM_SHOW(ARM_SYSST),
|
||||
ULPD_SHOW(ULPD_IT_STATUS),
|
||||
ULPD_SHOW(ULPD_CLOCK_CTRL),
|
||||
ULPD_SHOW(ULPD_SOFT_REQ),
|
||||
ULPD_SHOW(ULPD_DPLL_CTRL),
|
||||
ULPD_SHOW(ULPD_STATUS_REQ),
|
||||
ULPD_SHOW(ULPD_POWER_CTRL));
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI730_CTRL_REG 0x%-8x \n"
|
||||
"MPUI730_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI730_SHOW(MPUI_CTRL),
|
||||
MPUI730_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI730_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI730_SHOW(EMIFS_CONFIG));
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI1510_CTRL_REG 0x%-8x \n"
|
||||
"MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI1510_SHOW(MPUI_CTRL),
|
||||
MPUI1510_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI1510_SHOW(EMIFS_CONFIG));
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI1610_CTRL_REG 0x%-8x \n"
|
||||
"MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI1610_SHOW(MPUI_CTRL),
|
||||
MPUI1610_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI1610_SHOW(EMIFS_CONFIG));
|
||||
}
|
||||
|
||||
g_read_completed++;
|
||||
} else if (g_read_completed >= 1) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
g_read_completed++;
|
||||
|
||||
*my_first_byte = page_buffer;
|
||||
return my_buffer_offset;
|
||||
}
|
||||
|
||||
static void omap_pm_init_proc(void)
|
||||
{
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
entry = create_proc_read_entry("driver/omap_pm",
|
||||
S_IWUSR | S_IRUGO, NULL,
|
||||
omap_pm_read_proc, NULL);
|
||||
}
|
||||
|
||||
#endif /* DEBUG && CONFIG_PROC_FS */
|
||||
|
||||
static void (*saved_idle)(void) = NULL;
|
||||
|
||||
/*
|
||||
* omap_pm_prepare - Do preliminary suspend work.
|
||||
* @state: suspend state we're entering.
|
||||
*
|
||||
*/
|
||||
static int omap_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* We cannot sleep in idle until we have resumed */
|
||||
saved_idle = pm_idle;
|
||||
pm_idle = NULL;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* omap_pm_enter - Actually enter a sleep state.
|
||||
* @state: State we're entering.
|
||||
*
|
||||
*/
|
||||
|
||||
static int omap_pm_enter(suspend_state_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
omap_pm_suspend();
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap_pm_finish - Finish up suspend sequence.
|
||||
* @state: State we're coming out of.
|
||||
*
|
||||
* This is called after we wake back up (or if entering the sleep state
|
||||
* failed).
|
||||
*/
|
||||
|
||||
static int omap_pm_finish(suspend_state_t state)
|
||||
{
|
||||
pm_idle = saved_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
|
||||
struct pt_regs * regs)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap_wakeup_irq = {
|
||||
.name = "peripheral wakeup",
|
||||
.flags = SA_INTERRUPT,
|
||||
.handler = omap_wakeup_interrupt
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct pm_ops omap_pm_ops ={
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap_pm_prepare,
|
||||
.enter = omap_pm_enter,
|
||||
.finish = omap_pm_finish,
|
||||
};
|
||||
|
||||
static int __init omap_pm_init(void)
|
||||
{
|
||||
printk("Power Management for TI OMAP.\n");
|
||||
|
||||
/*
|
||||
* We copy the assembler sleep/wakeup routines to SRAM.
|
||||
* These routines need to be in SRAM as that's the only
|
||||
* memory the MPU can see when it wakes up.
|
||||
*/
|
||||
if (cpu_is_omap730()) {
|
||||
omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
|
||||
omap730_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
|
||||
omap730_cpu_suspend_sz);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
|
||||
omap1510_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
|
||||
omap1510_cpu_suspend_sz);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
|
||||
omap1610_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
|
||||
omap1610_cpu_suspend_sz);
|
||||
}
|
||||
|
||||
if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
|
||||
printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pm_idle = omap_pm_idle;
|
||||
|
||||
if (cpu_is_omap730())
|
||||
setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
else if (cpu_is_omap16xx())
|
||||
setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
|
||||
/* Program new power ramp-up time
|
||||
* (0 for most boards since we don't lower voltage when in deep sleep)
|
||||
*/
|
||||
omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
|
||||
|
||||
/* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
|
||||
omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
|
||||
|
||||
/* Configure IDLECT3 */
|
||||
if (cpu_is_omap730())
|
||||
omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
|
||||
else if (cpu_is_omap16xx())
|
||||
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
|
||||
|
||||
pm_set_ops(&omap_pm_ops);
|
||||
|
||||
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
|
||||
omap_pm_init_proc();
|
||||
#endif
|
||||
|
||||
subsys_create_file(&power_subsys, &sleep_while_idle_attr);
|
||||
|
||||
if (cpu_is_omap16xx()) {
|
||||
/* configure LOW_PWR pin */
|
||||
omap_cfg_reg(T20_1610_LOW_PWR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
__initcall(omap_pm_init);
|
@ -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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/sleep.S
|
||||
* linux/arch/arm/mach-omap1/sleep.S
|
||||
*
|
||||
* Low-level OMAP730/1510/1610 sleep/wakeUp support
|
||||
*
|
||||
@ -383,60 +383,133 @@ ENTRY(omap1610_cpu_suspend)
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
nop
|
||||
|
||||
@ load base address of Traffic Controller
|
||||
@ Load base address of Traffic Controller
|
||||
mov r6, #TCMIF_ASM_BASE & 0xff000000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ prepare to put SDRAM into self-refresh manually
|
||||
@ Prepare to put SDRAM into self-refresh manually
|
||||
ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
|
||||
orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
|
||||
str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ prepare to put EMIFS to Sleep
|
||||
@ Prepare to put EMIFS to Sleep
|
||||
ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
|
||||
str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
@ Load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ turn off clock domains
|
||||
@ do not disable PERCK (0x04)
|
||||
@ Turn off clock domains
|
||||
@ Do not disable PERCK (0x04)
|
||||
mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
|
||||
orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
|
||||
strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
|
||||
@ request ARM idle
|
||||
@ Request ARM idle
|
||||
mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
|
||||
orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
|
||||
strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ disable instruction cache
|
||||
mrc p15, 0, r9, c1, c0, 0
|
||||
bic r2, r9, #0x1000
|
||||
mcr p15, 0, r2, c1, c0, 0
|
||||
nop
|
||||
|
||||
/*
|
||||
* Let's wait for the next wake up event to wake us up. r0 can't be
|
||||
* used here because r0 holds ARM_IDLECT1
|
||||
*/
|
||||
mov r2, #0
|
||||
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
|
||||
|
||||
@ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
|
||||
@ according to this formula:
|
||||
@ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
|
||||
@ Max DPLL_MULT = 18
|
||||
@ DPLL_DIV = 1
|
||||
@ ARMDIV = 1
|
||||
@ => 74 nop-instructions
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @10
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @20
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @30
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @40
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @50
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @60
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @70
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @74
|
||||
/*
|
||||
* omap1610_cpu_suspend()'s resume point.
|
||||
*
|
||||
* It will just start executing here, so we'll restore stuff from the
|
||||
* stack.
|
||||
*/
|
||||
@ re-enable Icache
|
||||
mcr p15, 0, r9, c1, c0, 0
|
||||
|
||||
@ reset the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
@ Restore the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ -444,7 +517,7 @@ ENTRY(omap1610_cpu_suspend)
|
||||
str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ restore regs and return
|
||||
@ Restore regs and return
|
||||
ldmfd sp!, {r0 - r12, pc}
|
||||
|
||||
ENTRY(omap1610_cpu_suspend_sz)
|
@ -51,8 +51,6 @@
|
||||
|
||||
struct sys_timer omap_timer;
|
||||
|
||||
#ifdef CONFIG_OMAP_MPU_TIMER
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* MPU timer
|
||||
@ -222,195 +220,6 @@ unsigned long long sched_clock(void)
|
||||
|
||||
return cycles_2_ns(ticks64);
|
||||
}
|
||||
#endif /* CONFIG_OMAP_MPU_TIMER */
|
||||
|
||||
#ifdef CONFIG_OMAP_32K_TIMER
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
#error OMAP 32KHz timer does not currently work on 15XX!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* 32KHz OS timer
|
||||
*
|
||||
* This currently works only on 16xx, as 1510 does not have the continuous
|
||||
* 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
|
||||
* of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
|
||||
* on 1510 would be possible, but the timer would not be as accurate as
|
||||
* with the 32KHz synchronized timer.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#define OMAP_32K_TIMER_BASE 0xfffb9000
|
||||
#define OMAP_32K_TIMER_CR 0x08
|
||||
#define OMAP_32K_TIMER_TVR 0x00
|
||||
#define OMAP_32K_TIMER_TCR 0x04
|
||||
|
||||
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
|
||||
|
||||
/*
|
||||
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
|
||||
* so with HZ = 100, TVR = 327.68.
|
||||
*/
|
||||
#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
|
||||
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
|
||||
|
||||
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
|
||||
(((nr_jiffies) * (clock_rate)) / HZ)
|
||||
|
||||
static inline void omap_32k_timer_write(int val, int reg)
|
||||
{
|
||||
omap_writew(val, reg + OMAP_32K_TIMER_BASE);
|
||||
}
|
||||
|
||||
static inline unsigned long omap_32k_timer_read(int reg)
|
||||
{
|
||||
return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 32KHz synchronized timer is an additional timer on 16xx.
|
||||
* It is always running.
|
||||
*/
|
||||
static inline unsigned long omap_32k_sync_timer_read(void)
|
||||
{
|
||||
return omap_readl(TIMER_32K_SYNCHRONIZED);
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_start(unsigned long load_val)
|
||||
{
|
||||
omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
|
||||
omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_stop(void)
|
||||
{
|
||||
omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest usec. Note that this will overflow for larger values.
|
||||
*/
|
||||
static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (ticks_32k * 5*5*5*5*5*5) >> 9;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest nsec.
|
||||
*/
|
||||
static inline unsigned long long
|
||||
omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
|
||||
}
|
||||
|
||||
static unsigned long omap_32k_last_tick = 0;
|
||||
|
||||
/*
|
||||
* Returns elapsed usecs since last 32k timer interrupt
|
||||
*/
|
||||
static unsigned long omap_32k_timer_gettimeoffset(void)
|
||||
{
|
||||
unsigned long now = omap_32k_sync_timer_read();
|
||||
return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns current time from boot in nsecs. It's OK for this to wrap
|
||||
* around for now, as it's just a relative time stamp.
|
||||
*/
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
|
||||
}
|
||||
|
||||
/*
|
||||
* Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
|
||||
* function is also called from other interrupts to remove latency
|
||||
* issues with dynamic tick. In the dynamic tick case, we need to lock
|
||||
* with irqsave.
|
||||
*/
|
||||
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long now;
|
||||
|
||||
write_seqlock_irqsave(&xtime_lock, flags);
|
||||
now = omap_32k_sync_timer_read();
|
||||
|
||||
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
|
||||
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
|
||||
timer_tick(regs);
|
||||
}
|
||||
|
||||
/* Restart timer so we don't drift off due to modulo or dynamic tick.
|
||||
* By default we program the next timer to be continuous to avoid
|
||||
* latencies during high system load. During dynamic tick operation the
|
||||
* continuous timer can be overridden from pm_idle to be longer.
|
||||
*/
|
||||
omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
/*
|
||||
* Programs the next timer interrupt needed. Called when dynamic tick is
|
||||
* enabled, and to reprogram the ticks to skip from pm_idle. Note that
|
||||
* we can keep the timer continuous, and don't need to set it to run in
|
||||
* one-shot mode. This is because the timer will get reprogrammed again
|
||||
* after next interrupt.
|
||||
*/
|
||||
void omap_32k_timer_reprogram(unsigned long next_tick)
|
||||
{
|
||||
omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
|
||||
}
|
||||
|
||||
static struct irqaction omap_32k_timer_irq;
|
||||
extern struct timer_update_handler timer_update;
|
||||
|
||||
static int omap_32k_timer_enable_dyn_tick(void)
|
||||
{
|
||||
/* No need to reprogram timer, just use the next interrupt */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_32k_timer_disable_dyn_tick(void)
|
||||
{
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dyn_tick_timer omap_dyn_tick_timer = {
|
||||
.enable = omap_32k_timer_enable_dyn_tick,
|
||||
.disable = omap_32k_timer_disable_dyn_tick,
|
||||
.reprogram = omap_32k_timer_reprogram,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
#endif /* CONFIG_NO_IDLE_HZ */
|
||||
|
||||
static struct irqaction omap_32k_timer_irq = {
|
||||
.name = "32KHz timer",
|
||||
.flags = SA_INTERRUPT | SA_TIMER,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
|
||||
static __init void omap_init_32k_timer(void)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
omap_timer.dyn_tick = &omap_dyn_tick_timer;
|
||||
#endif
|
||||
|
||||
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
|
||||
omap_timer.offset = omap_32k_timer_gettimeoffset;
|
||||
omap_32k_last_tick = omap_32k_sync_timer_read();
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
}
|
||||
#endif /* CONFIG_OMAP_32K_TIMER */
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
@ -419,13 +228,7 @@ static __init void omap_init_32k_timer(void)
|
||||
*/
|
||||
static void __init omap_timer_init(void)
|
||||
{
|
||||
#if defined(CONFIG_OMAP_MPU_TIMER)
|
||||
omap_init_mpu_timer();
|
||||
#elif defined(CONFIG_OMAP_32K_TIMER)
|
||||
omap_init_32k_timer();
|
||||
#else
|
||||
#error No system timer selected in Kconfig!
|
||||
#endif
|
||||
}
|
||||
|
||||
struct sys_timer omap_timer = {
|
||||
|
@ -20,3 +20,6 @@ config MACH_OMAP_H4
|
||||
bool "OMAP 2420 H4 board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
||||
config MACH_OMAP_APOLLON
|
||||
bool "OMAP 2420 Apollon board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
@ -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
|
||||
|
||||
|
285
arch/arm/mach-omap2/board-apollon.c
Normal file
285
arch/arm/mach-omap2/board-apollon.c
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap/omap2/board-apollon.c
|
||||
*
|
||||
* Copyright (C) 2005,2006 Samsung Electronics
|
||||
* Author: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* Modified from mach-omap/omap2/board-h4.c
|
||||
*
|
||||
* Code for apollon OMAP2 board. Should work on many OMAP2 systems where
|
||||
* the bootloader passes the board-specific data to the kernel.
|
||||
* 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/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/onenand.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
/* LED & Switch macros */
|
||||
#define LED0_GPIO13 13
|
||||
#define LED1_GPIO14 14
|
||||
#define LED2_GPIO15 15
|
||||
#define SW_ENTER_GPIO16 16
|
||||
#define SW_UP_GPIO17 17
|
||||
#define SW_DOWN_GPIO58 58
|
||||
|
||||
static struct mtd_partition apollon_partitions[] = {
|
||||
{
|
||||
.name = "X-Loader + U-Boot",
|
||||
.offset = 0,
|
||||
.size = SZ_128K,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
{
|
||||
.name = "params",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_128K,
|
||||
},
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_2M,
|
||||
},
|
||||
{
|
||||
.name = "rootfs",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_16M,
|
||||
},
|
||||
{
|
||||
.name = "filesystem00",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_32M,
|
||||
},
|
||||
{
|
||||
.name = "filesystem01",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct flash_platform_data apollon_flash_data = {
|
||||
.parts = apollon_partitions,
|
||||
.nr_parts = ARRAY_SIZE(apollon_partitions),
|
||||
};
|
||||
|
||||
static struct resource apollon_flash_resource = {
|
||||
.start = APOLLON_CS0_BASE,
|
||||
.end = APOLLON_CS0_BASE + SZ_128K,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device apollon_onenand_device = {
|
||||
.name = "onenand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &apollon_flash_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(&apollon_flash_resource),
|
||||
.resource = &apollon_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource apollon_smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = APOLLON_ETHR_START, /* Physical */
|
||||
.end = APOLLON_ETHR_START + 0xf,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
|
||||
.end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device apollon_smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(apollon_smc91x_resources),
|
||||
.resource = apollon_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device apollon_lcd_device = {
|
||||
.name = "apollon_lcd",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *apollon_devices[] __initdata = {
|
||||
&apollon_onenand_device,
|
||||
&apollon_smc91x_device,
|
||||
&apollon_lcd_device,
|
||||
};
|
||||
|
||||
static inline void __init apollon_init_smc91x(void)
|
||||
{
|
||||
/* Make sure CS1 timings are correct */
|
||||
GPMC_CONFIG1_1 = 0x00011203;
|
||||
GPMC_CONFIG2_1 = 0x001f1f01;
|
||||
GPMC_CONFIG3_1 = 0x00080803;
|
||||
GPMC_CONFIG4_1 = 0x1c091c09;
|
||||
GPMC_CONFIG5_1 = 0x041f1f1f;
|
||||
GPMC_CONFIG6_1 = 0x000004c4;
|
||||
GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
|
||||
udelay(100);
|
||||
|
||||
omap_cfg_reg(W4__24XX_GPIO74);
|
||||
if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
|
||||
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
|
||||
APOLLON_ETHR_GPIO_IRQ);
|
||||
return;
|
||||
}
|
||||
omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
|
||||
}
|
||||
|
||||
static void __init omap_apollon_init_irq(void)
|
||||
{
|
||||
omap2_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
apollon_init_smc91x();
|
||||
}
|
||||
|
||||
static struct omap_uart_config apollon_uart_config __initdata = {
|
||||
.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
|
||||
};
|
||||
|
||||
static struct omap_mmc_config apollon_mmc_config __initdata = {
|
||||
.mmc [0] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_lcd_config apollon_lcd_config __initdata = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel apollon_config[] = {
|
||||
{ OMAP_TAG_UART, &apollon_uart_config },
|
||||
{ OMAP_TAG_MMC, &apollon_mmc_config },
|
||||
{ OMAP_TAG_LCD, &apollon_lcd_config },
|
||||
};
|
||||
|
||||
static void __init apollon_led_init(void)
|
||||
{
|
||||
/* LED0 - AA10 */
|
||||
omap_cfg_reg(AA10_242X_GPIO13);
|
||||
omap_request_gpio(LED0_GPIO13);
|
||||
omap_set_gpio_direction(LED0_GPIO13, 0);
|
||||
omap_set_gpio_dataout(LED0_GPIO13, 0);
|
||||
/* LED1 - AA6 */
|
||||
omap_cfg_reg(AA6_242X_GPIO14);
|
||||
omap_request_gpio(LED1_GPIO14);
|
||||
omap_set_gpio_direction(LED1_GPIO14, 0);
|
||||
omap_set_gpio_dataout(LED1_GPIO14, 0);
|
||||
/* LED2 - AA4 */
|
||||
omap_cfg_reg(AA4_242X_GPIO15);
|
||||
omap_request_gpio(LED2_GPIO15);
|
||||
omap_set_gpio_direction(LED2_GPIO15, 0);
|
||||
omap_set_gpio_dataout(LED2_GPIO15, 0);
|
||||
}
|
||||
|
||||
static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs)
|
||||
{
|
||||
static unsigned int led0, led1, led2;
|
||||
|
||||
if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16))
|
||||
omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1);
|
||||
else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17))
|
||||
omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1);
|
||||
else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58))
|
||||
omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void __init apollon_sw_init(void)
|
||||
{
|
||||
/* Enter SW - Y11 */
|
||||
omap_cfg_reg(Y11_242X_GPIO16);
|
||||
omap_request_gpio(SW_ENTER_GPIO16);
|
||||
omap_set_gpio_direction(SW_ENTER_GPIO16, 1);
|
||||
/* Up SW - AA12 */
|
||||
omap_cfg_reg(AA12_242X_GPIO17);
|
||||
omap_request_gpio(SW_UP_GPIO17);
|
||||
omap_set_gpio_direction(SW_UP_GPIO17, 1);
|
||||
/* Down SW - AA8 */
|
||||
omap_cfg_reg(AA8_242X_GPIO58);
|
||||
omap_request_gpio(SW_DOWN_GPIO58);
|
||||
omap_set_gpio_direction(SW_DOWN_GPIO58, 1);
|
||||
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "enter sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "up sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "down sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
}
|
||||
|
||||
static void __init omap_apollon_init(void)
|
||||
{
|
||||
apollon_led_init();
|
||||
apollon_sw_init();
|
||||
|
||||
/* REVISIT: where's the correct place */
|
||||
omap_cfg_reg(W19_24XX_SYS_NIRQ);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
|
||||
omap_board_config = apollon_config;
|
||||
omap_board_config_size = ARRAY_SIZE(apollon_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init omap_apollon_map_io(void)
|
||||
{
|
||||
omap2_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
|
||||
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
.map_io = omap_apollon_map_io,
|
||||
.init_irq = omap_apollon_init_irq,
|
||||
.init_machine = omap_apollon_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
@ -17,6 +17,8 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -25,15 +27,57 @@
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/gpioexpander.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/prcm.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/menelaus.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
|
||||
static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
|
||||
|
||||
static int h4_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_A),
|
||||
KEY(0, 3, KEY_B),
|
||||
KEY(0, 4, KEY_C),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_E),
|
||||
KEY(1, 3, KEY_F),
|
||||
KEY(1, 4, KEY_G),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_I),
|
||||
KEY(2, 2, KEY_J),
|
||||
KEY(2, 3, KEY_K),
|
||||
KEY(2, 4, KEY_3),
|
||||
KEY(3, 0, KEY_M),
|
||||
KEY(3, 1, KEY_N),
|
||||
KEY(3, 2, KEY_O),
|
||||
KEY(3, 3, KEY_P),
|
||||
KEY(3, 4, KEY_Q),
|
||||
KEY(4, 0, KEY_R),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_T),
|
||||
KEY(4, 3, KEY_U),
|
||||
KEY(4, 4, KEY_ENTER),
|
||||
KEY(5, 0, KEY_V),
|
||||
KEY(5, 1, KEY_W),
|
||||
KEY(5, 2, KEY_L),
|
||||
KEY(5, 3, KEY_S),
|
||||
KEY(5, 4, KEY_ENTER),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition h4_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -108,9 +152,123 @@ static struct platform_device h4_smc91x_device = {
|
||||
.resource = h4_smc91x_resources,
|
||||
};
|
||||
|
||||
/* Select between the IrDA and aGPS module
|
||||
*/
|
||||
static int h4_select_irda(struct device *dev, int state)
|
||||
{
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x21))) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 'P6' enable/disable IRDA_TX and IRDA_RX */
|
||||
if (state & IR_SEL) { /* IrDa */
|
||||
if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void set_trans_mode(void *data)
|
||||
{
|
||||
int *mode = data;
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
}
|
||||
|
||||
expa &= ~0x01;
|
||||
|
||||
if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */
|
||||
expa |= 0x01;
|
||||
}
|
||||
|
||||
if ((err = write_gpio_expa(expa, 0x20)) != 0) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int h4_transceiver_mode(struct device *dev, int mode)
|
||||
{
|
||||
struct omap_irda_config *irda_config = dev->platform_data;
|
||||
|
||||
cancel_delayed_work(&irda_config->gpio_expa);
|
||||
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
|
||||
schedule_work(&irda_config->gpio_expa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct omap_irda_config h4_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.transceiver_mode = h4_transceiver_mode,
|
||||
.select_irda = h4_select_irda,
|
||||
.rx_channel = OMAP24XX_DMA_UART3_RX,
|
||||
.tx_channel = OMAP24XX_DMA_UART3_TX,
|
||||
.dest_start = OMAP_UART3_BASE,
|
||||
.src_start = OMAP_UART3_BASE,
|
||||
.tx_trigger = OMAP24XX_DMA_UART3_TX,
|
||||
.rx_trigger = OMAP24XX_DMA_UART3_RX,
|
||||
};
|
||||
|
||||
static struct resource h4_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_24XX_UART3_IRQ,
|
||||
.end = INT_24XX_UART3_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h4_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h4_irda_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = h4_irda_resources,
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h4_kp_data = {
|
||||
.rows = 6,
|
||||
.cols = 7,
|
||||
.keymap = h4_keymap,
|
||||
.rep = 1,
|
||||
.row_gpios = row_gpios,
|
||||
.col_gpios = col_gpios,
|
||||
};
|
||||
|
||||
static struct platform_device h4_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h4_kp_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h4_lcd_device = {
|
||||
.name = "lcd_h4",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *h4_devices[] __initdata = {
|
||||
&h4_smc91x_device,
|
||||
&h4_flash_device,
|
||||
&h4_irda_device,
|
||||
&h4_kp_device,
|
||||
&h4_lcd_device,
|
||||
};
|
||||
|
||||
static inline void __init h4_init_smc91x(void)
|
||||
@ -157,7 +315,6 @@ static struct omap_mmc_config h4_mmc_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h4_lcd_config __initdata = {
|
||||
.panel_name = "h4",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -174,6 +331,19 @@ static void __init omap_h4_init(void)
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
omap_cfg_reg(K15_24XX_UART3_TX);
|
||||
omap_cfg_reg(K14_24XX_UART3_RX);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
|
||||
if (omap_has_menelaus()) {
|
||||
row_gpios[5] = 0;
|
||||
col_gpios[2] = 15;
|
||||
col_gpios[6] = 18;
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
|
||||
omap_board_config = h4_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h4_config);
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/prcm.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
#include "memory.h"
|
||||
#include "clock.h"
|
||||
|
||||
//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
|
||||
|
||||
static struct prcm_config *curr_prcm_set;
|
||||
static struct memory_timings mem_timings;
|
||||
static u32 curr_perf_level = PRCM_FULL_SPEED;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -54,11 +54,13 @@ static void omap2_sys_clk_recalc(struct clk * clk)
|
||||
|
||||
static u32 omap2_get_dpll_rate(struct clk * tclk)
|
||||
{
|
||||
int dpll_clk, dpll_mult, dpll_div, amult;
|
||||
long long dpll_clk;
|
||||
int dpll_mult, dpll_div, amult;
|
||||
|
||||
dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */
|
||||
dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */
|
||||
dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
|
||||
dpll_clk = (long long)tclk->parent->rate * dpll_mult;
|
||||
do_div(dpll_clk, dpll_div + 1);
|
||||
amult = CM_CLKSEL2_PLL & 0x3;
|
||||
dpll_clk *= amult;
|
||||
|
||||
@ -385,75 +387,23 @@ static u32 omap2_dll_force_needed(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
|
||||
{
|
||||
unsigned long dll_cnt;
|
||||
u32 fast_dll = 0;
|
||||
|
||||
mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
|
||||
|
||||
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
|
||||
* In the case of 2422, its ok to use CS1 instead of CS0.
|
||||
*/
|
||||
|
||||
#if 0 /* FIXME: Enable after 24xx cpu detection works */
|
||||
ctype = get_cpu_type();
|
||||
if (cpu_is_omap2422())
|
||||
mem_timings.base_cs = 1;
|
||||
else
|
||||
#endif
|
||||
mem_timings.base_cs = 0;
|
||||
|
||||
if (mem_timings.m_type != M_DDR)
|
||||
return;
|
||||
|
||||
/* With DDR we need to determine the low frequency DLL value */
|
||||
if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
|
||||
mem_timings.dll_mode = M_UNLOCK;
|
||||
else
|
||||
mem_timings.dll_mode = M_LOCK;
|
||||
|
||||
if (mem_timings.base_cs == 0) {
|
||||
fast_dll = SDRC_DLLA_CTRL;
|
||||
dll_cnt = SDRC_DLLA_STATUS & 0xff00;
|
||||
} else {
|
||||
fast_dll = SDRC_DLLB_CTRL;
|
||||
dll_cnt = SDRC_DLLB_STATUS & 0xff00;
|
||||
}
|
||||
if (force_lock_to_unlock_mode) {
|
||||
fast_dll &= ~0xff00;
|
||||
fast_dll |= dll_cnt; /* Current lock mode */
|
||||
}
|
||||
mem_timings.fast_dll_ctrl = fast_dll;
|
||||
|
||||
/* No disruptions, DDR will be offline & C-ABI not followed */
|
||||
omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.base_cs,
|
||||
force_lock_to_unlock_mode);
|
||||
mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
|
||||
|
||||
/* Turn status into unlock ctrl */
|
||||
mem_timings.slow_dll_ctrl |=
|
||||
((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
|
||||
|
||||
/* 90 degree phase for anything below 133Mhz */
|
||||
mem_timings.slow_dll_ctrl |= (1 << 1);
|
||||
}
|
||||
|
||||
static u32 omap2_reprogram_sdrc(u32 level, u32 force)
|
||||
{
|
||||
u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
|
||||
u32 prev = curr_perf_level, flags;
|
||||
|
||||
if ((curr_perf_level == level) && !force)
|
||||
return prev;
|
||||
|
||||
m_type = omap2_memory_get_type();
|
||||
slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
|
||||
fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
|
||||
|
||||
if (level == PRCM_HALF_SPEED) {
|
||||
local_irq_save(flags);
|
||||
PRCM_VOLTSETUP = 0xffff;
|
||||
omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
|
||||
mem_timings.slow_dll_ctrl,
|
||||
mem_timings.m_type);
|
||||
slow_dll_ctrl, m_type);
|
||||
curr_perf_level = PRCM_HALF_SPEED;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@ -461,8 +411,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force)
|
||||
local_irq_save(flags);
|
||||
PRCM_VOLTSETUP = 0xffff;
|
||||
omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.m_type);
|
||||
fast_dll_ctrl, m_type);
|
||||
curr_perf_level = PRCM_FULL_SPEED;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@ -650,7 +599,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
|
||||
case 13: /* dss2 */
|
||||
mask = 0x1; break;
|
||||
case 25: /* usb */
|
||||
mask = 0xf; break;
|
||||
mask = 0x7; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,20 +33,6 @@ static u32 omap2_clksel_get_divisor(struct clk *clk);
|
||||
#define RATE_IN_242X (1 << 0)
|
||||
#define RATE_IN_243X (1 << 1)
|
||||
|
||||
/* Memory timings */
|
||||
#define M_DDR 1
|
||||
#define M_LOCK_CTRL (1 << 2)
|
||||
#define M_UNLOCK 0
|
||||
#define M_LOCK 1
|
||||
|
||||
struct memory_timings {
|
||||
u32 m_type; /* ddr = 1, sdr = 0 */
|
||||
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
|
||||
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
|
||||
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
|
||||
u32 base_cs; /* base chip select to use for calculations */
|
||||
};
|
||||
|
||||
/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
|
||||
* xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
|
||||
* CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
|
||||
@ -731,6 +717,16 @@ static struct clk sys_clkout2 = {
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk emul_ck = {
|
||||
.name = "emul_ck",
|
||||
.parent = &func_54m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X,
|
||||
.enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL,
|
||||
.enable_bit = 0,
|
||||
.recalc = &omap2_propagate_rate,
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* MPU clock domain
|
||||
* Clocks:
|
||||
@ -1702,7 +1698,8 @@ static struct clk hdq_fck = {
|
||||
};
|
||||
|
||||
static struct clk i2c2_ick = {
|
||||
.name = "i2c2_ick",
|
||||
.name = "i2c_ick",
|
||||
.id = 2,
|
||||
.parent = &l4_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
|
||||
@ -1711,7 +1708,8 @@ static struct clk i2c2_ick = {
|
||||
};
|
||||
|
||||
static struct clk i2c2_fck = {
|
||||
.name = "i2c2_fck",
|
||||
.name = "i2c_fck",
|
||||
.id = 2,
|
||||
.parent = &func_12m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
|
||||
@ -1729,7 +1727,8 @@ static struct clk i2chs2_fck = {
|
||||
};
|
||||
|
||||
static struct clk i2c1_ick = {
|
||||
.name = "i2c1_ick",
|
||||
.name = "i2c_ick",
|
||||
.id = 1,
|
||||
.parent = &l4_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
|
||||
@ -1738,7 +1737,8 @@ static struct clk i2c1_ick = {
|
||||
};
|
||||
|
||||
static struct clk i2c1_fck = {
|
||||
.name = "i2c1_fck",
|
||||
.name = "i2c_fck",
|
||||
.id = 1,
|
||||
.parent = &func_12m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
|
||||
@ -1971,6 +1971,7 @@ static struct clk *onchip_clks[] = {
|
||||
&wdt1_osc_ck,
|
||||
&sys_clkout,
|
||||
&sys_clkout2,
|
||||
&emul_ck,
|
||||
/* mpu domain clocks */
|
||||
&mpu_ck,
|
||||
/* dsp domain clocks */
|
||||
|
@ -74,6 +74,47 @@ static void omap_init_i2c(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_STI)
|
||||
|
||||
#define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
|
||||
#define OMAP2_STI_CHANNEL_BASE 0x54000000
|
||||
#define OMAP2_STI_IRQ 4
|
||||
|
||||
static struct resource sti_resources[] = {
|
||||
{
|
||||
.start = OMAP2_STI_BASE,
|
||||
.end = OMAP2_STI_BASE + 0x7ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP2_STI_CHANNEL_BASE,
|
||||
.end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP2_STI_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sti_device = {
|
||||
.name = "sti",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(sti_resources),
|
||||
.resource = sti_resources,
|
||||
};
|
||||
|
||||
static inline void omap_init_sti(void)
|
||||
{
|
||||
platform_device_register(&sti_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init omap2_init_devices(void)
|
||||
@ -82,6 +123,7 @@ static int __init omap2_init_devices(void)
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_i2c();
|
||||
omap_init_sti();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
102
arch/arm/mach-omap2/memory.c
Normal file
102
arch/arm/mach-omap2/memory.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/memory.c
|
||||
*
|
||||
* Memory timing related functions for OMAP24XX
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
#include "memory.h"
|
||||
|
||||
static struct memory_timings mem_timings;
|
||||
|
||||
u32 omap2_memory_get_slow_dll_ctrl(void)
|
||||
{
|
||||
return mem_timings.slow_dll_ctrl;
|
||||
}
|
||||
|
||||
u32 omap2_memory_get_fast_dll_ctrl(void)
|
||||
{
|
||||
return mem_timings.fast_dll_ctrl;
|
||||
}
|
||||
|
||||
u32 omap2_memory_get_type(void)
|
||||
{
|
||||
return mem_timings.m_type;
|
||||
}
|
||||
|
||||
void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
|
||||
{
|
||||
unsigned long dll_cnt;
|
||||
u32 fast_dll = 0;
|
||||
|
||||
mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
|
||||
|
||||
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
|
||||
* In the case of 2422, its ok to use CS1 instead of CS0.
|
||||
*/
|
||||
if (cpu_is_omap2422())
|
||||
mem_timings.base_cs = 1;
|
||||
else
|
||||
mem_timings.base_cs = 0;
|
||||
|
||||
if (mem_timings.m_type != M_DDR)
|
||||
return;
|
||||
|
||||
/* With DDR we need to determine the low frequency DLL value */
|
||||
if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
|
||||
mem_timings.dll_mode = M_UNLOCK;
|
||||
else
|
||||
mem_timings.dll_mode = M_LOCK;
|
||||
|
||||
if (mem_timings.base_cs == 0) {
|
||||
fast_dll = SDRC_DLLA_CTRL;
|
||||
dll_cnt = SDRC_DLLA_STATUS & 0xff00;
|
||||
} else {
|
||||
fast_dll = SDRC_DLLB_CTRL;
|
||||
dll_cnt = SDRC_DLLB_STATUS & 0xff00;
|
||||
}
|
||||
if (force_lock_to_unlock_mode) {
|
||||
fast_dll &= ~0xff00;
|
||||
fast_dll |= dll_cnt; /* Current lock mode */
|
||||
}
|
||||
/* set fast timings with DLL filter disabled */
|
||||
mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
|
||||
|
||||
/* No disruptions, DDR will be offline & C-ABI not followed */
|
||||
omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.base_cs,
|
||||
force_lock_to_unlock_mode);
|
||||
mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
|
||||
|
||||
/* Turn status into unlock ctrl */
|
||||
mem_timings.slow_dll_ctrl |=
|
||||
((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
|
||||
|
||||
/* 90 degree phase for anything below 133Mhz + disable DLL filter */
|
||||
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
|
||||
}
|
34
arch/arm/mach-omap2/memory.h
Normal file
34
arch/arm/mach-omap2/memory.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/memory.h
|
||||
*
|
||||
* Interface for memory timing related functions for OMAP24XX
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/* Memory timings */
|
||||
#define M_DDR 1
|
||||
#define M_LOCK_CTRL (1 << 2)
|
||||
#define M_UNLOCK 0
|
||||
#define M_LOCK 1
|
||||
|
||||
struct memory_timings {
|
||||
u32 m_type; /* ddr = 1, sdr = 0 */
|
||||
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
|
||||
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
|
||||
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
|
||||
u32 base_cs; /* base chip select to use for calculations */
|
||||
};
|
||||
|
||||
extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
|
||||
extern u32 omap2_memory_get_slow_dll_ctrl(void);
|
||||
extern u32 omap2_memory_get_fast_dll_ctrl(void);
|
||||
extern u32 omap2_memory_get_type(void);
|
@ -50,9 +50,54 @@ MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
|
||||
/* Menelaus interrupt */
|
||||
MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
|
||||
|
||||
/* 24xx clocks */
|
||||
MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
|
||||
|
||||
/* 24xx McBSP */
|
||||
MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
|
||||
|
||||
/* 24xx GPIO */
|
||||
MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
|
||||
|
||||
/* TSC IRQ */
|
||||
MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
|
||||
|
||||
/* UART3 */
|
||||
MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
|
||||
MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
|
||||
|
||||
/* Keypad GPIO*/
|
||||
MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1)
|
||||
|
||||
/* 24xx Menelaus Keypad GPIO */
|
||||
MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1)
|
||||
|
||||
};
|
||||
|
||||
|
149
arch/arm/mach-omap2/pm.c
Normal file
149
arch/arm/mach-omap2/pm.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/pm.c
|
||||
*
|
||||
* OMAP2 Power Management Routines
|
||||
*
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments, Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Based on pm.c for omap1
|
||||
*
|
||||
* 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/pm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/pm.h>
|
||||
|
||||
static struct clk *vclk;
|
||||
static void (*omap2_sram_idle)(void);
|
||||
static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
|
||||
static void (*saved_idle)(void);
|
||||
|
||||
void omap2_pm_idle(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
if (need_resched()) {
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since an interrupt may set up a timer, we don't want to
|
||||
* reprogram the hardware timer with interrupts enabled.
|
||||
* Re-enable interrupts only after returning from idle.
|
||||
*/
|
||||
timer_dyn_reprogram();
|
||||
|
||||
omap2_sram_idle();
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static int omap2_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* We cannot sleep in idle until we have resumed */
|
||||
saved_idle = pm_idle;
|
||||
pm_idle = NULL;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int omap2_pm_enter(suspend_state_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
/* FIXME: Add suspend */
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_pm_finish(suspend_state_t state)
|
||||
{
|
||||
pm_idle = saved_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pm_ops omap_pm_ops = {
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap2_pm_prepare,
|
||||
.enter = omap2_pm_enter,
|
||||
.finish = omap2_pm_finish,
|
||||
};
|
||||
|
||||
int __init omap2_pm_init(void)
|
||||
{
|
||||
printk("Power Management for TI OMAP.\n");
|
||||
|
||||
vclk = clk_get(NULL, "virt_prcm_set");
|
||||
if (IS_ERR(vclk)) {
|
||||
printk(KERN_ERR "Could not get PM vclk\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* We copy the assembler sleep/wakeup routines to SRAM.
|
||||
* These routines need to be in SRAM as that's the only
|
||||
* memory the MPU can see when it wakes up.
|
||||
*/
|
||||
omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
|
||||
omap24xx_idle_loop_suspend_sz);
|
||||
|
||||
omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
|
||||
omap24xx_cpu_suspend_sz);
|
||||
|
||||
pm_set_ops(&omap_pm_ops);
|
||||
pm_idle = omap2_pm_idle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(omap2_pm_init);
|
@ -1,5 +1,7 @@
|
||||
/*
|
||||
* prcm.h - Access definations for use in OMAP24XX clock and power management
|
||||
* linux/arch/arm/mach-omap2/prcm-reg.h
|
||||
*
|
||||
* OMAP24XX Power Reset and Clock Management (PRCM) registers
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments, Inc.
|
||||
*
|
||||
@ -18,8 +20,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
#define __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_PRCM_H
|
||||
|
||||
/* SET_PERFORMANCE_LEVEL PARAMETERS */
|
||||
#define PRCM_HALF_SPEED 1
|
||||
@ -159,54 +161,63 @@
|
||||
#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
|
||||
#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
|
||||
#define CM_IDLEST_MDM PRCM_REG32(0xC20)
|
||||
#define CM_AUTOIDLE_MDM PRCM_REG32(0xC30)
|
||||
#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
|
||||
#define CM_CLKSTCTRL_MDM PRCM_REG32(0xC48)
|
||||
#define RM_RSTCTRL_MDM PRCM_REG32(0xC50)
|
||||
#define RM_RSTST_MDM PRCM_REG32(0xC58)
|
||||
#define PM_WKEN_MDM PRCM_REG32(0xCA0)
|
||||
#define PM_WKST_MDM PRCM_REG32(0xCB0)
|
||||
#define PM_WKDEP_MDM PRCM_REG32(0xCC8)
|
||||
#define PM_PWSTCTRL_MDM PRCM_REG32(0xCE0)
|
||||
#define PM_PWSTST_MDM PRCM_REG32(0xCE4)
|
||||
|
||||
/* FIXME: Move to header for 2430 */
|
||||
#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
|
||||
#define OMAP24XX_L4_IO_BASE 0x48000000
|
||||
|
||||
#define DISP_BASE (OMAP24XX_L4_IO_BASE + 0x50000)
|
||||
#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
|
||||
|
||||
#define GPMC_BASE (OMAP24XX_GPMC_BASE)
|
||||
#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
|
||||
#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
|
||||
#define GPMC_REG32(offset) __REG32(OMAP24XX_GPMC_BASE + (offset))
|
||||
|
||||
#define GPT1_BASE (OMAP24XX_GPT1)
|
||||
/* FIXME: Move these to timer code */
|
||||
#define GPT1_BASE (0x48028000)
|
||||
#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
|
||||
|
||||
/* Misc sysconfig */
|
||||
#define DISPC_SYSCONFIG DISP_REG32(0x410)
|
||||
#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
|
||||
#define SPI_BASE (OMAP24XX_L4_IO_BASE + 0x98000)
|
||||
#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
|
||||
#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
|
||||
#define MCSPI2_SYSCONFIG __REG32(SPI_BASE + 0x2000 + 0x10)
|
||||
#define MCSPI3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0xb8010)
|
||||
|
||||
//#define DSP_MMU_SYSCONFIG 0x5A000010
|
||||
#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
|
||||
//#define IVA_MMU_SYSCONFIG 0x5D000010
|
||||
//#define DSP_DMA_SYSCONFIG 0x00FCC02C
|
||||
#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
|
||||
#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
|
||||
#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE + 0x2C10)
|
||||
#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE + 0x282C)
|
||||
#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE + 0x602C)
|
||||
#define GPMC_SYSCONFIG GPMC_REG32(0x010)
|
||||
#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
|
||||
#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
|
||||
#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
|
||||
#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
|
||||
//#define IVA_SYSCONFIG 0x5C060010
|
||||
#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
|
||||
#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
|
||||
#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
|
||||
//#define VLYNQ_SYSCONFIG 0x67FFFE10
|
||||
#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x94010)
|
||||
#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6A054)
|
||||
#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6C054)
|
||||
#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6E054)
|
||||
#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE + 0x10)
|
||||
#define OMAP24XX_SMS_BASE (L3_24XX_BASE + 0x8000)
|
||||
#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE + 0x10)
|
||||
#define SSI_SYSCONFIG __REG32(DISP_BASE + 0x8010)
|
||||
|
||||
/* rkw - good cannidates for PM_ to start what nm was trying */
|
||||
#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
|
||||
#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
|
||||
#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
|
||||
#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
|
||||
#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
|
||||
#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
|
||||
#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
|
||||
#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
|
||||
#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
|
||||
#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
|
||||
#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
|
||||
#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE + 0x2A000)
|
||||
#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE + 0x78000)
|
||||
#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE + 0x7A000)
|
||||
#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE + 0x7C000)
|
||||
#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE + 0x7E000)
|
||||
#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE + 0x80000)
|
||||
#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE + 0x82000)
|
||||
#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE + 0x84000)
|
||||
#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE + 0x86000)
|
||||
#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE + 0x88000)
|
||||
#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE + 0x8A000)
|
||||
|
||||
/* FIXME: Move these to timer code */
|
||||
#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
|
||||
#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
|
||||
#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
|
||||
@ -220,12 +231,18 @@
|
||||
#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
|
||||
#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
|
||||
|
||||
#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
|
||||
/* FIXME: Move these to gpio code */
|
||||
#define OMAP24XX_GPIO_BASE 0x48018000
|
||||
#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1)))
|
||||
|
||||
#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
|
||||
#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
|
||||
#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
|
||||
#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
|
||||
#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1) + 0x10))
|
||||
#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2) + 0x10))
|
||||
#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3) + 0x10))
|
||||
#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4) + 0x10))
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP243X)
|
||||
#define GPIO5_SYSCONFIG __REG32((OMAP24XX_GPIO5_BASE + 0x10))
|
||||
#endif
|
||||
|
||||
/* GP TIMER 1 */
|
||||
#define GPTIMER1_TISTAT GPT1_REG32(0x014)
|
||||
@ -243,15 +260,15 @@
|
||||
#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
|
||||
|
||||
/* rkw -- base fix up please... */
|
||||
#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
|
||||
#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE + 0x78018)
|
||||
|
||||
/* SDRC */
|
||||
#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
|
||||
#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
|
||||
#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
|
||||
#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
|
||||
#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
|
||||
#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
|
||||
#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x060)
|
||||
#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x064)
|
||||
#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x068)
|
||||
#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x06C)
|
||||
#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE + 0x070)
|
||||
#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE + 0x084)
|
||||
|
||||
/* GPIO 1 */
|
||||
#define GPIO1_BASE GPIOX_BASE(1)
|
||||
@ -278,6 +295,8 @@
|
||||
#define GPIO2_DATAIN GPIO2_REG32(0x038)
|
||||
#define GPIO2_OE GPIO2_REG32(0x034)
|
||||
#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
|
||||
#define GPIO2_DEBOUNCENABLE GPIO2_REG32(0x050)
|
||||
#define GPIO2_DEBOUNCINGTIME GPIO2_REG32(0x054)
|
||||
|
||||
/* GPIO 3 */
|
||||
#define GPIO3_BASE GPIOX_BASE(3)
|
||||
@ -294,6 +313,8 @@
|
||||
#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
|
||||
#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
|
||||
#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
|
||||
#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
|
||||
#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
|
||||
|
||||
/* GPIO 4 */
|
||||
#define GPIO4_BASE GPIOX_BASE(4)
|
||||
@ -311,10 +332,26 @@
|
||||
#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
|
||||
#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP243X)
|
||||
/* GPIO 5 */
|
||||
#define GPIO5_REG32(offset) __REG32((OMAP24XX_GPIO5_BASE + (offset)))
|
||||
#define GPIO5_IRQENABLE1 GPIO5_REG32(0x01C)
|
||||
#define GPIO5_IRQSTATUS1 GPIO5_REG32(0x018)
|
||||
#define GPIO5_IRQENABLE2 GPIO5_REG32(0x02C)
|
||||
#define GPIO5_IRQSTATUS2 GPIO5_REG32(0x028)
|
||||
#define GPIO5_WAKEUPENABLE GPIO5_REG32(0x020)
|
||||
#define GPIO5_RISINGDETECT GPIO5_REG32(0x048)
|
||||
#define GPIO5_FALLINGDETECT GPIO5_REG32(0x04C)
|
||||
#define GPIO5_DATAIN GPIO5_REG32(0x038)
|
||||
#define GPIO5_OE GPIO5_REG32(0x034)
|
||||
#define GPIO5_DATAOUT GPIO5_REG32(0x03C)
|
||||
#define GPIO5_DEBOUNCENABLE GPIO5_REG32(0x050)
|
||||
#define GPIO5_DEBOUNCINGTIME GPIO5_REG32(0x054)
|
||||
#endif
|
||||
|
||||
/* IO CONFIG */
|
||||
#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
|
||||
#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
|
||||
#define OMAP24XX_CTRL_BASE (L4_24XX_BASE)
|
||||
#define CONTROL_REG32(offset) __REG32(OMAP24XX_CTRL_BASE + (offset))
|
||||
|
||||
#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
|
||||
#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
|
||||
@ -322,15 +359,18 @@
|
||||
#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
|
||||
#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
|
||||
#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
|
||||
#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
|
||||
#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) /* 2420 */
|
||||
#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
|
||||
#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
|
||||
#define CONTROL_PADCONF_SYS_NIRQW0 CONTROL_REG32(0x0BC) /* 2430 */
|
||||
#define CONTROL_PADCONF_SSI1_FLAG_TX CONTROL_REG32(0x108) /* 2430 */
|
||||
|
||||
/* CONTROL */
|
||||
#define CONTROL_DEVCONF CONTROL_REG32(0x274)
|
||||
#define CONTROL_DEVCONF1 CONTROL_REG32(0x2E8)
|
||||
|
||||
/* INTERRUPT CONTROLLER */
|
||||
#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
|
||||
#define INTC_BASE ((L4_24XX_BASE) + 0xfe000)
|
||||
#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
|
||||
|
||||
#define INTC1_U_BASE INTC_REG32(0x000)
|
||||
@ -348,10 +388,12 @@
|
||||
#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
|
||||
#define INTC_SIR_IRQ INTC_REG32(0x040)
|
||||
#define INTC_CONTROL INTC_REG32(0x048)
|
||||
#define INTC_ILR11 INTC_REG32(0x12C)
|
||||
#define INTC_ILR11 INTC_REG32(0x12C) /* PRCM on MPU PIC */
|
||||
#define INTC_ILR30 INTC_REG32(0x178)
|
||||
#define INTC_ILR31 INTC_REG32(0x17C)
|
||||
#define INTC_ILR32 INTC_REG32(0x180)
|
||||
#define INTC_ILR37 INTC_REG32(0x194)
|
||||
#define INTC_SYSCONFIG INTC_REG32(0x010)
|
||||
#define INTC_ILR37 INTC_REG32(0x194) /* GPIO4 on MPU PIC */
|
||||
#define INTC_SYSCONFIG INTC_REG32(0x010) /* GPT1 on MPU PIC */
|
||||
|
||||
/* RAM FIREWALL */
|
||||
#define RAMFW_BASE (0x68005000)
|
||||
@ -373,6 +415,24 @@
|
||||
#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
|
||||
#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
|
||||
|
||||
/* GPMC CS1 */
|
||||
#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
|
||||
#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
|
||||
#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
|
||||
#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
|
||||
#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
|
||||
#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
|
||||
#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
|
||||
|
||||
/* GPMC CS3 */
|
||||
#define GPMC_CONFIG1_3 GPMC_REG32(0x0F0)
|
||||
#define GPMC_CONFIG2_3 GPMC_REG32(0x0F4)
|
||||
#define GPMC_CONFIG3_3 GPMC_REG32(0x0F8)
|
||||
#define GPMC_CONFIG4_3 GPMC_REG32(0x0FC)
|
||||
#define GPMC_CONFIG5_3 GPMC_REG32(0x100)
|
||||
#define GPMC_CONFIG6_3 GPMC_REG32(0x104)
|
||||
#define GPMC_CONFIG7_3 GPMC_REG32(0x108)
|
||||
|
||||
/* DSS */
|
||||
#define DSS_CONTROL DISP_REG32(0x040)
|
||||
#define DISPC_CONTROL DISP_REG32(0x440)
|
||||
@ -405,11 +465,15 @@
|
||||
#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
|
||||
#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
|
||||
|
||||
/* Wake up define for board */
|
||||
#define GPIO97 (1 << 1)
|
||||
#define GPIO88 (1 << 24)
|
||||
/* HSUSB Suspend */
|
||||
#define HSUSB_CTRL __REG8(0x480AC001)
|
||||
#define USBOTG_POWER __REG32(0x480AC000)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
/* HS MMC */
|
||||
#define MMCHS1_SYSCONFIG __REG32(0x4809C010)
|
||||
#define MMCHS2_SYSCONFIG __REG32(0x480b4010)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif
|
||||
|
40
arch/arm/mach-omap2/prcm.c
Normal file
40
arch/arm/mach-omap2/prcm.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/prcm.c
|
||||
*
|
||||
* OMAP 24xx Power Reset and Clock Management (PRCM) functions
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren <tony.lindgren@nokia.com>
|
||||
*
|
||||
* Some pieces of code Copyright (C) 2005 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
|
||||
u32 omap_prcm_get_reset_sources(void)
|
||||
{
|
||||
return RM_RSTST_WKUP & 0x7f;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
|
||||
|
||||
/* Resets clock rates and reboots the system. Only called from system.h */
|
||||
void omap_prcm_arch_reset(char mode)
|
||||
{
|
||||
u32 rate;
|
||||
struct clk *vclk, *sclk;
|
||||
|
||||
vclk = clk_get(NULL, "virt_prcm_set");
|
||||
sclk = clk_get(NULL, "sys_ck");
|
||||
rate = clk_get_rate(sclk);
|
||||
clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
|
||||
RM_RSTCTRL_WKUP |= 2;
|
||||
}
|
144
arch/arm/mach-omap2/sleep.S
Normal file
144
arch/arm/mach-omap2/sleep.S
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/sleep.S
|
||||
*
|
||||
* (C) Copyright 2004
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Richard Woodruff <r-woodruff2@ti.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 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
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/arch/io.h>
|
||||
#include <asm/arch/pm.h>
|
||||
|
||||
#define A_32KSYNC_CR_V IO_ADDRESS(OMAP_TIMER32K_BASE+0x10)
|
||||
#define A_PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50)
|
||||
#define A_PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80)
|
||||
#define A_CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500)
|
||||
#define A_CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520)
|
||||
#define A_CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540)
|
||||
#define A_CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544)
|
||||
|
||||
#define A_SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60)
|
||||
#define A_SDRC_POWER_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70)
|
||||
#define A_SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4)
|
||||
#define A_SDRC0_V (0xC0000000)
|
||||
#define A_SDRC_MANUAL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8)
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* Forces OMAP into idle state
|
||||
*
|
||||
* omap24xx_idle_loop_suspend() - This bit of code just executes the WFI
|
||||
* for normal idles.
|
||||
*
|
||||
* Note: This code get's copied to internal SRAM at boot. When the OMAP
|
||||
* wakes up it continues execution at the point it went to sleep.
|
||||
*/
|
||||
ENTRY(omap24xx_idle_loop_suspend)
|
||||
stmfd sp!, {r0, lr} @ save registers on stack
|
||||
mov r0, #0 @ clear for mcr setup
|
||||
mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
|
||||
ldmfd sp!, {r0, pc} @ restore regs and return
|
||||
|
||||
ENTRY(omap24xx_idle_loop_suspend_sz)
|
||||
.word . - omap24xx_idle_loop_suspend
|
||||
|
||||
/*
|
||||
* omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
|
||||
* SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore
|
||||
* SDRC.
|
||||
*
|
||||
* Input:
|
||||
* R0 : DLL ctrl value pre-Sleep
|
||||
* R1 : Processor+Revision
|
||||
* 2420: 0x21 = 242xES1, 0x26 = 242xES2.2
|
||||
* 2430: 0x31 = 2430ES1, 0x32 = 2430ES2
|
||||
*
|
||||
* The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
|
||||
* when we get called, but the DLL probably isn't. We will wait a bit more in
|
||||
* case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
|
||||
* if in unlocked mode.
|
||||
*
|
||||
* For less than 242x-ES2.2 upon wake from a sleep mode where the external
|
||||
* oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
|
||||
* clock can pass into the PRCM can cause problems at DSP and IVA.
|
||||
* To work around this the code will switch to the 32kHz source prior to sleep.
|
||||
* Post sleep we will shift back to using the DPLL. Apparently,
|
||||
* CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
|
||||
* 3x12MHz + 3x32kHz clocks for a full switch.
|
||||
*
|
||||
* The DLL load value is not kept in RETENTION or OFF. It needs to be restored
|
||||
* at wake
|
||||
*/
|
||||
ENTRY(omap24xx_cpu_suspend)
|
||||
stmfd sp!, {r0 - r12, lr} @ save registers on stack
|
||||
mov r3, #0x0 @ clear for mrc call
|
||||
mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
|
||||
nop
|
||||
nop
|
||||
ldr r3, A_SDRC_POWER @ addr of sdrc power
|
||||
ldr r4, [r3] @ value of sdrc power
|
||||
orr r4, r4, #0x40 @ enable self refresh on idle req
|
||||
mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
|
||||
str r4, [r3] @ make it so
|
||||
mov r2, #0
|
||||
nop
|
||||
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
|
||||
nop
|
||||
loop:
|
||||
subs r5, r5, #0x1 @ awake, wait just a bit
|
||||
bne loop
|
||||
|
||||
/* The DPLL has on before we take the DDR out of self refresh */
|
||||
bic r4, r4, #0x40 @ now clear self refresh bit.
|
||||
str r4, [r3] @ put vlaue back.
|
||||
ldr r4, A_SDRC0 @ make a clock happen
|
||||
ldr r4, [r4]
|
||||
nop @ start auto refresh only after clk ok
|
||||
movs r0, r0 @ see if DDR or SDR
|
||||
ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl
|
||||
strne r0, [r1] @ rewrite DLLA to force DLL reload
|
||||
addne r1, r1, #0x8 @ move to DLLB
|
||||
strne r0, [r1] @ rewrite DLLB to force DLL reload
|
||||
|
||||
mov r5, #0x1000
|
||||
loop2:
|
||||
subs r5, r5, #0x1
|
||||
bne loop2
|
||||
/* resume*/
|
||||
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
|
||||
|
||||
A_SDRC_POWER:
|
||||
.word A_SDRC_POWER_V
|
||||
A_SDRC0:
|
||||
.word A_SDRC0_V
|
||||
A_CM_CLKSEL2_PLL_S:
|
||||
.word A_CM_CLKSEL2_PLL_V
|
||||
A_CM_CLKEN_PLL:
|
||||
.word A_CM_CLKEN_PLL_V
|
||||
A_SDRC_DLLA_CTRL_S:
|
||||
.word A_SDRC_DLLA_CTRL_V
|
||||
A_SDRC_MANUAL_S:
|
||||
.word A_SDRC_MANUAL_V
|
||||
|
||||
ENTRY(omap24xx_cpu_suspend_sz)
|
||||
.word . - omap24xx_cpu_suspend
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/sram.S
|
||||
* linux/arch/arm/mach-omap2/sram.S
|
||||
*
|
||||
* Omap2 specific functions that need to be run in internal SRAM
|
||||
*
|
||||
@ -28,7 +28,7 @@
|
||||
#include <asm/arch/io.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/arch/prcm.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
|
||||
|
||||
|
@ -307,6 +307,10 @@ static void __init fixup_poodle(struct machine_desc *desc,
|
||||
struct tag *tags, char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
sharpsl_save_param();
|
||||
mi->nr_banks=1;
|
||||
mi->bank[0].start = 0xa0000000;
|
||||
mi->bank[0].node = 0;
|
||||
mi->bank[0].size = (32*1024*1024);
|
||||
}
|
||||
|
||||
MACHINE_START(POODLE, "SHARP Poodle")
|
||||
|
@ -50,9 +50,15 @@ config MACH_N30
|
||||
|
||||
<http://zoo.weinigel.se/n30>.
|
||||
|
||||
config MACH_SMDK
|
||||
bool
|
||||
help
|
||||
Common machine code for SMDK2410 and SMDK2440
|
||||
|
||||
config ARCH_SMDK2410
|
||||
bool "SMDK2410/A9M2410"
|
||||
select CPU_S3C2410
|
||||
select MACH_SMDK
|
||||
help
|
||||
Say Y here if you are using the SMDK2410 or the derived module A9M2410
|
||||
<http://www.fsforth.de>
|
||||
@ -60,6 +66,7 @@ config ARCH_SMDK2410
|
||||
config ARCH_S3C2440
|
||||
bool "SMDK2440"
|
||||
select CPU_S3C2440
|
||||
select MACH_SMDK
|
||||
help
|
||||
Say Y here if you are using the SMDK2440.
|
||||
|
||||
|
@ -48,3 +48,5 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
|
||||
obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
|
||||
obj-$(CONFIG_MACH_OTOM) += mach-otom.o
|
||||
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
|
||||
|
||||
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
|
@ -249,7 +249,7 @@ static int s3c24xx_upll_enable(struct clk *clk, int enable)
|
||||
|
||||
/* if we started the UPLL, then allow to settle */
|
||||
|
||||
if (enable && !(orig & S3C2410_CLKSLOW_UCLK_OFF))
|
||||
if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
|
||||
udelay(200);
|
||||
|
||||
return 0;
|
||||
|
134
arch/arm/mach-s3c2410/common-smdk.c
Normal file
134
arch/arm/mach-s3c2410/common-smdk.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* linux/arch/arm/mach-s3c2410/common-smdk.c
|
||||
*
|
||||
* Copyright (c) 2006 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* Common code for SMDK2410 and SMDK2440 boards
|
||||
*
|
||||
* http://www.fluff.org/ben/smdk2440/
|
||||
*
|
||||
* 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/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
|
||||
#include <asm/arch/nand.h>
|
||||
|
||||
#include "devs.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* NAND parititon from 2.4.18-swl5 */
|
||||
|
||||
static struct mtd_partition smdk_default_nand_part[] = {
|
||||
[0] = {
|
||||
.name = "Boot Agent",
|
||||
.size = SZ_16K,
|
||||
.offset = 0,
|
||||
},
|
||||
[1] = {
|
||||
.name = "S3C2410 flash parition 1",
|
||||
.offset = 0,
|
||||
.size = SZ_2M,
|
||||
},
|
||||
[2] = {
|
||||
.name = "S3C2410 flash partition 2",
|
||||
.offset = SZ_4M,
|
||||
.size = SZ_4M,
|
||||
},
|
||||
[3] = {
|
||||
.name = "S3C2410 flash partition 3",
|
||||
.offset = SZ_8M,
|
||||
.size = SZ_2M,
|
||||
},
|
||||
[4] = {
|
||||
.name = "S3C2410 flash partition 4",
|
||||
.offset = SZ_1M * 10,
|
||||
.size = SZ_4M,
|
||||
},
|
||||
[5] = {
|
||||
.name = "S3C2410 flash partition 5",
|
||||
.offset = SZ_1M * 14,
|
||||
.size = SZ_1M * 10,
|
||||
},
|
||||
[6] = {
|
||||
.name = "S3C2410 flash partition 6",
|
||||
.offset = SZ_1M * 24,
|
||||
.size = SZ_1M * 24,
|
||||
},
|
||||
[7] = {
|
||||
.name = "S3C2410 flash partition 7",
|
||||
.offset = SZ_1M * 48,
|
||||
.size = SZ_16M,
|
||||
}
|
||||
};
|
||||
|
||||
static struct s3c2410_nand_set smdk_nand_sets[] = {
|
||||
[0] = {
|
||||
.name = "NAND",
|
||||
.nr_chips = 1,
|
||||
.nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
|
||||
.partitions = smdk_default_nand_part,
|
||||
},
|
||||
};
|
||||
|
||||
/* choose a set of timings which should suit most 512Mbit
|
||||
* chips and beyond.
|
||||
*/
|
||||
|
||||
static struct s3c2410_platform_nand smdk_nand_info = {
|
||||
.tacls = 20,
|
||||
.twrph0 = 60,
|
||||
.twrph1 = 20,
|
||||
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
|
||||
.sets = smdk_nand_sets,
|
||||
};
|
||||
|
||||
/* devices we initialise */
|
||||
|
||||
static struct platform_device __initdata *smdk_devs[] = {
|
||||
&s3c_device_nand,
|
||||
};
|
||||
|
||||
void __init smdk_machine_init(void)
|
||||
{
|
||||
/* Configure the LEDs (even if we have no LED support)*/
|
||||
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
|
||||
|
||||
s3c2410_gpio_setpin(S3C2410_GPF4, 1);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF5, 1);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF6, 1);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF7, 1);
|
||||
|
||||
s3c_device_nand.dev.platform_data = &smdk_nand_info;
|
||||
|
||||
platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
|
||||
|
||||
s3c2410_pm_init();
|
||||
}
|
15
arch/arm/mach-s3c2410/common-smdk.h
Normal file
15
arch/arm/mach-s3c2410/common-smdk.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* linux/arch/arm/mach-s3c2410/common-smdk.h
|
||||
*
|
||||
* Copyright (c) 2006 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* Common code for SMDK2410 and SMDK2440 boards
|
||||
*
|
||||
* http://www.fluff.org/ben/smdk2440/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern void smdk_machine_init(void);
|
@ -232,8 +232,8 @@ static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
|
||||
|
||||
static struct s3c2410_platform_nand anubis_nand_info = {
|
||||
.tacls = 25,
|
||||
.twrph0 = 80,
|
||||
.twrph1 = 80,
|
||||
.twrph0 = 55,
|
||||
.twrph1 = 40,
|
||||
.nr_sets = ARRAY_SIZE(anubis_nand_sets),
|
||||
.sets = anubis_nand_sets,
|
||||
.select_chip = anubis_nand_select,
|
||||
|
@ -32,6 +32,11 @@
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
@ -46,6 +51,7 @@
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/regs-lcd.h>
|
||||
|
||||
#include <asm/arch/nand.h>
|
||||
#include <asm/arch/fb.h>
|
||||
|
||||
#include "clock.h"
|
||||
@ -170,12 +176,39 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition rx3715_nand_part[] = {
|
||||
[0] = {
|
||||
.name = "Whole Flash",
|
||||
.offset = 0,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
}
|
||||
};
|
||||
|
||||
static struct s3c2410_nand_set rx3715_nand_sets[] = {
|
||||
[0] = {
|
||||
.name = "Internal",
|
||||
.nr_chips = 1,
|
||||
.nr_partitions = ARRAY_SIZE(rx3715_nand_part),
|
||||
.partitions = rx3715_nand_part,
|
||||
},
|
||||
};
|
||||
|
||||
static struct s3c2410_platform_nand rx3715_nand_info = {
|
||||
.tacls = 25,
|
||||
.twrph0 = 50,
|
||||
.twrph1 = 15,
|
||||
.nr_sets = ARRAY_SIZE(rx3715_nand_sets),
|
||||
.sets = rx3715_nand_sets,
|
||||
};
|
||||
|
||||
static struct platform_device *rx3715_devices[] __initdata = {
|
||||
&s3c_device_usb,
|
||||
&s3c_device_lcd,
|
||||
&s3c_device_wdt,
|
||||
&s3c_device_i2c,
|
||||
&s3c_device_iis,
|
||||
&s3c_device_nand,
|
||||
};
|
||||
|
||||
static struct s3c24xx_board rx3715_board __initdata = {
|
||||
@ -185,6 +218,8 @@ static struct s3c24xx_board rx3715_board __initdata = {
|
||||
|
||||
static void __init rx3715_map_io(void)
|
||||
{
|
||||
s3c_device_nand.dev.platform_data = &rx3715_nand_info;
|
||||
|
||||
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
|
||||
s3c24xx_init_clocks(16934000);
|
||||
s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
|
||||
|
@ -28,7 +28,8 @@
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
* 01-Apr-2006 BJD Moved init code to common smdk
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
@ -54,6 +55,8 @@
|
||||
#include "devs.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "common-smdk.h"
|
||||
|
||||
static struct map_desc smdk2410_iodesc[] __initdata = {
|
||||
/* nothing here yet */
|
||||
};
|
||||
@ -107,11 +110,6 @@ static void __init smdk2410_map_io(void)
|
||||
s3c24xx_set_board(&smdk2410_board);
|
||||
}
|
||||
|
||||
static void __init smdk2410_init_irq(void)
|
||||
{
|
||||
s3c24xx_init_irq();
|
||||
}
|
||||
|
||||
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
|
||||
* to SMDK2410 */
|
||||
/* Maintainer: Jonas Dietsche */
|
||||
@ -119,7 +117,8 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
|
||||
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
|
||||
.boot_params = S3C2410_SDRAM_PA + 0x100,
|
||||
.map_io = smdk2410_map_io,
|
||||
.init_irq = smdk2410_init_irq,
|
||||
.init_irq = s3c24xx_init_irq,
|
||||
.init_machine = smdk_machine_init,
|
||||
.timer = &s3c24xx_timer,
|
||||
MACHINE_END
|
||||
|
||||
|
@ -53,7 +53,8 @@
|
||||
#include "clock.h"
|
||||
#include "devs.h"
|
||||
#include "cpu.h"
|
||||
#include "pm.h"
|
||||
|
||||
#include "common-smdk.h"
|
||||
|
||||
static struct map_desc smdk2440_iodesc[] __initdata = {
|
||||
/* ISA IO Space map (memory space selected by A24) */
|
||||
@ -197,21 +198,9 @@ static void __init smdk2440_map_io(void)
|
||||
|
||||
static void __init smdk2440_machine_init(void)
|
||||
{
|
||||
/* Configure the LEDs (even if we have no LED support)*/
|
||||
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
|
||||
s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
|
||||
|
||||
s3c2410_gpio_setpin(S3C2410_GPF4, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF5, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF6, 0);
|
||||
s3c2410_gpio_setpin(S3C2410_GPF7, 0);
|
||||
|
||||
s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
|
||||
|
||||
s3c2410_pm_init();
|
||||
smdk_machine_init();
|
||||
}
|
||||
|
||||
MACHINE_START(S3C2440, "SMDK2440")
|
||||
|
@ -11,7 +11,8 @@
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* ChangeLog:
|
||||
* 03-06-2004 John Lenz <jelenz@wisc.edu>
|
||||
* 2006 Pavel Machek <pavel@suse.cz>
|
||||
* 03-06-2004 John Lenz <lenz@cs.wisc.edu>
|
||||
* 06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
|
||||
* 04-16-2001 Lineo Japan,Inc. ...
|
||||
*/
|
||||
@ -87,12 +88,75 @@ static struct mcp_plat_data collie_mcp_data = {
|
||||
.sclk_rate = 11981000,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SHARP_LOCOMO
|
||||
/*
|
||||
* low-level UART features.
|
||||
*/
|
||||
static struct locomo_dev *uart_dev = NULL;
|
||||
|
||||
static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
|
||||
{
|
||||
if (!uart_dev) return;
|
||||
|
||||
if (mctrl & TIOCM_RTS)
|
||||
locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0);
|
||||
else
|
||||
locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1);
|
||||
|
||||
if (mctrl & TIOCM_DTR)
|
||||
locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0);
|
||||
else
|
||||
locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1);
|
||||
}
|
||||
|
||||
static u_int collie_uart_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
int ret = TIOCM_CD;
|
||||
unsigned int r;
|
||||
if (!uart_dev) return ret;
|
||||
|
||||
r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
|
||||
if (r & LOCOMO_GPIO_CTS)
|
||||
ret |= TIOCM_CTS;
|
||||
if (r & LOCOMO_GPIO_DSR)
|
||||
ret |= TIOCM_DSR;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sa1100_port_fns collie_port_fns __initdata = {
|
||||
.set_mctrl = collie_uart_set_mctrl,
|
||||
.get_mctrl = collie_uart_get_mctrl,
|
||||
};
|
||||
|
||||
static int collie_uart_probe(struct locomo_dev *dev)
|
||||
{
|
||||
uart_dev = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int collie_uart_remove(struct locomo_dev *dev)
|
||||
{
|
||||
uart_dev = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct locomo_driver collie_uart_driver = {
|
||||
.drv = {
|
||||
.name = "collie_uart",
|
||||
},
|
||||
.devid = LOCOMO_DEVID_UART,
|
||||
.probe = collie_uart_probe,
|
||||
.remove = collie_uart_remove,
|
||||
};
|
||||
|
||||
static int __init collie_uart_init(void) {
|
||||
return locomo_driver_register(&collie_uart_driver);
|
||||
}
|
||||
device_initcall(collie_uart_init);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static struct resource locomo_resources[] = {
|
||||
[0] = {
|
||||
@ -218,6 +282,12 @@ static void __init collie_map_io(void)
|
||||
{
|
||||
sa1100_map_io();
|
||||
iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
|
||||
|
||||
#ifdef CONFIG_SHARP_LOCOMO
|
||||
sa1100_register_uart_fns(&collie_port_fns);
|
||||
#endif
|
||||
sa1100_register_uart(0, 3);
|
||||
sa1100_register_uart(1, 1);
|
||||
}
|
||||
|
||||
MACHINE_START(COLLIE, "Sharp-Collie")
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/sizes.h>
|
||||
@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
{
|
||||
if (arch_is_coherent()) {
|
||||
void *virt;
|
||||
|
||||
virt = kmalloc(size, gfp);
|
||||
if (!virt)
|
||||
return NULL;
|
||||
*handle = virt_to_dma(dev, virt);
|
||||
|
||||
return virt;
|
||||
}
|
||||
|
||||
return __dma_alloc(dev, size, handle, gfp,
|
||||
pgprot_noncached(pgprot_kernel));
|
||||
}
|
||||
@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
kfree(cpu_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
spin_lock_irqsave(&consistent_lock, flags);
|
||||
|
@ -388,6 +388,17 @@ void __init build_mem_type_table(void)
|
||||
cp = &cache_policies[cachepolicy];
|
||||
kern_pgprot = user_pgprot = cp->pte;
|
||||
|
||||
/*
|
||||
* Enable CPU-specific coherency if supported.
|
||||
* (Only available on XSC3 at the moment.)
|
||||
*/
|
||||
if (arch_is_coherent()) {
|
||||
if (cpu_is_xsc3()) {
|
||||
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
|
||||
mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ARMv6 and above have extended page tables.
|
||||
*/
|
||||
|
@ -371,7 +371,7 @@ ENTRY(cpu_xsc3_switch_mm)
|
||||
ENTRY(cpu_xsc3_set_pte)
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0xff0
|
||||
bic r2, r1, #0xdf0 @ Keep C, B, coherency bits
|
||||
orr r2, r2, #PTE_TYPE_EXT @ extended page
|
||||
|
||||
eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
|
||||
|
@ -70,13 +70,13 @@ config OMAP_MPU_TIMER
|
||||
|
||||
config OMAP_32K_TIMER
|
||||
bool "Use 32KHz timer"
|
||||
depends on ARCH_OMAP16XX
|
||||
depends on ARCH_OMAP16XX || ARCH_OMAP24XX
|
||||
help
|
||||
Select this option if you want to enable the OMAP 32KHz timer.
|
||||
This timer saves power compared to the OMAP_MPU_TIMER, and has
|
||||
support for no tick during idle. The 32KHz timer provides less
|
||||
intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
|
||||
currently only available for OMAP-16xx.
|
||||
currently only available for OMAP16XX and 24XX.
|
||||
|
||||
endchoice
|
||||
|
||||
|
@ -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
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/semaphore.h>
|
||||
@ -37,17 +38,37 @@ static struct clk_functions *arch_clock;
|
||||
* Standard clock functions defined in include/linux/clk.h
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Returns a clock. Note that we first try to use device id on the bus
|
||||
* and clock name. If this fails, we try to use clock name only.
|
||||
*/
|
||||
struct clk * clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *p, *clk = ERR_PTR(-ENOENT);
|
||||
int idno;
|
||||
|
||||
if (dev == NULL || dev->bus != &platform_bus_type)
|
||||
idno = -1;
|
||||
else
|
||||
idno = to_platform_device(dev)->id;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (p->id == idno &&
|
||||
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return clk;
|
||||
@ -59,6 +80,9 @@ int clk_enable(struct clk *clk)
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_enable)
|
||||
ret = arch_clock->clk_enable(clk);
|
||||
@ -72,6 +96,9 @@ void clk_disable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_disable)
|
||||
arch_clock->clk_disable(clk);
|
||||
@ -84,6 +111,9 @@ int clk_get_usecount(struct clk *clk)
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
ret = clk->usecount;
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
@ -97,6 +127,9 @@ unsigned long clk_get_rate(struct clk *clk)
|
||||
unsigned long flags;
|
||||
unsigned long ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
ret = clk->rate;
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
@ -121,6 +154,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
unsigned long flags;
|
||||
long ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_round_rate)
|
||||
ret = arch_clock->clk_round_rate(clk, rate);
|
||||
@ -133,7 +169,10 @@ EXPORT_SYMBOL(clk_round_rate);
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_set_rate)
|
||||
@ -147,7 +186,10 @@ EXPORT_SYMBOL(clk_set_rate);
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_set_parent)
|
||||
@ -163,6 +205,9 @@ struct clk *clk_get_parent(struct clk *clk)
|
||||
unsigned long flags;
|
||||
struct clk * ret = NULL;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_get_parent)
|
||||
ret = arch_clock->clk_get_parent(clk);
|
||||
@ -199,6 +244,9 @@ __setup("mpurate=", omap_clk_setup);
|
||||
/* Used for clocks that always have same value as the parent clock */
|
||||
void followparent_recalc(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
clk->rate = clk->parent->rate;
|
||||
}
|
||||
|
||||
@ -207,6 +255,9 @@ void propagate_rate(struct clk * tclk)
|
||||
{
|
||||
struct clk *clkp;
|
||||
|
||||
if (tclk == NULL || IS_ERR(tclk))
|
||||
return;
|
||||
|
||||
list_for_each_entry(clkp, &clocks, node) {
|
||||
if (likely(clkp->parent != tclk))
|
||||
continue;
|
||||
@ -217,6 +268,9 @@ void propagate_rate(struct clk * tclk)
|
||||
|
||||
int clk_register(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_add(&clk->node, &clocks);
|
||||
if (clk->init)
|
||||
@ -229,6 +283,9 @@ EXPORT_SYMBOL(clk_register);
|
||||
|
||||
void clk_unregister(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_del(&clk->node);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
@ -239,6 +296,9 @@ void clk_deny_idle(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_deny_idle)
|
||||
arch_clock->clk_deny_idle(clk);
|
||||
@ -250,6 +310,9 @@ void clk_allow_idle(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (arch_clock->clk_allow_idle)
|
||||
arch_clock->clk_allow_idle(clk);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/menelaus.h>
|
||||
|
||||
|
||||
void omap_nop_release(struct device *dev)
|
||||
@ -97,6 +98,62 @@ static void omap_init_i2c(void)
|
||||
static inline void omap_init_i2c(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
|
||||
|
||||
static void omap_init_kp(void)
|
||||
{
|
||||
if (machine_is_omap_h2() || machine_is_omap_h3()) {
|
||||
omap_cfg_reg(F18_1610_KBC0);
|
||||
omap_cfg_reg(D20_1610_KBC1);
|
||||
omap_cfg_reg(D19_1610_KBC2);
|
||||
omap_cfg_reg(E18_1610_KBC3);
|
||||
omap_cfg_reg(C21_1610_KBC4);
|
||||
|
||||
omap_cfg_reg(G18_1610_KBR0);
|
||||
omap_cfg_reg(F19_1610_KBR1);
|
||||
omap_cfg_reg(H14_1610_KBR2);
|
||||
omap_cfg_reg(E20_1610_KBR3);
|
||||
omap_cfg_reg(E19_1610_KBR4);
|
||||
omap_cfg_reg(N19_1610_KBR5);
|
||||
} else if (machine_is_omap_perseus2()) {
|
||||
omap_cfg_reg(E2_730_KBR0);
|
||||
omap_cfg_reg(J7_730_KBR1);
|
||||
omap_cfg_reg(E1_730_KBR2);
|
||||
omap_cfg_reg(F3_730_KBR3);
|
||||
omap_cfg_reg(D2_730_KBR4);
|
||||
|
||||
omap_cfg_reg(C2_730_KBC0);
|
||||
omap_cfg_reg(D3_730_KBC1);
|
||||
omap_cfg_reg(E4_730_KBC2);
|
||||
omap_cfg_reg(F4_730_KBC3);
|
||||
omap_cfg_reg(E3_730_KBC4);
|
||||
} else if (machine_is_omap_h4()) {
|
||||
omap_cfg_reg(T19_24XX_KBR0);
|
||||
omap_cfg_reg(R19_24XX_KBR1);
|
||||
omap_cfg_reg(V18_24XX_KBR2);
|
||||
omap_cfg_reg(M21_24XX_KBR3);
|
||||
omap_cfg_reg(E5__24XX_KBR4);
|
||||
if (omap_has_menelaus()) {
|
||||
omap_cfg_reg(B3__24XX_KBR5);
|
||||
omap_cfg_reg(AA4_24XX_KBC2);
|
||||
omap_cfg_reg(B13_24XX_KBC6);
|
||||
} else {
|
||||
omap_cfg_reg(M18_24XX_KBR5);
|
||||
omap_cfg_reg(H19_24XX_KBC2);
|
||||
omap_cfg_reg(N19_24XX_KBC6);
|
||||
}
|
||||
omap_cfg_reg(R20_24XX_KBC0);
|
||||
omap_cfg_reg(M14_24XX_KBC1);
|
||||
omap_cfg_reg(V17_24XX_KBC3);
|
||||
omap_cfg_reg(P21_24XX_KBC4);
|
||||
omap_cfg_reg(L14_24XX_KBC5);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_kp(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
|
||||
@ -240,6 +297,55 @@ static void __init omap_init_mmc(void)
|
||||
static inline void omap_init_mmc(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Numbering for the SPI-capable controllers when used for SPI:
|
||||
* spi = 1
|
||||
* uwire = 2
|
||||
* mmc1..2 = 3..4
|
||||
* mcbsp1..3 = 5..7
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
|
||||
|
||||
#define OMAP_UWIRE_BASE 0xfffb3000
|
||||
|
||||
static struct resource uwire_resources[] = {
|
||||
{
|
||||
.start = OMAP_UWIRE_BASE,
|
||||
.end = OMAP_UWIRE_BASE + 0x20,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_uwire_device = {
|
||||
.name = "omap_uwire",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(uwire_resources),
|
||||
.resource = uwire_resources,
|
||||
};
|
||||
|
||||
static void omap_init_uwire(void)
|
||||
{
|
||||
/* FIXME define and use a boot tag; not all boards will be hooking
|
||||
* up devices to the microwire controller, and multi-board configs
|
||||
* mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
|
||||
*/
|
||||
|
||||
/* board-specific code must configure chipselects (only a few
|
||||
* are normally used) and SCLK/SDI/SDO (each has two choices).
|
||||
*/
|
||||
(void) platform_device_register(&omap_uwire_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_uwire(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
@ -310,40 +416,6 @@ static void omap_init_rng(void)
|
||||
static inline void omap_init_rng(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
|
||||
|
||||
static struct omap_lcd_config omap_fb_conf;
|
||||
|
||||
static u64 omap_fb_dma_mask = ~(u32)0;
|
||||
|
||||
static struct platform_device omap_fb_device = {
|
||||
.name = "omapfb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &omap_fb_dma_mask,
|
||||
.coherent_dma_mask = ~(u32)0,
|
||||
.platform_data = &omap_fb_conf,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
static inline void omap_init_fb(void)
|
||||
{
|
||||
const struct omap_lcd_config *conf;
|
||||
|
||||
conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
|
||||
if (conf != NULL)
|
||||
omap_fb_conf = *conf;
|
||||
platform_device_register(&omap_fb_device);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void omap_init_fb(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This gets called after board-specific INIT_MACHINE, and initializes most
|
||||
* on-chip peripherals accessible on this board (except for few like USB):
|
||||
@ -369,9 +441,10 @@ static int __init omap_init_devices(void)
|
||||
/* please keep these calls, and their implementations above,
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_fb();
|
||||
omap_init_i2c();
|
||||
omap_init_kp();
|
||||
omap_init_mmc();
|
||||
omap_init_uwire();
|
||||
omap_init_wdt();
|
||||
omap_init_rng();
|
||||
|
||||
|
@ -1258,6 +1258,11 @@ void omap_stop_lcd_dma(void)
|
||||
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
|
||||
}
|
||||
|
||||
int omap_lcd_dma_ext_running(void)
|
||||
{
|
||||
return lcd_dma.ext_ctrl && lcd_dma.active;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static int __init omap_init_dma(void)
|
||||
@ -1389,6 +1394,7 @@ EXPORT_SYMBOL(omap_free_lcd_dma);
|
||||
EXPORT_SYMBOL(omap_enable_lcd_dma);
|
||||
EXPORT_SYMBOL(omap_setup_lcd_dma);
|
||||
EXPORT_SYMBOL(omap_stop_lcd_dma);
|
||||
EXPORT_SYMBOL(omap_lcd_dma_ext_running);
|
||||
EXPORT_SYMBOL(omap_set_lcd_dma_b1);
|
||||
EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
|
||||
EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
|
||||
|
@ -97,6 +97,32 @@ int omap_dm_timers_active(void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
|
||||
* @inputmask: current value of idlect mask
|
||||
*/
|
||||
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* If ARMXOR cannot be idled this function call is unnecessary */
|
||||
if (!(inputmask & (1 << 1)))
|
||||
return inputmask;
|
||||
|
||||
/* If any active timer is using ARMXOR return modified mask */
|
||||
for (n = 0; dm_timers[n].base; ++n)
|
||||
if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)&
|
||||
OMAP_TIMER_CTRL_ST) {
|
||||
if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0)
|
||||
inputmask &= ~(1 << 1);
|
||||
else
|
||||
inputmask &= ~(1 << 2);
|
||||
}
|
||||
|
||||
return inputmask;
|
||||
}
|
||||
|
||||
|
||||
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
{
|
||||
int n = (timer - dm_timers) << 1;
|
||||
|
80
arch/arm/plat-omap/fb.c
Normal file
80
arch/arm/plat-omap/fb.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/bootmem.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/omapfb.h>
|
||||
|
||||
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
|
||||
|
||||
static struct omapfb_platform_data omapfb_config;
|
||||
|
||||
static u64 omap_fb_dma_mask = ~(u32)0;
|
||||
|
||||
static struct platform_device omap_fb_device = {
|
||||
.name = "omapfb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &omap_fb_dma_mask,
|
||||
.coherent_dma_mask = ~(u32)0,
|
||||
.platform_data = &omapfb_config,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
/* called from map_io */
|
||||
void omapfb_reserve_mem(void)
|
||||
{
|
||||
const struct omap_fbmem_config *fbmem_conf;
|
||||
|
||||
omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start;
|
||||
omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size;
|
||||
|
||||
fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
|
||||
|
||||
if (fbmem_conf != NULL) {
|
||||
/* indicate that the bootloader already initialized the
|
||||
* fb device, so we'll skip that part in the fb driver
|
||||
*/
|
||||
omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start;
|
||||
omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size;
|
||||
if (fbmem_conf->fb_sdram_size) {
|
||||
pr_info("Reserving %u bytes SDRAM for frame buffer\n",
|
||||
fbmem_conf->fb_sdram_size);
|
||||
reserve_bootmem(fbmem_conf->fb_sdram_start,
|
||||
fbmem_conf->fb_sdram_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int omap_init_fb(void)
|
||||
{
|
||||
const struct omap_lcd_config *conf;
|
||||
|
||||
conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
|
||||
if (conf == NULL)
|
||||
return 0;
|
||||
|
||||
omapfb_config.lcd = *conf;
|
||||
|
||||
return platform_device_register(&omap_fb_device);
|
||||
}
|
||||
|
||||
arch_initcall(omap_init_fb);
|
||||
|
||||
#else
|
||||
|
||||
void omapfb_reserve_mem(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -174,7 +174,7 @@ static int gpio_bank_count;
|
||||
static inline struct gpio_bank *get_gpio_bank(int gpio)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
if (OMAP_GPIO_IS_MPUIO(gpio))
|
||||
return &gpio_bank[0];
|
||||
return &gpio_bank[1];
|
||||
@ -223,7 +223,7 @@ static inline int gpio_valid(int gpio)
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510() && gpio < 16)
|
||||
if (cpu_is_omap15xx() && gpio < 16)
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
@ -402,13 +402,13 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr
|
||||
u32 gpio_bit = 1 << gpio;
|
||||
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
|
||||
trigger & IRQT_LOW);
|
||||
trigger & __IRQT_LOWLVL);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
|
||||
trigger & IRQT_HIGH);
|
||||
trigger & __IRQT_HIGHLVL);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
|
||||
trigger & IRQT_RISING);
|
||||
trigger & __IRQT_RISEDGE);
|
||||
MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
|
||||
trigger & IRQT_FALLING);
|
||||
trigger & __IRQT_FALEDGE);
|
||||
/* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
|
||||
* triggering requested. */
|
||||
}
|
||||
@ -422,9 +422,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
||||
case METHOD_MPUIO:
|
||||
reg += OMAP_MPUIO_GPIO_INT_EDGE;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger == IRQT_RISING)
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger == IRQT_FALLING)
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
@ -432,9 +432,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
||||
case METHOD_GPIO_1510:
|
||||
reg += OMAP1510_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger == IRQT_RISING)
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger == IRQT_FALLING)
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
@ -446,20 +446,21 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
||||
reg += OMAP1610_GPIO_EDGE_CTRL1;
|
||||
gpio &= 0x07;
|
||||
/* We allow only edge triggering, i.e. two lowest bits */
|
||||
if (trigger & ~IRQT_BOTHEDGE)
|
||||
if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
|
||||
BUG();
|
||||
/* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
|
||||
trigger &= 0x03;
|
||||
l = __raw_readl(reg);
|
||||
l &= ~(3 << (gpio << 1));
|
||||
l |= trigger << (gpio << 1);
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
l |= 2 << (gpio << 1);
|
||||
if (trigger & __IRQT_FALEDGE)
|
||||
l |= 1 << (gpio << 1);
|
||||
break;
|
||||
case METHOD_GPIO_730:
|
||||
reg += OMAP730_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger == IRQT_RISING)
|
||||
if (trigger & __IRQT_RISEDGE)
|
||||
l |= 1 << gpio;
|
||||
else if (trigger == IRQT_FALLING)
|
||||
else if (trigger & __IRQT_FALEDGE)
|
||||
l &= ~(1 << gpio);
|
||||
else
|
||||
goto bad;
|
||||
@ -491,7 +492,9 @@ static int gpio_irq_type(unsigned irq, unsigned type)
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
|
||||
if (type & IRQT_PROBE)
|
||||
return -EINVAL;
|
||||
if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
|
||||
return -EINVAL;
|
||||
|
||||
bank = get_gpio_bank(gpio);
|
||||
@ -755,13 +758,32 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
if (bank->method == METHOD_GPIO_24XX)
|
||||
isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
isr = __raw_readl(isr_reg);
|
||||
_enable_gpio_irqbank(bank, isr, 0);
|
||||
_clear_gpio_irqbank(bank, isr);
|
||||
_enable_gpio_irqbank(bank, isr, 1);
|
||||
desc->chip->unmask(irq);
|
||||
u32 isr_saved, level_mask = 0;
|
||||
|
||||
isr_saved = isr = __raw_readl(isr_reg);
|
||||
|
||||
if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
|
||||
isr &= 0x0000ffff;
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
level_mask =
|
||||
__raw_readl(bank->base +
|
||||
OMAP24XX_GPIO_LEVELDETECT0) |
|
||||
__raw_readl(bank->base +
|
||||
OMAP24XX_GPIO_LEVELDETECT1);
|
||||
|
||||
/* clear edge sensitive interrupts before handler(s) are
|
||||
called so that we don't miss any interrupt occurred while
|
||||
executing them */
|
||||
_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
|
||||
_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
|
||||
_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
|
||||
|
||||
/* if there is only edge sensitive GPIO pin interrupts
|
||||
configured, we could unmask GPIO bank interrupt immediately */
|
||||
if (!level_mask)
|
||||
desc->chip->unmask(irq);
|
||||
|
||||
if (!isr)
|
||||
break;
|
||||
@ -774,6 +796,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
d = irq_desc + gpio_irq;
|
||||
desc_handle_irq(gpio_irq, d, regs);
|
||||
}
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
/* clear level sensitive interrupts after handler(s) */
|
||||
_enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
|
||||
_clear_gpio_irqbank(bank, isr_saved & level_mask);
|
||||
_enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
|
||||
}
|
||||
|
||||
/* if bank has any level sensitive GPIO pin interrupt
|
||||
configured, we must unmask the bank interrupt only after
|
||||
handler(s) are executed in order to avoid spurious bank
|
||||
interrupt */
|
||||
if (level_mask)
|
||||
desc->chip->unmask(irq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -848,7 +884,7 @@ static int __init _omap_gpio_init(void)
|
||||
|
||||
initialized = 1;
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
gpio_ick = clk_get(NULL, "arm_gpio_ck");
|
||||
if (IS_ERR(gpio_ick))
|
||||
printk("Could not get arm_gpio_ck\n");
|
||||
@ -869,7 +905,7 @@ static int __init _omap_gpio_init(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
printk(KERN_INFO "OMAP1510 GPIO hardware\n");
|
||||
gpio_bank_count = 2;
|
||||
gpio_bank = gpio_bank_1510;
|
||||
|
@ -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));
|
||||
|
||||
|
||||
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].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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -728,6 +979,19 @@ static int __init omap_mcbsp_init(void)
|
||||
mcbsp_info = mcbsp_1610;
|
||||
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) {
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -16,24 +16,94 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
#define OMAP1_SRAM_PA 0x20000000
|
||||
#define OMAP1_SRAM_VA 0xd0000000
|
||||
#define OMAP2_SRAM_PA 0x40200000
|
||||
#define OMAP2_SRAM_PUB_PA 0x4020f800
|
||||
#define OMAP2_SRAM_VA 0xd0000000
|
||||
#define OMAP2_SRAM_PUB_VA 0xd0000800
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP24XX)
|
||||
#define SRAM_BOOTLOADER_SZ 0x00
|
||||
#else
|
||||
#define SRAM_BOOTLOADER_SZ 0x80
|
||||
#endif
|
||||
|
||||
#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048)
|
||||
#define VA_READPERM0 IO_ADDRESS(0x68005050)
|
||||
#define VA_WRITEPERM0 IO_ADDRESS(0x68005058)
|
||||
#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8)
|
||||
#define GP_DEVICE 0x300
|
||||
#define TYPE_MASK 0x700
|
||||
|
||||
#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
|
||||
|
||||
static unsigned long omap_sram_base;
|
||||
static unsigned long omap_sram_size;
|
||||
static unsigned long omap_sram_ceil;
|
||||
|
||||
unsigned long omap_fb_sram_start;
|
||||
unsigned long omap_fb_sram_size;
|
||||
|
||||
/* Depending on the target RAMFS firewall setup, the public usable amount of
|
||||
* SRAM varies. The default accessable size for all device types is 2k. A GP
|
||||
* device allows ARM11 but not other initators for full size. This
|
||||
* functionality seems ok until some nice security API happens.
|
||||
*/
|
||||
static int is_sram_locked(void)
|
||||
{
|
||||
int type = 0;
|
||||
|
||||
if (cpu_is_omap242x())
|
||||
type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK;
|
||||
|
||||
if (type == GP_DEVICE) {
|
||||
/* RAMFW: R/W access to all initators for all qualifier sets */
|
||||
if (cpu_is_omap242x()) {
|
||||
__raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */
|
||||
__raw_writel(0xCFDE, VA_READPERM0); /* all i-read */
|
||||
__raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */
|
||||
}
|
||||
return 0;
|
||||
} else
|
||||
return 1; /* assume locked with no PPA or security driver */
|
||||
}
|
||||
|
||||
void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail,
|
||||
unsigned long *start, unsigned long *size)
|
||||
{
|
||||
const struct omap_fbmem_config *fbmem_conf;
|
||||
|
||||
fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
|
||||
if (fbmem_conf != NULL) {
|
||||
*start = fbmem_conf->fb_sram_start;
|
||||
*size = fbmem_conf->fb_sram_size;
|
||||
} else {
|
||||
*size = 0;
|
||||
*start = 0;
|
||||
}
|
||||
|
||||
if (*size && (
|
||||
*start < start_avail ||
|
||||
*start + *size > start_avail + size_avail)) {
|
||||
printk(KERN_ERR "invalid FB SRAM configuration\n");
|
||||
*start = start_avail;
|
||||
*size = size_avail;
|
||||
}
|
||||
|
||||
if (*size)
|
||||
pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size);
|
||||
}
|
||||
|
||||
/*
|
||||
* The amount of SRAM depends on the core type.
|
||||
* Note that we cannot try to test for SRAM here because writes
|
||||
@ -42,26 +112,45 @@ static unsigned long omap_sram_ceil;
|
||||
*/
|
||||
void __init omap_detect_sram(void)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
unsigned long sram_start;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (is_sram_locked()) {
|
||||
omap_sram_base = OMAP2_SRAM_PUB_VA;
|
||||
sram_start = OMAP2_SRAM_PUB_PA;
|
||||
omap_sram_size = 0x800; /* 2K */
|
||||
} else {
|
||||
omap_sram_base = OMAP2_SRAM_VA;
|
||||
sram_start = OMAP2_SRAM_PA;
|
||||
if (cpu_is_omap242x())
|
||||
omap_sram_size = 0xa0000; /* 640K */
|
||||
else if (cpu_is_omap243x())
|
||||
omap_sram_size = 0x10000; /* 64K */
|
||||
}
|
||||
} else {
|
||||
omap_sram_base = OMAP1_SRAM_VA;
|
||||
else
|
||||
omap_sram_base = OMAP2_SRAM_VA;
|
||||
sram_start = OMAP1_SRAM_PA;
|
||||
|
||||
if (cpu_is_omap730())
|
||||
omap_sram_size = 0x32000; /* 200K */
|
||||
else if (cpu_is_omap15xx())
|
||||
omap_sram_size = 0x30000; /* 192K */
|
||||
else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
|
||||
omap_sram_size = 0x4000; /* 16K */
|
||||
else if (cpu_is_omap1611())
|
||||
omap_sram_size = 0x3e800; /* 250K */
|
||||
else if (cpu_is_omap2420())
|
||||
omap_sram_size = 0xa0014; /* 640K */
|
||||
else {
|
||||
printk(KERN_ERR "Could not detect SRAM size\n");
|
||||
omap_sram_size = 0x4000;
|
||||
if (cpu_is_omap730())
|
||||
omap_sram_size = 0x32000; /* 200K */
|
||||
else if (cpu_is_omap15xx())
|
||||
omap_sram_size = 0x30000; /* 192K */
|
||||
else if (cpu_is_omap1610() || cpu_is_omap1621() ||
|
||||
cpu_is_omap1710())
|
||||
omap_sram_size = 0x4000; /* 16K */
|
||||
else if (cpu_is_omap1611())
|
||||
omap_sram_size = 0x3e800; /* 250K */
|
||||
else {
|
||||
printk(KERN_ERR "Could not detect SRAM size\n");
|
||||
omap_sram_size = 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ,
|
||||
omap_sram_size - SRAM_BOOTLOADER_SZ,
|
||||
&omap_fb_sram_start, &omap_fb_sram_size);
|
||||
if (omap_fb_sram_size)
|
||||
omap_sram_size -= sram_start + omap_sram_size -
|
||||
omap_fb_sram_start;
|
||||
omap_sram_ceil = omap_sram_base + omap_sram_size;
|
||||
}
|
||||
|
||||
@ -80,12 +169,20 @@ static struct map_desc omap_sram_io_desc[] __initdata = {
|
||||
*/
|
||||
void __init omap_map_sram(void)
|
||||
{
|
||||
unsigned long base;
|
||||
|
||||
if (omap_sram_size == 0)
|
||||
return;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
|
||||
omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
|
||||
|
||||
if (is_sram_locked())
|
||||
base = OMAP2_SRAM_PUB_PA;
|
||||
else
|
||||
base = OMAP2_SRAM_PA;
|
||||
base = ROUND_DOWN(base, PAGE_SIZE);
|
||||
omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
|
||||
}
|
||||
|
||||
omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
|
||||
@ -93,7 +190,8 @@ void __init omap_map_sram(void)
|
||||
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
|
||||
|
||||
printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
|
||||
omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
|
||||
__pfn_to_phys(omap_sram_io_desc[0].pfn),
|
||||
omap_sram_io_desc[0].virtual,
|
||||
omap_sram_io_desc[0].length);
|
||||
|
||||
/*
|
||||
@ -118,8 +216,9 @@ void * omap_sram_push(void * start, unsigned long size)
|
||||
printk(KERN_ERR "Not enough space in SRAM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
omap_sram_ceil -= size;
|
||||
omap_sram_ceil &= ~0x3;
|
||||
omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
|
||||
memcpy((void *)omap_sram_ceil, start, size);
|
||||
|
||||
return (void *)omap_sram_ceil;
|
||||
|
325
arch/arm/plat-omap/timer32k.c
Normal file
325
arch/arm/plat-omap/timer32k.c
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/timer32k.c
|
||||
*
|
||||
* OMAP 32K Timer
|
||||
*
|
||||
* Copyright (C) 2004 - 2005 Nokia Corporation
|
||||
* Partial timer rewrite and additional dynamic tick timer support by
|
||||
* Tony Lindgen <tony@atomide.com> and
|
||||
* Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
*
|
||||
* MPU timer code based on the older MPU timer code for OMAP
|
||||
* Copyright (C) 2000 RidgeRun, Inc.
|
||||
* Author: Greg Lonnon <glonnon@ridgerun.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/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/leds.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
struct sys_timer omap_timer;
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* 32KHz OS timer
|
||||
*
|
||||
* This currently works only on 16xx, as 1510 does not have the continuous
|
||||
* 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
|
||||
* of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
|
||||
* on 1510 would be possible, but the timer would not be as accurate as
|
||||
* with the 32KHz synchronized timer.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
|
||||
#elif defined(CONFIG_ARCH_OMAP24XX)
|
||||
#define TIMER_32K_SYNCHRONIZED 0x48004010
|
||||
#else
|
||||
#error OMAP 32KHz timer does not currently work on 15XX!
|
||||
#endif
|
||||
|
||||
/* 16xx specific defines */
|
||||
#define OMAP1_32K_TIMER_BASE 0xfffb9000
|
||||
#define OMAP1_32K_TIMER_CR 0x08
|
||||
#define OMAP1_32K_TIMER_TVR 0x00
|
||||
#define OMAP1_32K_TIMER_TCR 0x04
|
||||
|
||||
/* 24xx specific defines */
|
||||
#define OMAP2_GP_TIMER_BASE 0x48028000
|
||||
#define CM_CLKSEL_WKUP 0x48008440
|
||||
#define GP_TIMER_TIDR 0x00
|
||||
#define GP_TIMER_TISR 0x18
|
||||
#define GP_TIMER_TIER 0x1c
|
||||
#define GP_TIMER_TCLR 0x24
|
||||
#define GP_TIMER_TCRR 0x28
|
||||
#define GP_TIMER_TLDR 0x2c
|
||||
#define GP_TIMER_TTGR 0x30
|
||||
#define GP_TIMER_TSICR 0x40
|
||||
|
||||
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
|
||||
|
||||
/*
|
||||
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
|
||||
* so with HZ = 128, TVR = 255.
|
||||
*/
|
||||
#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
|
||||
|
||||
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
|
||||
(((nr_jiffies) * (clock_rate)) / HZ)
|
||||
|
||||
static inline void omap_32k_timer_write(int val, int reg)
|
||||
{
|
||||
if (cpu_class_is_omap1())
|
||||
omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
omap_writel(val, OMAP2_GP_TIMER_BASE + reg);
|
||||
}
|
||||
|
||||
static inline unsigned long omap_32k_timer_read(int reg)
|
||||
{
|
||||
if (cpu_class_is_omap1())
|
||||
return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
return omap_readl(OMAP2_GP_TIMER_BASE + reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* The 32KHz synchronized timer is an additional timer on 16xx.
|
||||
* It is always running.
|
||||
*/
|
||||
static inline unsigned long omap_32k_sync_timer_read(void)
|
||||
{
|
||||
return omap_readl(TIMER_32K_SYNCHRONIZED);
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_start(unsigned long load_val)
|
||||
{
|
||||
if (cpu_class_is_omap1()) {
|
||||
omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
|
||||
omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
|
||||
}
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR);
|
||||
omap_32k_timer_write((1 << 1), GP_TIMER_TIER);
|
||||
omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_stop(void)
|
||||
{
|
||||
if (cpu_class_is_omap1())
|
||||
omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
omap_32k_timer_write(0x0, GP_TIMER_TCLR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest usec. Note that this will overflow for larger values.
|
||||
*/
|
||||
static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (ticks_32k * 5*5*5*5*5*5) >> 9;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest nsec.
|
||||
*/
|
||||
static inline unsigned long long
|
||||
omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
|
||||
}
|
||||
|
||||
static unsigned long omap_32k_last_tick = 0;
|
||||
|
||||
/*
|
||||
* Returns elapsed usecs since last 32k timer interrupt
|
||||
*/
|
||||
static unsigned long omap_32k_timer_gettimeoffset(void)
|
||||
{
|
||||
unsigned long now = omap_32k_sync_timer_read();
|
||||
return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns current time from boot in nsecs. It's OK for this to wrap
|
||||
* around for now, as it's just a relative time stamp.
|
||||
*/
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
|
||||
}
|
||||
|
||||
/*
|
||||
* Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
|
||||
* function is also called from other interrupts to remove latency
|
||||
* issues with dynamic tick. In the dynamic tick case, we need to lock
|
||||
* with irqsave.
|
||||
*/
|
||||
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long now;
|
||||
|
||||
write_seqlock_irqsave(&xtime_lock, flags);
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
u32 status = omap_32k_timer_read(GP_TIMER_TISR);
|
||||
omap_32k_timer_write(status, GP_TIMER_TISR);
|
||||
}
|
||||
|
||||
now = omap_32k_sync_timer_read();
|
||||
|
||||
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
|
||||
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
|
||||
timer_tick(regs);
|
||||
}
|
||||
|
||||
/* Restart timer so we don't drift off due to modulo or dynamic tick.
|
||||
* By default we program the next timer to be continuous to avoid
|
||||
* latencies during high system load. During dynamic tick operation the
|
||||
* continuous timer can be overridden from pm_idle to be longer.
|
||||
*/
|
||||
omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
/*
|
||||
* Programs the next timer interrupt needed. Called when dynamic tick is
|
||||
* enabled, and to reprogram the ticks to skip from pm_idle. Note that
|
||||
* we can keep the timer continuous, and don't need to set it to run in
|
||||
* one-shot mode. This is because the timer will get reprogrammed again
|
||||
* after next interrupt.
|
||||
*/
|
||||
void omap_32k_timer_reprogram(unsigned long next_tick)
|
||||
{
|
||||
omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
|
||||
}
|
||||
|
||||
static struct irqaction omap_32k_timer_irq;
|
||||
extern struct timer_update_handler timer_update;
|
||||
|
||||
static int omap_32k_timer_enable_dyn_tick(void)
|
||||
{
|
||||
/* No need to reprogram timer, just use the next interrupt */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_32k_timer_disable_dyn_tick(void)
|
||||
{
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dyn_tick_timer omap_dyn_tick_timer = {
|
||||
.enable = omap_32k_timer_enable_dyn_tick,
|
||||
.disable = omap_32k_timer_disable_dyn_tick,
|
||||
.reprogram = omap_32k_timer_reprogram,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
#endif /* CONFIG_NO_IDLE_HZ */
|
||||
|
||||
static struct irqaction omap_32k_timer_irq = {
|
||||
.name = "32KHz timer",
|
||||
.flags = SA_INTERRUPT | SA_TIMER,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
|
||||
static struct clk * gpt1_ick;
|
||||
static struct clk * gpt1_fck;
|
||||
|
||||
static __init void omap_init_32k_timer(void)
|
||||
{
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
omap_timer.dyn_tick = &omap_dyn_tick_timer;
|
||||
#endif
|
||||
|
||||
if (cpu_class_is_omap1())
|
||||
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
|
||||
if (cpu_is_omap24xx())
|
||||
setup_irq(37, &omap_32k_timer_irq);
|
||||
omap_timer.offset = omap_32k_timer_gettimeoffset;
|
||||
omap_32k_last_tick = omap_32k_sync_timer_read();
|
||||
|
||||
/* REVISIT: Check 24xx TIOCP_CFG settings after idle works */
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap_32k_timer_write(0, GP_TIMER_TCLR);
|
||||
omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */
|
||||
|
||||
gpt1_ick = clk_get(NULL, "gpt1_ick");
|
||||
if (IS_ERR(gpt1_ick))
|
||||
printk(KERN_ERR "Could not get gpt1_ick\n");
|
||||
else
|
||||
clk_enable(gpt1_ick);
|
||||
|
||||
gpt1_fck = clk_get(NULL, "gpt1_fck");
|
||||
if (IS_ERR(gpt1_fck))
|
||||
printk(KERN_ERR "Could not get gpt1_fck\n");
|
||||
else
|
||||
clk_enable(gpt1_fck);
|
||||
|
||||
mdelay(100); /* Wait for clocks to stabilize */
|
||||
|
||||
omap_32k_timer_write(0x7, GP_TIMER_TISR);
|
||||
}
|
||||
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* Timer initialization
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void __init omap_timer_init(void)
|
||||
{
|
||||
omap_init_32k_timer();
|
||||
}
|
||||
|
||||
struct sys_timer omap_timer = {
|
||||
.init = omap_timer_init,
|
||||
.offset = NULL, /* Initialized later */
|
||||
};
|
@ -38,6 +38,8 @@ extern unsigned long at91_master_clock;
|
||||
extern int at91_serial_map[AT91_NR_UART];
|
||||
extern int at91_console_port;
|
||||
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
/* USB Device */
|
||||
struct at91_udc_data {
|
||||
u8 vbus_pin; /* high == host powering us */
|
||||
@ -77,4 +79,26 @@ struct at91_usbh_data {
|
||||
};
|
||||
extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
|
||||
|
||||
/* NAND / SmartMedia */
|
||||
struct at91_nand_data {
|
||||
u8 enable_pin; /* chip enable */
|
||||
u8 det_pin; /* card detect */
|
||||
u8 rdy_pin; /* ready/busy */
|
||||
u8 ale; /* address line number connected to ALE */
|
||||
u8 cle; /* address line number connected to CLE */
|
||||
struct mtd_partition* (*partition_info)(int, int*);
|
||||
};
|
||||
extern void __init at91_add_device_nand(struct at91_nand_data *data);
|
||||
|
||||
/* I2C*/
|
||||
void __init at91_add_device_i2c(void);
|
||||
|
||||
/* RTC */
|
||||
void __init at91_add_device_rtc(void);
|
||||
|
||||
/* LEDs */
|
||||
extern u8 at91_leds_cpu;
|
||||
extern u8 at91_leds_timer;
|
||||
extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,8 @@
|
||||
* febfc000 [67]0000000 4K NAND data register
|
||||
* febfb000 [67]0400000 4K NAND control register
|
||||
* febfa000 [67]0800000 4K NAND busy register
|
||||
* febf9000 10800000 4K TS-5620 RTC index register
|
||||
* febf8000 11700000 4K TS-5620 RTC data register
|
||||
*/
|
||||
|
||||
#define TS72XX_MODEL_PHYS_BASE 0x22000000
|
||||
@ -58,6 +60,15 @@
|
||||
#define TS72XX_NAND_BUSY_SIZE 0x00001000
|
||||
|
||||
|
||||
#define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000
|
||||
#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
|
||||
#define TS72XX_RTC_INDEX_SIZE 0x00001000
|
||||
|
||||
#define TS72XX_RTC_DATA_VIRT_BASE 0xfebf8000
|
||||
#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
|
||||
#define TS72XX_RTC_DATA_SIZE 0x00001000
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/io.h>
|
||||
|
||||
|
@ -17,27 +17,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_DMA_H
|
||||
#define __ASM_ARCH_DMA_H
|
||||
|
||||
/*
|
||||
* DMA registration
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
DMA_PRIO_HIGH = 0,
|
||||
DMA_PRIO_MEDIUM = 3,
|
||||
DMA_PRIO_LOW = 6
|
||||
DMA_PRIO_MEDIUM = 1,
|
||||
DMA_PRIO_LOW = 2
|
||||
} imx_dma_prio;
|
||||
|
||||
int imx_request_dma(char *name, imx_dma_prio prio,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *),
|
||||
void *data);
|
||||
|
||||
void imx_free_dma(int dma_ch);
|
||||
|
||||
|
||||
#define DMA_REQ_UART3_T 2
|
||||
#define DMA_REQ_UART3_R 3
|
||||
#define DMA_REQ_SSI2_T 4
|
||||
|
90
include/asm-arm/arch-imx/imx-dma.h
Normal file
90
include/asm-arm/arch-imx/imx-dma.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* linux/include/asm-arm/imxads/dma.h
|
||||
*
|
||||
* Copyright (C) 1997,1998 Russell King
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <asm/dma.h>
|
||||
|
||||
#ifndef __ASM_ARCH_IMX_DMA_H
|
||||
#define __ASM_ARCH_IMX_DMA_H
|
||||
|
||||
#define IMX_DMA_CHANNELS 11
|
||||
|
||||
/*
|
||||
* struct imx_dma_channel - i.MX specific DMA extension
|
||||
* @name: name specified by DMA client
|
||||
* @irq_handler: client callback for end of transfer
|
||||
* @err_handler: client callback for error condition
|
||||
* @data: clients context data for callbacks
|
||||
* @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
|
||||
* @sg: pointer to the actual read/written chunk for scatter-gather emulation
|
||||
* @sgbc: counter of processed bytes in the actual read/written chunk
|
||||
* @resbytes: total residual number of bytes to transfer
|
||||
* (it can be lower or same as sum of SG mapped chunk sizes)
|
||||
* @sgcount: number of chunks to be read/written
|
||||
*
|
||||
* Structure is used for IMX DMA processing. It would be probably good
|
||||
* @struct dma_struct in the future for external interfacing and use
|
||||
* @struct imx_dma_channel only as extension to it.
|
||||
*/
|
||||
|
||||
struct imx_dma_channel {
|
||||
const char *name;
|
||||
void (*irq_handler) (int, void *, struct pt_regs *);
|
||||
void (*err_handler) (int, void *, struct pt_regs *);
|
||||
void *data;
|
||||
dmamode_t dma_mode;
|
||||
struct scatterlist *sg;
|
||||
unsigned int sgbc;
|
||||
unsigned int sgcount;
|
||||
unsigned int resbytes;
|
||||
int dma_num;
|
||||
};
|
||||
|
||||
extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
|
||||
|
||||
|
||||
/* The type to distinguish channel numbers parameter from ordinal int type */
|
||||
typedef int imx_dmach_t;
|
||||
|
||||
int
|
||||
imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
|
||||
unsigned int dma_length, unsigned int dev_addr, dmamode_t dmamode);
|
||||
|
||||
int
|
||||
imx_dma_setup_sg(imx_dmach_t dma_ch,
|
||||
struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
|
||||
unsigned int dev_addr, dmamode_t dmamode);
|
||||
|
||||
int
|
||||
imx_dma_setup_handlers(imx_dmach_t dma_ch,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *), void *data);
|
||||
|
||||
void imx_dma_enable(imx_dmach_t dma_ch);
|
||||
|
||||
void imx_dma_disable(imx_dmach_t dma_ch);
|
||||
|
||||
int imx_dma_request(imx_dmach_t dma_ch, const char *name);
|
||||
|
||||
void imx_dma_free(imx_dmach_t dma_ch);
|
||||
|
||||
int imx_dma_request_by_prio(imx_dmach_t *pdma_ch, const char *name, imx_dma_prio prio);
|
||||
|
||||
|
||||
#endif /* _ASM_ARCH_IMX_DMA_H */
|
@ -28,6 +28,7 @@
|
||||
* to an address that the kernel can use.
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#define __virt_to_bus(v) \
|
||||
({ unsigned int ret; \
|
||||
@ -40,6 +41,22 @@
|
||||
data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \
|
||||
__phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
|
||||
|
||||
/*
|
||||
* Coherency support. Only supported on A2 CPUs or on A1
|
||||
* systems that have the cache coherency workaround.
|
||||
*/
|
||||
static inline int __ixp23xx_arch_is_coherent(void)
|
||||
{
|
||||
extern unsigned int processor_id;
|
||||
|
||||
if (((processor_id & 15) >= 2) || machine_is_roadrunner())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define arch_is_coherent() __ixp23xx_arch_is_coherent()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ void ixp23xx_sys_init(void);
|
||||
int ixp23xx_pci_setup(int, struct pci_sys_data *);
|
||||
void ixp23xx_pci_preinit(void);
|
||||
struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*);
|
||||
void ixp23xx_pci_slave_init(void);
|
||||
|
||||
extern struct sys_timer ixp23xx_timer;
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#define LHV_MIN 0x0000
|
||||
|
||||
// Analog audio path control register
|
||||
#define STA_REG(x) ((x)<<6)
|
||||
#define STE_ENABLED 0x0020
|
||||
#define DAC_SELECTED 0x0010
|
||||
#define BYPASS_ON 0x0008
|
||||
@ -109,4 +110,7 @@
|
||||
#define TLV320AIC23ID1 (0x1a) // cs low
|
||||
#define TLV320AIC23ID2 (0x1b) // cs high
|
||||
|
||||
void tlv320aic23_power_up(void);
|
||||
void tlv320aic23_power_down(void);
|
||||
|
||||
#endif /* __ASM_ARCH_AIC23_H */
|
||||
|
65
include/asm-arm/arch-omap/board-ams-delta.h
Normal file
65
include/asm-arm/arch-omap/board-ams-delta.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* linux/include/asm-arm/arch-omap/board-ams-delta.h
|
||||
*
|
||||
* Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
|
||||
*
|
||||
* 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 __ASM_ARCH_OMAP_AMS_DELTA_H
|
||||
#define __ASM_ARCH_OMAP_AMS_DELTA_H
|
||||
|
||||
#if defined (CONFIG_MACH_AMS_DELTA)
|
||||
|
||||
#define AMS_DELTA_LATCH1_PHYS 0x01000000
|
||||
#define AMS_DELTA_LATCH1_VIRT 0xEA000000
|
||||
#define AMS_DELTA_MODEM_PHYS 0x04000000
|
||||
#define AMS_DELTA_MODEM_VIRT 0xEB000000
|
||||
#define AMS_DELTA_LATCH2_PHYS 0x08000000
|
||||
#define AMS_DELTA_LATCH2_VIRT 0xEC000000
|
||||
|
||||
#define AMS_DELTA_LATCH1_LED_CAMERA 0x01
|
||||
#define AMS_DELTA_LATCH1_LED_ADVERT 0x02
|
||||
#define AMS_DELTA_LATCH1_LED_EMAIL 0x04
|
||||
#define AMS_DELTA_LATCH1_LED_HANDSFREE 0x08
|
||||
#define AMS_DELTA_LATCH1_LED_VOICEMAIL 0x10
|
||||
#define AMS_DELTA_LATCH1_LED_VOICE 0x20
|
||||
|
||||
#define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001
|
||||
#define AMS_DELTA_LATCH2_LCD_NDISP 0x0002
|
||||
#define AMS_DELTA_LATCH2_NAND_NCE 0x0004
|
||||
#define AMS_DELTA_LATCH2_NAND_NRE 0x0008
|
||||
#define AMS_DELTA_LATCH2_NAND_NWP 0x0010
|
||||
#define AMS_DELTA_LATCH2_NAND_NWE 0x0020
|
||||
#define AMS_DELTA_LATCH2_NAND_ALE 0x0040
|
||||
#define AMS_DELTA_LATCH2_NAND_CLE 0x0080
|
||||
#define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000
|
||||
#define AMS_DELTA_LATCH2_MODEM_CODEC 0x2000
|
||||
|
||||
#define AMS_DELTA_GPIO_PIN_NAND_RB 12
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
void ams_delta_latch1_write(u8 mask, u8 value);
|
||||
void ams_delta_latch2_write(u16 mask, u16 value);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_MACH_AMS_DELTA */
|
||||
|
||||
#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
|
45
include/asm-arm/arch-omap/board-apollon.h
Normal file
45
include/asm-arm/arch-omap/board-apollon.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* linux/include/asm-arm/arch-omap/board-apollon.h
|
||||
*
|
||||
* Hardware definitions for Samsung OMAP24XX Apollon board.
|
||||
*
|
||||
* Initial creation by Kyungmin Park <kyungmin.park@samsung.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.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_OMAP_APOLLON_H
|
||||
#define __ASM_ARCH_OMAP_APOLLON_H
|
||||
|
||||
/* Placeholder for APOLLON specific defines */
|
||||
/* GPMC CS0 */
|
||||
#define APOLLON_CS0_BASE 0x00000000
|
||||
/* GPMC CS1 */
|
||||
#define APOLLON_CS1_BASE 0x08000000
|
||||
#define APOLLON_ETHR_START (APOLLON_CS1_BASE + 0x300)
|
||||
#define APOLLON_ETHR_GPIO_IRQ 74
|
||||
/* GPMC CS2 - reserved for OneNAND */
|
||||
#define APOLLON_CS2_BASE 0x10000000
|
||||
/* GPMC CS3 - reserved for NOR or NAND */
|
||||
#define APOLLON_CS3_BASE 0x18000000
|
||||
|
||||
#endif /* __ASM_ARCH_OMAP_APOLLON_H */
|
||||
|
@ -34,9 +34,5 @@
|
||||
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
|
||||
#define OMAP1610_ETHR_START 0x04000300
|
||||
|
||||
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
|
||||
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
|
||||
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
|
||||
|
||||
#endif /* __ASM_ARCH_OMAP_H2_H */
|
||||
|
||||
|
@ -30,10 +30,6 @@
|
||||
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
|
||||
#define OMAP1710_ETHR_START 0x04000300
|
||||
|
||||
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
|
||||
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
|
||||
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
|
||||
|
||||
#define MAXIRQNUM (IH_BOARD_BASE)
|
||||
#define MAXFIQNUM MAXIRQNUM
|
||||
#define MAXSWINUM MAXIRQNUM
|
||||
|
@ -33,12 +33,6 @@
|
||||
/* GPMC CS1 */
|
||||
#define OMAP24XX_ETHR_START 0x08000300
|
||||
#define OMAP24XX_ETHR_GPIO_IRQ 92
|
||||
|
||||
#define H4_CS0_BASE 0x04000000
|
||||
|
||||
#define H4_CS0_BASE 0x04000000
|
||||
|
||||
#define H4_CS0_BASE 0x04000000
|
||||
|
||||
#define H4_CS0_BASE 0x04000000
|
||||
#endif /* __ASM_ARCH_OMAP_H4_H */
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
|
||||
*
|
||||
* Hardware definitions for OMAP5910 based NetStar board.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_NETSTAR_H
|
||||
#define __ASM_ARCH_NETSTAR_H
|
||||
|
||||
#include <asm/arch/tc.h>
|
||||
|
||||
#define OMAP_NAND_FLASH_START1 OMAP_CS1_PHYS + (1 << 23)
|
||||
#define OMAP_NAND_FLASH_START2 OMAP_CS1_PHYS + (2 << 23)
|
||||
|
||||
#endif /* __ASM_ARCH_NETSTAR_H */
|
54
include/asm-arm/arch-omap/board-nokia.h
Normal file
54
include/asm-arm/arch-omap/board-nokia.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* linux/include/asm-arm/arch-omap/board-nokia.h
|
||||
*
|
||||
* Information structures for Nokia-specific board config data
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef _OMAP_BOARD_NOKIA_H
|
||||
#define _OMAP_BOARD_NOKIA_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define OMAP_TAG_NOKIA_BT 0x4e01
|
||||
#define OMAP_TAG_WLAN_CX3110X 0x4e02
|
||||
#define OMAP_TAG_CBUS 0x4e03
|
||||
#define OMAP_TAG_EM_ASIC_BB5 0x4e04
|
||||
|
||||
|
||||
#define BT_CHIP_CSR 1
|
||||
#define BT_CHIP_TI 2
|
||||
|
||||
#define BT_SYSCLK_12 1
|
||||
#define BT_SYSCLK_38_4 2
|
||||
|
||||
struct omap_bluetooth_config {
|
||||
u8 chip_type;
|
||||
u8 bt_wakeup_gpio;
|
||||
u8 host_wakeup_gpio;
|
||||
u8 reset_gpio;
|
||||
u8 bt_uart;
|
||||
u8 bd_addr[6];
|
||||
u8 bt_sysclk;
|
||||
};
|
||||
|
||||
struct omap_wlan_cx3110x_config {
|
||||
u8 chip_type;
|
||||
s16 power_gpio;
|
||||
s16 irq_gpio;
|
||||
s16 spi_cs_gpio;
|
||||
};
|
||||
|
||||
struct omap_cbus_config {
|
||||
s16 clk_gpio;
|
||||
s16 dat_gpio;
|
||||
s16 sel_gpio;
|
||||
};
|
||||
|
||||
struct omap_em_asic_bb5_config {
|
||||
s16 retu_irq_gpio;
|
||||
s16 tahvo_irq_gpio;
|
||||
};
|
||||
|
||||
#endif
|
@ -42,8 +42,4 @@
|
||||
|
||||
#define NR_IRQS (MAXIRQNUM + 1)
|
||||
|
||||
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
|
||||
#define OMAP_NAND_FLASH_START1 0x0A000000 /* CS2B */
|
||||
#define OMAP_NAND_FLASH_START2 0x0C000000 /* CS3 */
|
||||
|
||||
#endif
|
||||
|
@ -21,9 +21,12 @@
|
||||
#define OMAP_TAG_LCD 0x4f05
|
||||
#define OMAP_TAG_GPIO_SWITCH 0x4f06
|
||||
#define OMAP_TAG_UART 0x4f07
|
||||
#define OMAP_TAG_FBMEM 0x4f08
|
||||
#define OMAP_TAG_STI_CONSOLE 0x4f09
|
||||
|
||||
#define OMAP_TAG_BOOT_REASON 0x4f80
|
||||
#define OMAP_TAG_FLASH_PART 0x4f81
|
||||
#define OMAP_TAG_VERSION_STR 0x4f82
|
||||
|
||||
struct omap_clock_config {
|
||||
/* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
|
||||
@ -54,6 +57,11 @@ struct omap_serial_console_config {
|
||||
u32 console_speed;
|
||||
};
|
||||
|
||||
struct omap_sti_console_config {
|
||||
unsigned enable:1;
|
||||
u8 channel;
|
||||
};
|
||||
|
||||
struct omap_usb_config {
|
||||
/* Configure drivers according to the connectors on your board:
|
||||
* - "A" connector (rectagular)
|
||||
@ -87,6 +95,13 @@ struct omap_lcd_config {
|
||||
char ctrl_name[16];
|
||||
};
|
||||
|
||||
struct omap_fbmem_config {
|
||||
u32 fb_sram_start;
|
||||
u32 fb_sram_size;
|
||||
u32 fb_sdram_start;
|
||||
u32 fb_sdram_size;
|
||||
};
|
||||
|
||||
/* Cover:
|
||||
* high -> closed
|
||||
* low -> open
|
||||
@ -106,6 +121,12 @@ struct omap_gpio_switch_config {
|
||||
int key_code:24; /* Linux key code */
|
||||
};
|
||||
|
||||
struct omap_uart_config {
|
||||
/* Bit field of UARTs present; bit 0 --> UART1 */
|
||||
unsigned int enabled_uarts;
|
||||
};
|
||||
|
||||
|
||||
struct omap_flash_part_config {
|
||||
char part_table[0];
|
||||
};
|
||||
@ -114,11 +135,14 @@ struct omap_boot_reason_config {
|
||||
char reason_str[12];
|
||||
};
|
||||
|
||||
struct omap_uart_config {
|
||||
/* Bit field of UARTs present; bit 0 --> UART1 */
|
||||
unsigned int enabled_uarts;
|
||||
struct omap_version_config {
|
||||
char component[12];
|
||||
char version[12];
|
||||
};
|
||||
|
||||
|
||||
#include <asm-arm/arch-omap/board-nokia.h>
|
||||
|
||||
struct omap_board_config_entry {
|
||||
u16 tag;
|
||||
u16 len;
|
||||
|
@ -19,6 +19,7 @@ struct clk {
|
||||
struct list_head node;
|
||||
struct module *owner;
|
||||
const char *name;
|
||||
int id;
|
||||
struct clk *parent;
|
||||
unsigned long rate;
|
||||
__u32 flags;
|
||||
@ -57,6 +58,7 @@ extern void propagate_rate(struct clk *clk);
|
||||
extern void followparent_recalc(struct clk * clk);
|
||||
extern void clk_allow_idle(struct clk *clk);
|
||||
extern void clk_deny_idle(struct clk *clk);
|
||||
extern int clk_get_usecount(struct clk *clk);
|
||||
|
||||
/* Clock flags */
|
||||
#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
|
||||
@ -80,10 +82,11 @@ extern void clk_deny_idle(struct clk *clk);
|
||||
#define CM_PLL_SEL1 (1 << 18)
|
||||
#define CM_PLL_SEL2 (1 << 19)
|
||||
#define CM_SYSCLKOUT_SEL1 (1 << 20)
|
||||
#define CLOCK_IN_OMAP730 (1 << 21)
|
||||
#define CLOCK_IN_OMAP1510 (1 << 22)
|
||||
#define CLOCK_IN_OMAP16XX (1 << 23)
|
||||
#define CLOCK_IN_OMAP242X (1 << 24)
|
||||
#define CLOCK_IN_OMAP243X (1 << 25)
|
||||
#define CLOCK_IN_OMAP310 (1 << 21)
|
||||
#define CLOCK_IN_OMAP730 (1 << 22)
|
||||
#define CLOCK_IN_OMAP1510 (1 << 23)
|
||||
#define CLOCK_IN_OMAP16XX (1 << 24)
|
||||
#define CLOCK_IN_OMAP242X (1 << 25)
|
||||
#define CLOCK_IN_OMAP243X (1 << 26)
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user