Commit a144a563 authored by Russell King's avatar Russell King Committed by Russell King

Merge omap tree

* master.kernel.org:/pub/scm/linux/kernel/git/tmlind/linux-omap-upstream: (26 commits)
  ARM: OMAP: Multiplexing for 24xx GPMC wait pin monitoring
  ARM: OMAP: Fix SRAM to use MT_MEMORY instead of MT_DEVICE
  ARM: OMAP: Update dmtimers
  ARM: OMAP: Make clock variables static
  ARM: OMAP: Fix GPMC compilation when DEBUG is defined
  ARM: OMAP: Mux updates for external DMA and GPIO
  ARM: OMAP: Add OMAP_TAG_CAMERA_SENSOR
  ARM: OMAP: Add initial 24xx suspend support
  ARM: OMAP: Update cpufreq support for 24xx
  ARM: OMAP: Add GPMC support for OMAP2
  ARM: OMAP: Fix DMA channel irq handling for omap24xx
  ARM: OMAP: OMAP2 DMA burst support
  ARM: OMAP: Fix 32 kHz timer and modify GP timer to use GPT1
  ARM: OMAP: Port dmtimers to OMAP2 and implement PWM support
  ARM: OMAP: Correct two bugs in arch/arm/mach-omap2/clock.c
  ARM: OMAP: Register the 24xx McSPI device
  ARM: OMAP: Add bitbank SPI driver for Innovator 1510 touchscreen
  ARM: OMAP: Aic23 alsa platform driver code for board-innovator
  ARM: OMAP: Fix GPIO IRQ mask handling
  ARM: OMAP: DMA transfer parameter configuration fix
  ...
parents 8fc5ffa0 3cbc9605
...@@ -678,7 +678,7 @@ config XIP_PHYS_ADDR ...@@ -678,7 +678,7 @@ config XIP_PHYS_ADDR
endmenu endmenu
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1) if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
menu "CPU Frequency scaling" menu "CPU Frequency scaling"
......
...@@ -62,6 +62,13 @@ config MACH_OMAP_PERSEUS2 ...@@ -62,6 +62,13 @@ config MACH_OMAP_PERSEUS2
Support for TI OMAP 730 Perseus2 board. Say Y here if you have such Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
a board. a board.
config MACH_OMAP_FSAMPLE
bool "TI F-Sample"
depends on ARCH_OMAP1 && ARCH_OMAP730
help
Support for TI OMAP 850 F-Sample board. Say Y here if you have such
a board.
config MACH_VOICEBLUE config MACH_VOICEBLUE
bool "Voiceblue" bool "Voiceblue"
depends on ARCH_OMAP1 && ARCH_OMAP15XX depends on ARCH_OMAP1 && ARCH_OMAP15XX
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
obj-$(CONFIG_MACH_OMAP_FSAMPLE) += board-fsample.o
obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
......
...@@ -80,8 +80,15 @@ static struct omap_uart_config ams_delta_uart_config __initdata = { ...@@ -80,8 +80,15 @@ static struct omap_uart_config ams_delta_uart_config __initdata = {
.enabled_uarts = 1, .enabled_uarts = 1,
}; };
static struct omap_usb_config ams_delta_usb_config __initdata = {
.register_host = 1,
.hmc_mode = 16,
.pins[0] = 2,
};
static struct omap_board_config_kernel ams_delta_config[] = { static struct omap_board_config_kernel ams_delta_config[] = {
{ OMAP_TAG_UART, &ams_delta_uart_config }, { OMAP_TAG_UART, &ams_delta_uart_config },
{ OMAP_TAG_USB, &ams_delta_usb_config },
}; };
static struct platform_device ams_delta_led_device = { static struct platform_device ams_delta_led_device = {
......
/*
* linux/arch/arm/mach-omap1/board-fsample.c
*
* Modified from board-perseus2.c
*
* Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
* Updated for 2.6 by Kevin Hilman <kjh@hilman.org>
*
* 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/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>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/arch/tc.h>
#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>
#include <asm/arch/board-fsample.h>
static int fsample_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 */
.end = H2P2_DBG_FPGA_ETHR_START + 0xf,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = INT_730_MPU_EXT_NIRQ,
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct mtd_partition nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
.name = "bootloader",
.offset = 0,
.size = SZ_128K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* bootloader params in the next sector */
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = SZ_128K,
.mask_flags = 0,
},
/* kernel */
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_2M,
.mask_flags = 0
},
/* rest of flash is a file system */
{
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0
},
};
static struct flash_platform_data nor_data = {
.map_name = "cfi_probe",
.width = 2,
.parts = nor_partitions,
.nr_parts = ARRAY_SIZE(nor_partitions),
};
static struct resource nor_resource = {
.start = OMAP_CS0_PHYS,
.end = OMAP_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device nor_device = {
.name = "omapflash",
.id = 0,
.dev = {
.platform_data = &nor_data,
},
.num_resources = 1,
.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 = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
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 = fsample_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 fsample_uart_config __initdata = {
.enabled_uarts = ((1 << 0) | (1 << 1)),
};
static struct omap_lcd_config fsample_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_board_config_kernel fsample_config[] = {
{ OMAP_TAG_UART, &fsample_uart_config },
{ OMAP_TAG_LCD, &fsample_lcd_config },
};
static void __init omap_fsample_init(void)
{
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 = fsample_config;
omap_board_config_size = ARRAY_SIZE(fsample_config);
omap_serial_init();
}
static void __init fsample_init_smc91x(void)
{
fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
mdelay(50);
fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
H2P2_DBG_FPGA_LAN_RESET);
mdelay(50);
}
void omap_fsample_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
omap_gpio_init();
fsample_init_smc91x();
}
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc omap_fsample_io_desc[] __initdata = {
{
.virtual = H2P2_DBG_FPGA_BASE,
.pfn = __phys_to_pfn(H2P2_DBG_FPGA_START),
.length = H2P2_DBG_FPGA_SIZE,
.type = MT_DEVICE
},
{
.virtual = FSAMPLE_CPLD_BASE,
.pfn = __phys_to_pfn(FSAMPLE_CPLD_START),
.length = FSAMPLE_CPLD_SIZE,
.type = MT_DEVICE
}
};
static void __init omap_fsample_map_io(void)
{
omap1_map_common_io();
iotable_init(omap_fsample_io_desc,
ARRAY_SIZE(omap_fsample_io_desc));
/* Early, board-dependent init */
/*
* Hold GSM Reset until needed
*/
omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
/*
* UARTs -> done automagically by 8250 driver
*/
/*
* CSx timings, GPIO Mux ... setup
*/
/* Flash: CS0 timings setup */
omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
/*
* Ethernet support through the debug board
* CS1 timings setup
*/
omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
/*
* Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
* It is used as the Ethernet controller interrupt
*/
omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
}
MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
/* Maintainer: Brian Swetland <swetland@google.com> */
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_fsample_map_io,
.init_irq = omap_fsample_init_irq,
.init_machine = omap_fsample_init,
.timer = &omap_timer,
MACHINE_END
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <asm/arch/usb.h> #include <asm/arch/usb.h>
#include <asm/arch/keypad.h> #include <asm/arch/keypad.h>
#include <asm/arch/common.h> #include <asm/arch/common.h>
#include <asm/arch/mcbsp.h>
#include <asm/arch/omap-alsa.h>
static int innovator_keymap[] = { static int innovator_keymap[] = {
KEY(0, 0, KEY_F1), KEY(0, 0, KEY_F1),
...@@ -112,6 +114,42 @@ static struct platform_device innovator_flash_device = { ...@@ -112,6 +114,42 @@ static struct platform_device innovator_flash_device = {
.resource = &innovator_flash_resource, .resource = &innovator_flash_resource,
}; };
#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 = "OMAP Innovator 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 innovator_mcbsp1_device = {
.name = "omap_alsa_mcbsp",
.id = 1,
.dev = {
.platform_data = &alsa_config,
},
};
static struct resource innovator_kp_resources[] = { static struct resource innovator_kp_resources[] = {
[0] = { [0] = {
.start = INT_KEYBOARD, .start = INT_KEYBOARD,
...@@ -139,6 +177,10 @@ static struct platform_device innovator_kp_device = { ...@@ -139,6 +177,10 @@ static struct platform_device innovator_kp_device = {
#ifdef CONFIG_ARCH_OMAP15XX #ifdef CONFIG_ARCH_OMAP15XX
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
/* Only FPGA needs to be mapped here. All others are done with ioremap */ /* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc[] __initdata = { static struct map_desc innovator1510_io_desc[] __initdata = {
{ {
...@@ -174,13 +216,44 @@ static struct platform_device innovator1510_lcd_device = { ...@@ -174,13 +216,44 @@ static struct platform_device innovator1510_lcd_device = {
.id = -1, .id = -1,
}; };
static struct platform_device innovator1510_spi_device = {
.name = "spi_inn1510",
.id = -1,
};
static struct platform_device *innovator1510_devices[] __initdata = { static struct platform_device *innovator1510_devices[] __initdata = {
&innovator_flash_device, &innovator_flash_device,
&innovator1510_smc91x_device, &innovator1510_smc91x_device,
&innovator_mcbsp1_device,
&innovator_kp_device, &innovator_kp_device,
&innovator1510_lcd_device, &innovator1510_lcd_device,
&innovator1510_spi_device,
}; };
static int innovator_get_pendown_state(void)
{
return !(fpga_read(OMAP1510_FPGA_TOUCHSCREEN) & (1 << 5));
}
static const struct ads7846_platform_data innovator1510_ts_info = {
.model = 7846,
.vref_delay_usecs = 100, /* internal, no capacitor */
.x_plate_ohms = 419,
.y_plate_ohms = 486,
.get_pendown_state = innovator_get_pendown_state,
};
static struct spi_board_info __initdata innovator1510_boardinfo[] = { {
/* FPGA (bus "10") CS0 has an ads7846e */
.modalias = "ads7846",
.platform_data = &innovator1510_ts_info,
.irq = OMAP1510_INT_FPGA_TS,
.max_speed_hz = 120000 /* max sample rate at 3V */
* 26 /* command + data + overhead */,
.bus_num = 10,
.chip_select = 0,
} };
#endif /* CONFIG_ARCH_OMAP15XX */ #endif /* CONFIG_ARCH_OMAP15XX */
#ifdef CONFIG_ARCH_OMAP16XX #ifdef CONFIG_ARCH_OMAP16XX
...@@ -311,6 +384,8 @@ static void __init innovator_init(void) ...@@ -311,6 +384,8 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX #ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) { if (cpu_is_omap1510()) {
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
spi_register_board_info(innovator1510_boardinfo,
ARRAY_SIZE(innovator1510_boardinfo));
} }
#endif #endif
#ifdef CONFIG_ARCH_OMAP16XX #ifdef CONFIG_ARCH_OMAP16XX
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -45,25 +44,10 @@ ...@@ -45,25 +44,10 @@
#include <asm/arch/usb.h> #include <asm/arch/usb.h>
#include <asm/arch/mux.h> #include <asm/arch/mux.h>
#include <asm/arch/tc.h> #include <asm/arch/tc.h>
#include <asm/arch/keypad.h>
#include <asm/arch/common.h> #include <asm/arch/common.h>
#include <asm/arch/mcbsp.h> #include <asm/arch/mcbsp.h>
#include <asm/arch/omap-alsa.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[] = { static struct mtd_partition osk_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */ /* bootloader (U-Boot, etc) in first sector */
{ {
...@@ -187,42 +171,11 @@ static struct platform_device osk5912_mcbsp1_device = { ...@@ -187,42 +171,11 @@ static struct platform_device osk5912_mcbsp1_device = {
}, },
}; };
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 = { static struct platform_device *osk5912_devices[] __initdata = {
&osk5912_flash_device, &osk5912_flash_device,
&osk5912_smc91x_device, &osk5912_smc91x_device,
&osk5912_cf_device, &osk5912_cf_device,
&osk5912_mcbsp1_device, &osk5912_mcbsp1_device,
&osk5912_kp_device,
&osk5912_lcd_device,
}; };
static void __init osk_init_smc91x(void) static void __init osk_init_smc91x(void)
...@@ -276,18 +229,100 @@ static struct omap_uart_config osk_uart_config __initdata = { ...@@ -276,18 +229,100 @@ static struct omap_uart_config osk_uart_config __initdata = {
.enabled_uarts = (1 << 0), .enabled_uarts = (1 << 0),
}; };
#ifdef CONFIG_OMAP_OSK_MISTRAL
static struct omap_lcd_config osk_lcd_config __initdata = { static struct omap_lcd_config osk_lcd_config __initdata = {
.ctrl_name = "internal", .ctrl_name = "internal",
}; };
#endif
static struct omap_board_config_kernel osk_config[] = { static struct omap_board_config_kernel osk_config[] = {
{ OMAP_TAG_USB, &osk_usb_config }, { OMAP_TAG_USB, &osk_usb_config },
{ OMAP_TAG_UART, &osk_uart_config }, { OMAP_TAG_UART, &osk_uart_config },
#ifdef CONFIG_OMAP_OSK_MISTRAL
{ OMAP_TAG_LCD, &osk_lcd_config }, { OMAP_TAG_LCD, &osk_lcd_config },
#endif
}; };
#ifdef CONFIG_OMAP_OSK_MISTRAL #ifdef CONFIG_OMAP_OSK_MISTRAL
#include <linux/input.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <asm/arch/keypad.h>
static const int osk_keymap[] = {
/* KEY(col, row, code) */
KEY(0, 0, KEY_F1), /* SW4 */
KEY(0, 3, KEY_UP), /* (sw2/up) */
KEY(1, 1, KEY_LEFTCTRL), /* SW5 */
KEY(1, 2, KEY_LEFT), /* (sw2/left) */
KEY(2, 0, KEY_SPACE), /* SW3 */
KEY(2, 1, KEY_ESC), /* SW6 */
KEY(2, 2, KEY_DOWN), /* (sw2/down) */
KEY(3, 2, KEY_ENTER), /* (sw2/select) */
KEY(3, 3, KEY_RIGHT), /* (sw2/right) */
0
};
static struct omap_kp_platform_data osk_kp_data = {
.rows = 8,
.cols = 8,
.keymap = (int *) osk_keymap,
};
static struct resource osk5912_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
.end = INT_KEYBOARD,
.flags = IORESOURCE_IRQ,
},
};
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 *mistral_devices[] __initdata = {
&osk5912_kp_device,
&osk5912_lcd_device,
};
static int mistral_get_pendown_state(void)
{
return !omap_get_gpio_datain(4);
}
static const struct ads7846_platform_data mistral_ts_info = {
.model = 7846,
.vref_delay_usecs = 100, /* internal, no capacitor */
.x_plate_ohms = 419,
.y_plate_ohms = 486,
.get_pendown_state = mistral_get_pendown_state,
};
static struct spi_board_info __initdata mistral_boardinfo[] = { {
/* MicroWire (bus 2) CS0 has an ads7846e */
.modalias = "ads7846",
.platform_data = &mistral_ts_info,
.irq = OMAP_GPIO_IRQ(4),
.max_speed_hz = 120000 /* max sample rate at 3V */
* 26 /* command + data + overhead */,
.bus_num = 2,
.chip_select = 0,
} };
#ifdef CONFIG_PM #ifdef CONFIG_PM
static irqreturn_t static irqreturn_t
osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
...@@ -298,14 +333,18 @@ osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) ...@@ -298,14 +333,18 @@ osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
static void __init osk_mistral_init(void) static void __init osk_mistral_init(void)
{ {
/* FIXME here's where to feed in framebuffer, touchpad, and /* NOTE: we could actually tell if there's a Mistral board
* keyboard setup ... not in the drivers for those devices!
*
* NOTE: we could actually tell if there's a Mistral board
* attached, e.g. by trying to read something from the ads7846. * attached, e.g. by trying to read something from the ads7846.
* But this is too early for that... * But this arch_init() code is too early for that, since we
* can't talk to the ads or even the i2c eeprom.
*/ */
// omap_cfg_reg(P19_1610_GPIO6); // BUSY
omap_cfg_reg(P20_1610_GPIO4); // PENIRQ
set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING);
spi_register_board_info(mistral_boardinfo,
ARRAY_SIZE(mistral_boardinfo));
/* the sideways button (SW1) is for use as a "wakeup" button */ /* the sideways button (SW1) is for use as a "wakeup" button */
omap_cfg_reg(N15_1610_MPUIO2); omap_cfg_reg(N15_1610_MPUIO2);
if (omap_request_gpio(OMAP_MPUIO(2)) == 0) { if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
...@@ -329,6 +368,8 @@ static void __init osk_mistral_init(void) ...@@ -329,6 +368,8 @@ static void __init osk_mistral_init(void)
#endif #endif
} else } else
printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n"); printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices));
} }
#else #else
static void __init osk_mistral_init(void) { } static void __init osk_mistral_init(void) { }
......
//kernel/linux-omap-fsample/arch/arm/mach-omap1/clock.c#2 - edit change 3808 (text)
/* /*
* linux/arch/arm/mach-omap1/clock.c * linux/arch/arm/mach-omap1/clock.c
* *
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/usb.h> #include <asm/arch/usb.h>
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
#include <asm/arch/sram.h> #include <asm/arch/sram.h>
...@@ -270,7 +272,11 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate) ...@@ -270,7 +272,11 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
/* /*
* In most cases we should not need to reprogram DPLL. * In most cases we should not need to reprogram DPLL.
* Reprogramming the DPLL is tricky, it must be done from SRAM. * Reprogramming the DPLL is tricky, it must be done from SRAM.
* (on 730, bit 13 must always be 1)
*/ */
if (cpu_is_omap730())
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000);
else
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
ck_dpll1.rate = ptr->pll_rate; ck_dpll1.rate = ptr->pll_rate;
...@@ -748,7 +754,7 @@ int __init omap1_clk_init(void) ...@@ -748,7 +754,7 @@ int __init omap1_clk_init(void)
printk(KERN_ERR "System frequencies not set. Check your config.\n"); printk(KERN_ERR "System frequencies not set. Check your config.\n");
/* Guess sane values (60MHz) */ /* Guess sane values (60MHz) */
omap_writew(0x2290, DPLL_CTL); omap_writew(0x2290, DPLL_CTL);
omap_writew(0x1005, ARM_CKCTL); omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
ck_dpll1.rate = 60000000; ck_dpll1.rate = 60000000;
propagate_rate(&ck_dpll1); propagate_rate(&ck_dpll1);
} }
...@@ -761,12 +767,16 @@ int __init omap1_clk_init(void) ...@@ -761,12 +767,16 @@ int __init omap1_clk_init(void)
ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
#ifdef CONFIG_MACH_OMAP_PERSEUS2 #if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
/* Select slicer output as OMAP input clock */ /* Select slicer output as OMAP input clock */
omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
#endif #endif
/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
/* (on 730, bit 13 must not be cleared) */
if (cpu_is_omap730())
omap_writew(omap_readw(ARM_CKCTL) & 0x2fff, ARM_CKCTL);
else
omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL); omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
/* Put DSP/MPUI into reset until needed */ /* Put DSP/MPUI into reset until needed */
......
//kernel/linux-omap-fsample/arch/arm/mach-omap1/pm.c#3 - integrate change 4545 (text)
/* /*
* linux/arch/arm/mach-omap1/pm.c * linux/arch/arm/mach-omap1/pm.c
* *
...@@ -50,6 +51,7 @@ ...@@ -50,6 +51,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/arch/cpu.h>
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
#include <asm/arch/sram.h> #include <asm/arch/sram.h>
...@@ -327,6 +329,7 @@ void omap_pm_suspend(void) ...@@ -327,6 +329,7 @@ void omap_pm_suspend(void)
omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1); omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
/* shut down dsp_ck */ /* shut down dsp_ck */
if (!cpu_is_omap730())
omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL); omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
/* temporarily enabling api_ck to access DSP registers */ /* temporarily enabling api_ck to access DSP registers */
......
...@@ -94,7 +94,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) ...@@ -94,7 +94,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
* will break. On P2, the timer count rate is 6.5 MHz after programming PTV * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
* with 0. This divides the 13MHz input by 2, and is undocumented. * with 0. This divides the 13MHz input by 2, and is undocumented.
*/ */
#ifdef CONFIG_MACH_OMAP_PERSEUS2 #if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
/* REVISIT: This ifdef construct should be replaced by a query to clock /* REVISIT: This ifdef construct should be replaced by a query to clock
* framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz. * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
*/ */
......
...@@ -8,6 +8,7 @@ config ARCH_OMAP24XX ...@@ -8,6 +8,7 @@ config ARCH_OMAP24XX
config ARCH_OMAP2420 config ARCH_OMAP2420
bool "OMAP2420 support" bool "OMAP2420 support"
depends on ARCH_OMAP24XX depends on ARCH_OMAP24XX
select OMAP_DM_TIMER
comment "OMAP Board Type" comment "OMAP Board Type"
depends on ARCH_OMAP2 depends on ARCH_OMAP2
......
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
# #
# Common support # Common support
obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.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 gpmc.o
obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
# Specific board support # Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
......
...@@ -660,26 +660,35 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) ...@@ -660,26 +660,35 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
/* Isolate control register */ /* Isolate control register */
div_sel = (SRC_RATE_SEL_MASK & clk->flags); div_sel = (SRC_RATE_SEL_MASK & clk->flags);
div_off = clk->src_offset; div_off = clk->rate_offset;
validrate = omap2_clksel_round_rate(clk, rate, &new_div); validrate = omap2_clksel_round_rate(clk, rate, &new_div);
if(validrate != rate) if (validrate != rate)
return(ret); return(ret);
field_val = omap2_get_clksel(&div_sel, &field_mask, clk); field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
if (div_sel == 0) if (div_sel == 0)
return ret; return ret;
if(clk->flags & CM_SYSCLKOUT_SEL1){ if (clk->flags & CM_SYSCLKOUT_SEL1) {
switch(new_div){ switch (new_div) {
case 16: field_val = 4; break; case 16:
case 8: field_val = 3; break; field_val = 4;
case 4: field_val = 2; break; break;
case 2: field_val = 1; break; case 8:
case 1: field_val = 0; break; field_val = 3;
} break;
case 4:
field_val = 2;
break;
case 2:
field_val = 1;
break;
case 1:
field_val = 0;
break;
} }
else } else
field_val = new_div; field_val = new_div;
reg = (void __iomem *)div_sel; reg = (void __iomem *)div_sel;
...@@ -744,7 +753,7 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset, ...@@ -744,7 +753,7 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
val = 0x2; val = 0x2;
break; break;
case CM_WKUP_SEL1: case CM_WKUP_SEL1:
src_reg_addr = (u32)&CM_CLKSEL2_CORE; src_reg_addr = (u32)&CM_CLKSEL_WKUP;
mask = 0x3; mask = 0x3;
if (src_clk == &func_32k_ck) if (src_clk == &func_32k_ck)
val = 0x0; val = 0x0;
...@@ -784,9 +793,9 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset, ...@@ -784,9 +793,9 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
val = 0; val = 0;
if (src_clk == &sys_ck) if (src_clk == &sys_ck)
val = 1; val = 1;
if (src_clk == &func_54m_ck)
val = 2;
if (src_clk == &func_96m_ck) if (src_clk == &func_96m_ck)
val = 2;
if (src_clk == &func_54m_ck)
val = 3; val = 3;
break; break;
} }
......
...@@ -1062,7 +1062,7 @@ static struct clk gpt2_ick = { ...@@ -1062,7 +1062,7 @@ static struct clk gpt2_ick = {
.parent = &l4_ck, .parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit4 */ .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit4 */
.enable_bit = 0, .enable_bit = 4,
.recalc = &omap2_followparent_recalc, .recalc = &omap2_followparent_recalc,
}; };
......
...@@ -105,6 +105,51 @@ static inline void omap_init_sti(void) ...@@ -105,6 +105,51 @@ static inline void omap_init_sti(void)
static inline void omap_init_sti(void) {} static inline void omap_init_sti(void) {}
#endif #endif
#if defined(CONFIG_SPI_OMAP24XX)
#include <asm/arch/mcspi.h>
#define OMAP2_MCSPI1_BASE 0x48098000
#define OMAP2_MCSPI2_BASE 0x4809a000
/* FIXME: use resources instead */
static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
.base = io_p2v(OMAP2_MCSPI1_BASE),
.num_cs = 4,
};
struct platform_device omap2_mcspi1 = {
.name = "omap2_mcspi",
.id = 1,
.dev = {
.platform_data = &omap2_mcspi1_config,
},
};
static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
.base = io_p2v(OMAP2_MCSPI2_BASE),
.num_cs = 2,
};
struct platform_device omap2_mcspi2 = {
.name = "omap2_mcspi",
.id = 2,
.dev = {
.platform_data = &omap2_mcspi2_config,
},
};
static void omap_init_mcspi(void)
{
platform_device_register(&omap2_mcspi1);
platform_device_register(&omap2_mcspi2);
}
#else
static inline void omap_init_mcspi(void) {}
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void) static int __init omap2_init_devices(void)
...@@ -113,6 +158,7 @@ static int __init omap2_init_devices(void) ...@@ -113,6 +158,7 @@ static int __init omap2_init_devices(void)
* in alphabetical order so they're easier to sort through. * in alphabetical order so they're easier to sort through.
*/ */
omap_init_i2c(); omap_init_i2c();
omap_init_mcspi();
omap_init_sti(); omap_init_sti();
return 0; return 0;
......
/*
* GPMC support functions
*
* Copyright (C) 2005-2006 Nokia Corporation
*
* Author: Juha Yrjola
*
* 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/err.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/arch/gpmc.h>
#undef DEBUG
#define GPMC_BASE 0x6800a000
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
#define GPMC_IRQSTATUS 0x18
#define GPMC_IRQENABLE 0x1c
#define GPMC_TIMEOUT_CONTROL 0x40
#define GPMC_ERR_ADDRESS 0x44
#define GPMC_ERR_TYPE 0x48
#define GPMC_CONFIG 0x50
#define GPMC_STATUS 0x54
#define GPMC_PREFETCH_CONFIG1 0x1e0
#define GPMC_PREFETCH_CONFIG2 0x1e4
#define GPMC_PREFETCH_CONTROL 0x1e8
#define GPMC_PREFETCH_STATUS 0x1f0
#define GPMC_ECC_CONFIG 0x1f4
#define GPMC_ECC_CONTROL 0x1f8
#define GPMC_ECC_SIZE_CONFIG 0x1fc
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
static void __iomem *gpmc_base =
(void __iomem *) IO_ADDRESS(GPMC_BASE);
static void __iomem *gpmc_cs_base =
(void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0;
static struct clk *gpmc_l3_clk;
static void gpmc_write_reg(int idx, u32 val)
{
__raw_writel(val, gpmc_base + idx);
}
static u32 gpmc_read_reg(int idx)
{
return __raw_readl(gpmc_base + idx);
}
void gpmc_cs_write_reg(int cs, int idx, u32 val)
{
void __iomem *reg_addr;
reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx;
__raw_writel(val, reg_addr);
}
u32 gpmc_cs_read_reg(int cs, int idx)
{
return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx);
}
/* TODO: Add support for gpmc_fck to clock framework and use it */
static unsigned long gpmc_get_fclk_period(void)
{
/* In picoseconds */
return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000);
}
unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
{
unsigned long tick_ps;
/* Calculate in picosecs to yield more exact results */
tick_ps = gpmc_get_fclk_period();
return (time_ns * 1000 + tick_ps - 1) / tick_ps;
}
#ifdef DEBUG
static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
int time, const char *name)
#else
static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
int time)
#endif
{
u32 l;
int ticks, mask, nr_bits;
if (time == 0)
ticks = 0;
else
ticks = gpmc_ns_to_ticks(time);
nr_bits = end_bit - st_bit + 1;
if (ticks >= 1 << nr_bits)
return -1;
mask = (1 << nr_bits) - 1;
l = gpmc_cs_read_reg(cs, reg);
#ifdef DEBUG
printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n",
cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
(l >> st_bit) & mask);
#endif
l &= ~(mask << st_bit);
l |= ticks << st_bit;
gpmc_cs_write_reg(cs, reg, l);
return 0;
}
#ifdef DEBUG
#define GPMC_SET_ONE(reg, st, end, field) \
if (set_gpmc_timing_reg(cs, (reg), (st), (end), \
t->field, #field) < 0) \
return -1
#else
#define GPMC_SET_ONE(reg, st, end, field) \
if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \
return -1
#endif
int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
{
int div;
u32 l;
l = sync_clk * 1000 + (gpmc_get_fclk_period() - 1);
div = l / gpmc_get_fclk_period();
if (div > 4)
return -1;
if (div < 0)
div = 1;
return div;
}
int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
{
int div;
u32 l;
div = gpmc_cs_calc_divider(cs, t->sync_clk);
if (div < 0)
return -1;
GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on);
GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off);
GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on);
GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off);
GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off);
GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on);
GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off);
GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on);
GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off);
GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle);
GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle);
GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access);
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
#ifdef DEBUG
printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n",
cs, gpmc_get_fclk_period(), div);
#endif
l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
l &= ~0x03;
l |= (div - 1);
return 0;
}
unsigned long gpmc_cs_get_base_addr(int cs)
{
return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24;
}
void __init gpmc_init(void)
{
u32 l;
gpmc_l3_clk = clk_get(NULL, "core_l3_ck");
BUG_ON(IS_ERR(gpmc_l3_clk));
l = gpmc_read_reg(GPMC_REVISION);
printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
/* Set smart idle mode and automatic L3 clock gating */
l = gpmc_read_reg(GPMC_SYSCONFIG);
l &= 0x03 << 3;
l |= (0x02 << 3) | (1 << 0);
gpmc_write_reg(GPMC_SYSCONFIG, l);
}
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
extern void omap_sram_init(void); extern void omap_sram_init(void);
extern int omap2_clk_init(void); extern int omap2_clk_init(void);
extern void omap2_check_revision(void); extern void omap2_check_revision(void);
extern void gpmc_init(void);
/* /*
* The machine specific code may provide the extra mapping besides the * The machine specific code may provide the extra mapping besides the
...@@ -67,4 +68,5 @@ void __init omap2_init_common_hw(void) ...@@ -67,4 +68,5 @@ void __init omap2_init_common_hw(void)
{ {
omap2_mux_init(); omap2_mux_init();
omap2_clk_init(); omap2_clk_init();
gpmc_init();
} }
...@@ -53,6 +53,12 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) ...@@ -53,6 +53,12 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
/* 24xx clocks */ /* 24xx clocks */
MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
/* 24xx GPMC wait pin monitoring */
MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1)
MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1)
MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1)
MUX_CFG_24XX("P1_GPMC_WAIT3", 0x09d, 0, 1, 1, 1)
/* 24xx McBSP */ /* 24xx McBSP */
MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1) 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("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
...@@ -72,6 +78,26 @@ MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) ...@@ -72,6 +78,26 @@ 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("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
/* 242x DBG GPIO */
MUX_CFG_24XX("V4_242X_GPIO49", 0xd3, 3, 0, 0, 1)
MUX_CFG_24XX("W2_242X_GPIO50", 0xd4, 3, 0, 0, 1)
MUX_CFG_24XX("U4_242X_GPIO51", 0xd5, 3, 0, 0, 1)
MUX_CFG_24XX("V3_242X_GPIO52", 0xd6, 3, 0, 0, 1)
MUX_CFG_24XX("V2_242X_GPIO53", 0xd7, 3, 0, 0, 1)
MUX_CFG_24XX("V6_242X_GPIO53", 0xcf, 3, 0, 0, 1)
MUX_CFG_24XX("T4_242X_GPIO54", 0xd8, 3, 0, 0, 1)
MUX_CFG_24XX("Y4_242X_GPIO54", 0xd0, 3, 0, 0, 1)
MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1)
MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1)
/* 24xx external DMA requests */
MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1)
MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1)
MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1)
MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1)
MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1)
MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1)
/* TSC IRQ */ /* TSC IRQ */
MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
......
/*
* linux/arch/arm/mach-omap2/pm-domain.c
*
* Power domain functions for OMAP2
*
* Copyright (C) 2006 Nokia Corporation
* Tony Lindgren <tony@atomide.com>
*
* Some code based on earlier OMAP2 sample PM code
* Copyright (C) 2005 Texas Instruments, Inc.
* 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 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 <asm/io.h>
#include "prcm-regs.h"
/* Power domain offsets */
#define PM_MPU_OFFSET 0x100
#define PM_CORE_OFFSET 0x200
#define PM_GFX_OFFSET 0x300
#define PM_WKUP_OFFSET 0x400 /* Autoidle only */
#define PM_PLL_OFFSET 0x500 /* Autoidle only */
#define PM_DSP_OFFSET 0x800
#define PM_MDM_OFFSET 0xc00
/* Power domain wake-up dependency control register */
#define PM_WKDEP_OFFSET 0xc8
#define EN_MDM (1 << 5)
#define EN_WKUP (1 << 4)
#define EN_GFX (1 << 3)
#define EN_DSP (1 << 2)
#define EN_MPU (1 << 1)
#define EN_CORE (1 << 0)
/* Core power domain state transition control register */
#define PM_PWSTCTRL_OFFSET 0xe0
#define FORCESTATE (1 << 18) /* Only for DSP & GFX */
#define MEM4RETSTATE (1 << 6)
#define MEM3RETSTATE (1 << 5)
#define MEM2RETSTATE (1 << 4)
#define MEM1RETSTATE (1 << 3)
#define LOGICRETSTATE (1 << 2) /* Logic is retained */
#define POWERSTATE_OFF 0x3
#define POWERSTATE_RETENTION 0x1
#define POWERSTATE_ON 0x0
/* Power domain state register */
#define PM_PWSTST_OFFSET 0xe4
/* Hardware supervised state transition control register */
#define CM_CLKSTCTRL_OFFSET 0x48
#define AUTOSTAT_MPU (1 << 0) /* MPU */
#define AUTOSTAT_DSS (1 << 2) /* Core */
#define AUTOSTAT_L4 (1 << 1) /* Core */
#define AUTOSTAT_L3 (1 << 0) /* Core */
#define AUTOSTAT_GFX (1 << 0) /* GFX */
#define AUTOSTAT_IVA (1 << 8) /* 2420 IVA in DSP domain */
#define AUTOSTAT_DSP (1 << 0) /* DSP */
#define AUTOSTAT_MDM (1 << 0) /* MDM */
/* Automatic control of interface clock idling */
#define CM_AUTOIDLE1_OFFSET 0x30
#define CM_AUTOIDLE2_OFFSET 0x34 /* Core only */
#define CM_AUTOIDLE3_OFFSET 0x38 /* Core only */
#define CM_AUTOIDLE4_OFFSET 0x3c /* Core only */
#define AUTO_54M(x) (((x) & 0x3) << 6)
#define AUTO_96M(x) (((x) & 0x3) << 2)
#define AUTO_DPLL(x) (((x) & 0x3) << 0)
#define AUTO_STOPPED 0x3
#define AUTO_BYPASS_FAST 0x2 /* DPLL only */
#define AUTO_BYPASS_LOW_POWER 0x1 /* DPLL only */
#define AUTO_DISABLED 0x0
/* Voltage control PRCM_VOLTCTRL bits */
#define AUTO_EXTVOLT (1 << 15)
#define FORCE_EXTVOLT (1 << 14)
#define SETOFF_LEVEL(x) (((x) & 0x3) << 12)
#define MEMRETCTRL (1 << 8)
#define SETRET_LEVEL(x) (((x) & 0x3) << 6)
#define VOLT_LEVEL(x) (((x) & 0x3) << 0)
#define OMAP24XX_PRCM_VBASE IO_ADDRESS(OMAP24XX_PRCM_BASE)
#define prcm_readl(r) __raw_readl(OMAP24XX_PRCM_VBASE + (r))
#define prcm_writel(v, r) __raw_writel((v), OMAP24XX_PRCM_VBASE + (r))
static u32 pmdomain_get_wakeup_dependencies(int domain_offset)
{
return prcm_readl(domain_offset + PM_WKDEP_OFFSET);
}
static void pmdomain_set_wakeup_dependencies(u32 state, int domain_offset)
{
prcm_writel(state, domain_offset + PM_WKDEP_OFFSET);
}
static u32 pmdomain_get_powerstate(int domain_offset)
{
return prcm_readl(domain_offset + PM_PWSTCTRL_OFFSET);
}
static void pmdomain_set_powerstate(u32 state, int domain_offset)
{
prcm_writel(state, domain_offset + PM_PWSTCTRL_OFFSET);
}
static u32 pmdomain_get_clock_autocontrol(int domain_offset)
{
return prcm_readl(domain_offset + CM_CLKSTCTRL_OFFSET);
}
static void pmdomain_set_clock_autocontrol(u32 state, int domain_offset)
{
prcm_writel(state, domain_offset + CM_CLKSTCTRL_OFFSET);
}
static u32 pmdomain_get_clock_autoidle1(int domain_offset)
{
return prcm_readl(domain_offset + CM_AUTOIDLE1_OFFSET);
}
/* Core domain only */
static u32 pmdomain_get_clock_autoidle2(int domain_offset)
{
return prcm_readl(domain_offset + CM_AUTOIDLE2_OFFSET);
}
/* Core domain only */
static u32 pmdomain_get_clock_autoidle3(int domain_offset)
{
return prcm_readl(domain_offset + CM_AUTOIDLE3_OFFSET);
}
/* Core domain only */
static u32 pmdomain_get_clock_autoidle4(int domain_offset)
{
return prcm_readl(domain_offset + CM_AUTOIDLE4_OFFSET);
}
static void pmdomain_set_clock_autoidle1(u32 state, int domain_offset)
{
prcm_writel(state, CM_AUTOIDLE1_OFFSET + domain_offset);
}
/* Core domain only */
static void pmdomain_set_clock_autoidle2(u32 state, int domain_offset)
{
prcm_writel(state, CM_AUTOIDLE2_OFFSET + domain_offset);
}
/* Core domain only */
static void pmdomain_set_clock_autoidle3(u32 state, int domain_offset)
{
prcm_writel(state, CM_AUTOIDLE3_OFFSET + domain_offset);
}
/* Core domain only */
static void pmdomain_set_clock_autoidle4(u32 state, int domain_offset)
{
prcm_writel(state, CM_AUTOIDLE4_OFFSET + domain_offset);
}
/*
* Configures power management domains to idle clocks automatically.
*/
void pmdomain_set_autoidle(void)
{
u32 val;
/* Set PLL auto stop for 54M, 96M & DPLL */
pmdomain_set_clock_autoidle1(AUTO_54M(AUTO_STOPPED) |
AUTO_96M(AUTO_STOPPED) |
AUTO_DPLL(AUTO_STOPPED), PM_PLL_OFFSET);
/* External clock input control
* REVISIT: Should this be in clock framework?
*/
PRCM_CLKSRC_CTRL |= (0x3 << 3);
/* Configure number of 32KHz clock cycles for sys_clk */
PRCM_CLKSSETUP = 0x00ff;
/* Configure automatic voltage transition */
PRCM_VOLTSETUP = 0;
val = PRCM_VOLTCTRL;
val &= ~(SETOFF_LEVEL(0x3) | VOLT_LEVEL(0x3));
val |= SETOFF_LEVEL(1) | VOLT_LEVEL(1) | AUTO_EXTVOLT;
PRCM_VOLTCTRL = val;
/* Disable emulation tools functional clock */
PRCM_CLKEMUL_CTRL = 0x0;
/* Set core memory retention state */
val = pmdomain_get_powerstate(PM_CORE_OFFSET);
if (cpu_is_omap2420()) {
val &= ~(0x7 << 3);
val |= (MEM3RETSTATE | MEM2RETSTATE | MEM1RETSTATE);
} else {
val &= ~(0xf << 3);
val |= (MEM4RETSTATE | MEM3RETSTATE | MEM2RETSTATE |
MEM1RETSTATE);
}
pmdomain_set_powerstate(val, PM_CORE_OFFSET);
/* OCP interface smart idle. REVISIT: Enable autoidle bit0 ? */
val = SMS_SYSCONFIG;
val &= ~(0x3 << 3);
val |= (0x2 << 3) | (1 << 0);
SMS_SYSCONFIG |= val;
val = SDRC_SYSCONFIG;
val &= ~(0x3 << 3);
val |= (0x2 << 3);
SDRC_SYSCONFIG = val;
/* Configure L3 interface for smart idle.
* REVISIT: Enable autoidle bit0 ?
*/
val = GPMC_SYSCONFIG;
val &= ~(0x3 << 3);
val |= (0x2 << 3) | (1 << 0);
GPMC_SYSCONFIG = val;
pmdomain_set_powerstate(LOGICRETSTATE | POWERSTATE_RETENTION,
PM_MPU_OFFSET);
pmdomain_set_powerstate(POWERSTATE_RETENTION, PM_CORE_OFFSET);
if (!cpu_is_omap2420())
pmdomain_set_powerstate(POWERSTATE_RETENTION, PM_MDM_OFFSET);
/* Assume suspend function has saved the state for DSP and GFX */
pmdomain_set_powerstate(FORCESTATE | POWERSTATE_OFF, PM_DSP_OFFSET);
pmdomain_set_powerstate(FORCESTATE | POWERSTATE_OFF, PM_GFX_OFFSET);
#if 0
/* REVISIT: Internal USB needs special handling */
force_standby_usb();
if (cpu_is_omap2430())
force_hsmmc();
sdram_self_refresh_on_idle_req(1);
#endif
/* Enable clock auto control for all domains.
* Note that CORE domain includes also DSS, L4 & L3.
*/
pmdomain_set_clock_autocontrol(AUTOSTAT_MPU, PM_MPU_OFFSET);
pmdomain_set_clock_autocontrol(AUTOSTAT_GFX, PM_GFX_OFFSET);
pmdomain_set_clock_autocontrol(AUTOSTAT_DSS | AUTOSTAT_L4 | AUTOSTAT_L3,
PM_CORE_OFFSET);
if (cpu_is_omap2420())
pmdomain_set_clock_autocontrol(AUTOSTAT_IVA | AUTOSTAT_DSP,
PM_DSP_OFFSET);
else {
pmdomain_set_clock_autocontrol(AUTOSTAT_DSP, PM_DSP_OFFSET);
pmdomain_set_clock_autocontrol(AUTOSTAT_MDM, PM_MDM_OFFSET);
}
/* Enable clock autoidle for all domains */
pmdomain_set_clock_autoidle1(0x2, PM_DSP_OFFSET);
if (cpu_is_omap2420()) {
pmdomain_set_clock_autoidle1(0xfffffff9, PM_CORE_OFFSET);
pmdomain_set_clock_autoidle2(0x7, PM_CORE_OFFSET);
pmdomain_set_clock_autoidle1(0x3f, PM_WKUP_OFFSET);
} else {
pmdomain_set_clock_autoidle1(0xeafffff1, PM_CORE_OFFSET);
pmdomain_set_clock_autoidle2(0xfff, PM_CORE_OFFSET);
pmdomain_set_clock_autoidle1(0x7f, PM_WKUP_OFFSET);
pmdomain_set_clock_autoidle1(0x3, PM_MDM_OFFSET);
}
pmdomain_set_clock_autoidle3(0x7, PM_CORE_OFFSET);
pmdomain_set_clock_autoidle4(0x1f, PM_CORE_OFFSET);
}
/*
* Initializes power domains by removing wake-up dependencies and powering
* down DSP and GFX. Gets called from PM init. Note that DSP and IVA code
* must re-enable DSP and GFX when used.
*/
void __init pmdomain_init(void)
{
/* Remove all domain wakeup dependencies */
pmdomain_set_wakeup_dependencies(EN_WKUP | EN_CORE, PM_MPU_OFFSET);
pmdomain_set_wakeup_dependencies(0, PM_DSP_OFFSET);
pmdomain_set_wakeup_dependencies(0, PM_GFX_OFFSET);
pmdomain_set_wakeup_dependencies(EN_WKUP | EN_MPU, PM_CORE_OFFSET);
if (cpu_is_omap2430())
pmdomain_set_wakeup_dependencies(0, PM_MDM_OFFSET);
/* Power down DSP and GFX */
pmdomain_set_powerstate(POWERSTATE_OFF | FORCESTATE, PM_DSP_OFFSET);
pmdomain_set_powerstate(POWERSTATE_OFF | FORCESTATE, PM_GFX_OFFSET);
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -36,11 +37,18 @@ ...@@ -36,11 +37,18 @@
#include <asm/arch/sram.h> #include <asm/arch/sram.h>
#include <asm/arch/pm.h> #include <asm/arch/pm.h>
#include "prcm-regs.h"
static struct clk *vclk; static struct clk *vclk;
static void (*omap2_sram_idle)(void); static void (*omap2_sram_idle)(void);
static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
static void (*saved_idle)(void); static void (*saved_idle)(void);
extern void __init pmdomain_init(void);
extern void pmdomain_set_autoidle(void);
static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
void omap2_pm_idle(void) void omap2_pm_idle(void)
{ {
local_irq_disable(); local_irq_disable();
...@@ -87,23 +95,272 @@ static int omap2_pm_prepare(suspend_state_t state) ...@@ -87,23 +95,272 @@ static int omap2_pm_prepare(suspend_state_t state)
return error; return error;
} }
#define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \
OMAP_IRQ_BIT(INT_24XX_GPIO_BANK2) | \
OMAP_IRQ_BIT(INT_24XX_GPIO_BANK3))
#define INT1_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK4))
#define INT2_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_UART1_IRQ) | \
OMAP_IRQ_BIT(INT_24XX_UART2_IRQ) | \
OMAP_IRQ_BIT(INT_24XX_UART3_IRQ))
#define preg(reg) printk("%s\t(0x%p):\t0x%08x\n", #reg, &reg, reg);
static void omap2_pm_debug(char * desc)
{
printk("%s:\n", desc);
preg(CM_CLKSTCTRL_MPU);
preg(CM_CLKSTCTRL_CORE);
preg(CM_CLKSTCTRL_GFX);
preg(CM_CLKSTCTRL_DSP);
preg(CM_CLKSTCTRL_MDM);
preg(PM_PWSTCTRL_MPU);
preg(PM_PWSTCTRL_CORE);
preg(PM_PWSTCTRL_GFX);
preg(PM_PWSTCTRL_DSP);
preg(PM_PWSTCTRL_MDM);
preg(PM_PWSTST_MPU);
preg(PM_PWSTST_CORE);
preg(PM_PWSTST_GFX);
preg(PM_PWSTST_DSP);
preg(PM_PWSTST_MDM);
preg(CM_AUTOIDLE1_CORE);
preg(CM_AUTOIDLE2_CORE);
preg(CM_AUTOIDLE3_CORE);
preg(CM_AUTOIDLE4_CORE);
preg(CM_AUTOIDLE_WKUP);
preg(CM_AUTOIDLE_PLL);
preg(CM_AUTOIDLE_DSP);
preg(CM_AUTOIDLE_MDM);
preg(CM_ICLKEN1_CORE);
preg(CM_ICLKEN2_CORE);
preg(CM_ICLKEN3_CORE);
preg(CM_ICLKEN4_CORE);
preg(CM_ICLKEN_GFX);
preg(CM_ICLKEN_WKUP);
preg(CM_ICLKEN_DSP);
preg(CM_ICLKEN_MDM);
preg(CM_IDLEST1_CORE);
preg(CM_IDLEST2_CORE);
preg(CM_IDLEST3_CORE);
preg(CM_IDLEST4_CORE);
preg(CM_IDLEST_GFX);
preg(CM_IDLEST_WKUP);
preg(CM_IDLEST_CKGEN);
preg(CM_IDLEST_DSP);
preg(CM_IDLEST_MDM);
preg(RM_RSTST_MPU);
preg(RM_RSTST_GFX);
preg(RM_RSTST_WKUP);
preg(RM_RSTST_DSP);
preg(RM_RSTST_MDM);
preg(PM_WKDEP_MPU);
preg(PM_WKDEP_CORE);
preg(PM_WKDEP_GFX);
preg(PM_WKDEP_DSP);
preg(PM_WKDEP_MDM);
preg(CM_FCLKEN_WKUP);
preg(CM_ICLKEN_WKUP);
preg(CM_IDLEST_WKUP);
preg(CM_AUTOIDLE_WKUP);
preg(CM_CLKSEL_WKUP);
preg(PM_WKEN_WKUP);
preg(PM_WKST_WKUP);
}
static inline void omap2_pm_save_registers(void)
{
/* Save interrupt registers */
OMAP24XX_SAVE(INTC_MIR0);
OMAP24XX_SAVE(INTC_MIR1);
OMAP24XX_SAVE(INTC_MIR2);
/* Save power control registers */
OMAP24XX_SAVE(CM_CLKSTCTRL_MPU);
OMAP24XX_SAVE(CM_CLKSTCTRL_CORE);
OMAP24XX_SAVE(CM_CLKSTCTRL_GFX);
OMAP24XX_SAVE(CM_CLKSTCTRL_DSP);
OMAP24XX_SAVE(CM_CLKSTCTRL_MDM);
/* Save power state registers */
OMAP24XX_SAVE(PM_PWSTCTRL_MPU);
OMAP24XX_SAVE(PM_PWSTCTRL_CORE);
OMAP24XX_SAVE(PM_PWSTCTRL_GFX);
OMAP24XX_SAVE(PM_PWSTCTRL_DSP);
OMAP24XX_SAVE(PM_PWSTCTRL_MDM);
/* Save autoidle registers */
OMAP24XX_SAVE(CM_AUTOIDLE1_CORE);
OMAP24XX_SAVE(CM_AUTOIDLE2_CORE);
OMAP24XX_SAVE(CM_AUTOIDLE3_CORE);
OMAP24XX_SAVE(CM_AUTOIDLE4_CORE);
OMAP24XX_SAVE(CM_AUTOIDLE_WKUP);
OMAP24XX_SAVE(CM_AUTOIDLE_PLL);
OMAP24XX_SAVE(CM_AUTOIDLE_DSP);
OMAP24XX_SAVE(CM_AUTOIDLE_MDM);
/* Save idle state registers */
OMAP24XX_SAVE(CM_IDLEST1_CORE);
OMAP24XX_SAVE(CM_IDLEST2_CORE);
OMAP24XX_SAVE(CM_IDLEST3_CORE);
OMAP24XX_SAVE(CM_IDLEST4_CORE);
OMAP24XX_SAVE(CM_IDLEST_GFX);
OMAP24XX_SAVE(CM_IDLEST_WKUP);
OMAP24XX_SAVE(CM_IDLEST_CKGEN);
OMAP24XX_SAVE(CM_IDLEST_DSP);
OMAP24XX_SAVE(CM_IDLEST_MDM);
/* Save clock registers */
OMAP24XX_SAVE(CM_FCLKEN1_CORE);
OMAP24XX_SAVE(CM_FCLKEN2_CORE);
OMAP24XX_SAVE(CM_ICLKEN1_CORE);
OMAP24XX_SAVE(CM_ICLKEN2_CORE);
OMAP24XX_SAVE(CM_ICLKEN3_CORE);
OMAP24XX_SAVE(CM_ICLKEN4_CORE);
}
static inline void omap2_pm_restore_registers(void)
{
/* Restore clock state registers */
OMAP24XX_RESTORE(CM_CLKSTCTRL_MPU);
OMAP24XX_RESTORE(CM_CLKSTCTRL_CORE);
OMAP24XX_RESTORE(CM_CLKSTCTRL_GFX);
OMAP24XX_RESTORE(CM_CLKSTCTRL_DSP);
OMAP24XX_RESTORE(CM_CLKSTCTRL_MDM);
/* Restore power state registers */
OMAP24XX_RESTORE(PM_PWSTCTRL_MPU);
OMAP24XX_RESTORE(PM_PWSTCTRL_CORE);
OMAP24XX_RESTORE(PM_PWSTCTRL_GFX);
OMAP24XX_RESTORE(PM_PWSTCTRL_DSP);
OMAP24XX_RESTORE(PM_PWSTCTRL_MDM);
/* Restore idle state registers */
OMAP24XX_RESTORE(CM_IDLEST1_CORE);
OMAP24XX_RESTORE(CM_IDLEST2_CORE);
OMAP24XX_RESTORE(CM_IDLEST3_CORE);
OMAP24XX_RESTORE(CM_IDLEST4_CORE);
OMAP24XX_RESTORE(CM_IDLEST_GFX);
OMAP24XX_RESTORE(CM_IDLEST_WKUP);
OMAP24XX_RESTORE(CM_IDLEST_CKGEN);
OMAP24XX_RESTORE(CM_IDLEST_DSP);
OMAP24XX_RESTORE(CM_IDLEST_MDM);
/* Restore autoidle registers */
OMAP24XX_RESTORE(CM_AUTOIDLE1_CORE);
OMAP24XX_RESTORE(CM_AUTOIDLE2_CORE);
OMAP24XX_RESTORE(CM_AUTOIDLE3_CORE);
OMAP24XX_RESTORE(CM_AUTOIDLE4_CORE);
OMAP24XX_RESTORE(CM_AUTOIDLE_WKUP);
OMAP24XX_RESTORE(CM_AUTOIDLE_PLL);
OMAP24XX_RESTORE(CM_AUTOIDLE_DSP);
OMAP24XX_RESTORE(CM_AUTOIDLE_MDM);
/* Restore clock registers */
OMAP24XX_RESTORE(CM_FCLKEN1_CORE);
OMAP24XX_RESTORE(CM_FCLKEN2_CORE);
OMAP24XX_RESTORE(CM_ICLKEN1_CORE);
OMAP24XX_RESTORE(CM_ICLKEN2_CORE);
OMAP24XX_RESTORE(CM_ICLKEN3_CORE);
OMAP24XX_RESTORE(CM_ICLKEN4_CORE);
/* REVISIT: Clear interrupts here */
/* Restore interrupt registers */
OMAP24XX_RESTORE(INTC_MIR0);
OMAP24XX_RESTORE(INTC_MIR1);
OMAP24XX_RESTORE(INTC_MIR2);
}
static int omap2_pm_suspend(void)
{
int processor_type = 0;
/* REVISIT: 0x21 or 0x26? */
if (cpu_is_omap2420())
processor_type = 0x21;
if (!processor_type)
return -ENOTSUPP;
local_irq_disable();
local_fiq_disable();
omap2_pm_save_registers();
/* Disable interrupts except for the wake events */
INTC_MIR_SET0 = 0xffffffff & ~INT0_WAKE_MASK;
INTC_MIR_SET1 = 0xffffffff & ~INT1_WAKE_MASK;
INTC_MIR_SET2 = 0xffffffff & ~INT2_WAKE_MASK;
pmdomain_set_autoidle();
/* Clear old wake-up events */
PM_WKST1_CORE = 0;
PM_WKST2_CORE = 0;
PM_WKST_WKUP = 0;
/* Enable wake-up events */
PM_WKEN1_CORE = (1 << 22) | (1 << 21); /* UART1 & 2 */
PM_WKEN2_CORE = (1 << 2); /* UART3 */
PM_WKEN_WKUP = (1 << 2) | (1 << 0); /* GPIO & GPT1 */
/* Disable clocks except for CM_ICLKEN2_CORE. It gets disabled
* in the SRAM suspend code */
CM_FCLKEN1_CORE = 0;
CM_FCLKEN2_CORE = 0;
CM_ICLKEN1_CORE = 0;
CM_ICLKEN3_CORE = 0;
CM_ICLKEN4_CORE = 0;
omap2_pm_debug("Status before suspend");
/* Must wait for serial buffers to clear */
mdelay(200);
/* Jump to SRAM suspend code
* REVISIT: When is this SDRC_DLLB_CTRL?
*/
omap2_sram_suspend(SDRC_DLLA_CTRL, processor_type);
/* Back from sleep */
omap2_pm_restore_registers();
local_fiq_enable();
local_irq_enable();
return 0;
}
static int omap2_pm_enter(suspend_state_t state) static int omap2_pm_enter(suspend_state_t state)
{ {
int ret = 0;
switch (state) switch (state)
{ {
case PM_SUSPEND_STANDBY: case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM: case PM_SUSPEND_MEM:
/* FIXME: Add suspend */ ret = omap2_pm_suspend();
break; break;
case PM_SUSPEND_DISK: case PM_SUSPEND_DISK:
return -ENOTSUPP; ret = -ENOTSUPP;
break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
return 0; return ret;
} }
static int omap2_pm_finish(suspend_state_t state) static int omap2_pm_finish(suspend_state_t state)
...@@ -143,6 +400,8 @@ int __init omap2_pm_init(void) ...@@ -143,6 +400,8 @@ int __init omap2_pm_init(void)
pm_set_ops(&omap_pm_ops); pm_set_ops(&omap_pm_ops);
pm_idle = omap2_pm_idle; pm_idle = omap2_pm_idle;
pmdomain_init();
return 0; return 0;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright (C) 2005 Nokia Corporation * Copyright (C) 2005 Nokia Corporation
* Author: Paul Mundt <paul.mundt@nokia.com> * Author: Paul Mundt <paul.mundt@nokia.com>
* Juha Yrjl <juha.yrjola@nokia.com> * Juha Yrjl <juha.yrjola@nokia.com>
* OMAP Dual-mode timer framework support by Timo Teras
* *
* Some parts based off of TI's 24xx code: * Some parts based off of TI's 24xx code:
* *
...@@ -22,54 +23,18 @@ ...@@ -22,54 +23,18 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/delay.h> #include <asm/arch/dmtimer.h>
#include <asm/io.h>
#define OMAP2_GP_TIMER1_BASE 0x48028000 static struct omap_dm_timer *gptimer;
#define OMAP2_GP_TIMER2_BASE 0x4802a000
#define OMAP2_GP_TIMER3_BASE 0x48078000
#define OMAP2_GP_TIMER4_BASE 0x4807a000
#define GP_TIMER_TIDR 0x00 static inline void omap2_gp_timer_start(unsigned long load_val)
#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_TSICR 0x40
#define OS_TIMER_NR 1 /* GP timer 2 */
static unsigned long timer_base[] = {
IO_ADDRESS(OMAP2_GP_TIMER1_BASE),
IO_ADDRESS(OMAP2_GP_TIMER2_BASE),
IO_ADDRESS(OMAP2_GP_TIMER3_BASE),
IO_ADDRESS(OMAP2_GP_TIMER4_BASE),
};
static inline unsigned int timer_read_reg(int nr, unsigned int reg)
{
return __raw_readl(timer_base[nr] + reg);
}
static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val)
{
__raw_writel(val, timer_base[nr] + reg);
}
/* Note that we always enable the clock prescale divider bit */
static inline void omap2_gp_timer_start(int nr, unsigned long load_val)
{ {
unsigned int tmp; omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val);
omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
tmp = 0xffffffff - load_val; omap_dm_timer_start(gptimer);
timer_write_reg(nr, GP_TIMER_TLDR, tmp);
timer_write_reg(nr, GP_TIMER_TCRR, tmp);
timer_write_reg(nr, GP_TIMER_TIER, 1 << 1);
timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1);
} }
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id, static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
...@@ -77,7 +42,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id, ...@@ -77,7 +42,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
{ {
write_seqlock(&xtime_lock); write_seqlock(&xtime_lock);
timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1); omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
timer_tick(regs); timer_tick(regs);
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
...@@ -87,41 +52,26 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id, ...@@ -87,41 +52,26 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
static struct irqaction omap2_gp_timer_irq = { static struct irqaction omap2_gp_timer_irq = {
.name = "gp timer", .name = "gp timer",
.flags = SA_INTERRUPT, .flags = SA_INTERRUPT | SA_TIMER,
.handler = omap2_gp_timer_interrupt, .handler = omap2_gp_timer_interrupt,
}; };
static void __init omap2_gp_timer_init(void) static void __init omap2_gp_timer_init(void)
{ {
struct clk * sys_ck; u32 tick_period;
u32 tick_period = 120000;
u32 l;
/* Reset clock and prescale value */ omap_dm_timer_init();
timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0); gptimer = omap_dm_timer_request_specific(1);
BUG_ON(gptimer == NULL);
sys_ck = clk_get(NULL, "sys_ck"); omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
if (IS_ERR(sys_ck)) tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / 100;
printk(KERN_ERR "Could not get sys_ck\n");
else {
clk_enable(sys_ck);
tick_period = clk_get_rate(sys_ck) / 100;
clk_put(sys_ck);
}
tick_period /= 2; /* Minimum prescale divider is 2 */
tick_period -= 1; tick_period -= 1;
l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR); setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n", omap2_gp_timer_start(tick_period);
(l >> 4) & 0x0f, l & 0x0f);
setup_irq(38, &omap2_gp_timer_irq);
omap2_gp_timer_start(OS_TIMER_NR, tick_period);
} }
struct sys_timer omap_timer = { struct sys_timer omap_timer = {
.init = omap2_gp_timer_init, .init = omap2_gp_timer_init,
}; };
...@@ -91,7 +91,7 @@ config OMAP_32K_TIMER_HZ ...@@ -91,7 +91,7 @@ config OMAP_32K_TIMER_HZ
config OMAP_DM_TIMER config OMAP_DM_TIMER
bool "Use dual-mode timer" bool "Use dual-mode timer"
depends on ARCH_OMAP16XX depends on ARCH_OMAP16XX || ARCH_OMAP24XX
help help
Select this option if you want to use OMAP Dual-Mode timers. Select this option if you want to use OMAP Dual-Mode timers.
......
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
LIST_HEAD(clocks); static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex); static DEFINE_MUTEX(clocks_mutex);
DEFINE_SPINLOCK(clockfw_lock); static DEFINE_SPINLOCK(clockfw_lock);
static struct clk_functions *arch_clock; static struct clk_functions *arch_clock;
......
...@@ -25,6 +25,14 @@ ...@@ -25,6 +25,14 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#define VERY_HI_RATE 900000000
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
#else
#define MPU_CLK "virt_prcm_set"
#endif
/* TODO: Add support for SDRAM timing changes */ /* TODO: Add support for SDRAM timing changes */
int omap_verify_speed(struct cpufreq_policy *policy) int omap_verify_speed(struct cpufreq_policy *policy)
...@@ -36,7 +44,7 @@ int omap_verify_speed(struct cpufreq_policy *policy) ...@@ -36,7 +44,7 @@ int omap_verify_speed(struct cpufreq_policy *policy)
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq); policy->cpuinfo.max_freq);
mpu_clk = clk_get(NULL, "mpu"); mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk)) if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk); return PTR_ERR(mpu_clk);
policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
...@@ -56,7 +64,7 @@ unsigned int omap_getspeed(unsigned int cpu) ...@@ -56,7 +64,7 @@ unsigned int omap_getspeed(unsigned int cpu)
if (cpu) if (cpu)
return 0; return 0;
mpu_clk = clk_get(NULL, "mpu"); mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk)) if (IS_ERR(mpu_clk))
return 0; return 0;
rate = clk_get_rate(mpu_clk) / 1000; rate = clk_get_rate(mpu_clk) / 1000;
...@@ -73,7 +81,7 @@ static int omap_target(struct cpufreq_policy *policy, ...@@ -73,7 +81,7 @@ static int omap_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
int ret = 0; int ret = 0;
mpu_clk = clk_get(NULL, "mpu"); mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk)) if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk); return PTR_ERR(mpu_clk);
...@@ -93,7 +101,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) ...@@ -93,7 +101,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
{ {
struct clk * mpu_clk; struct clk * mpu_clk;
mpu_clk = clk_get(NULL, "mpu"); mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk)) if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk); return PTR_ERR(mpu_clk);
...@@ -102,7 +110,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) ...@@ -102,7 +110,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
policy->cur = policy->min = policy->max = omap_getspeed(0); policy->cur = policy->min = policy->max = omap_getspeed(0);
policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, 216000000) / 1000; policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
clk_put(mpu_clk); clk_put(mpu_clk);
......
...@@ -105,7 +105,7 @@ static void omap_init_kp(void) ...@@ -105,7 +105,7 @@ static void omap_init_kp(void)
omap_cfg_reg(E20_1610_KBR3); omap_cfg_reg(E20_1610_KBR3);
omap_cfg_reg(E19_1610_KBR4); omap_cfg_reg(E19_1610_KBR4);
omap_cfg_reg(N19_1610_KBR5); omap_cfg_reg(N19_1610_KBR5);
} else if (machine_is_omap_perseus2()) { } else if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
omap_cfg_reg(E2_730_KBR0); omap_cfg_reg(E2_730_KBR0);
omap_cfg_reg(J7_730_KBR1); omap_cfg_reg(J7_730_KBR1);
omap_cfg_reg(E1_730_KBR2); omap_cfg_reg(E1_730_KBR2);
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#define OMAP_DMA_ACTIVE 0x01 #define OMAP_DMA_ACTIVE 0x01
#define OMAP_DMA_CCR_EN (1 << 7) #define OMAP_DMA_CCR_EN (1 << 7)
#define OMAP2_DMA_CSR_CLEAR_MASK 0xffe
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
...@@ -166,18 +167,24 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, ...@@ -166,18 +167,24 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
if (cpu_is_omap24xx() && dma_trigger) { if (cpu_is_omap24xx() && dma_trigger) {
u32 val = OMAP_DMA_CCR_REG(lch); u32 val = OMAP_DMA_CCR_REG(lch);
val &= ~(3 << 19);
if (dma_trigger > 63) if (dma_trigger > 63)
val |= 1 << 20; val |= 1 << 20;
if (dma_trigger > 31) if (dma_trigger > 31)
val |= 1 << 19; val |= 1 << 19;
val &= ~(0x1f);
val |= (dma_trigger & 0x1f); val |= (dma_trigger & 0x1f);
if (sync_mode & OMAP_DMA_SYNC_FRAME) if (sync_mode & OMAP_DMA_SYNC_FRAME)
val |= 1 << 5; val |= 1 << 5;
else
val &= ~(1 << 5);
if (sync_mode & OMAP_DMA_SYNC_BLOCK) if (sync_mode & OMAP_DMA_SYNC_BLOCK)
val |= 1 << 18; val |= 1 << 18;
else
val &= ~(1 << 18);
if (src_or_dst_synch) if (src_or_dst_synch)
val |= 1 << 24; /* source synch */ val |= 1 << 24; /* source synch */
...@@ -286,22 +293,39 @@ void omap_set_dma_src_data_pack(int lch, int enable) ...@@ -286,22 +293,39 @@ void omap_set_dma_src_data_pack(int lch, int enable)
void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{ {
unsigned int burst = 0;
OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
switch (burst_mode) { switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS: case OMAP_DMA_DATA_BURST_DIS:
break; break;
case OMAP_DMA_DATA_BURST_4: case OMAP_DMA_DATA_BURST_4:
OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7); if (cpu_is_omap24xx())
burst = 0x1;
else
burst = 0x2;
break; break;
case OMAP_DMA_DATA_BURST_8: case OMAP_DMA_DATA_BURST_8:
/* not supported by current hardware if (cpu_is_omap24xx()) {
burst = 0x2;
break;
}
/* not supported by current hardware on OMAP1
* w |= (0x03 << 7); * w |= (0x03 << 7);
* fall through * fall through
*/ */
case OMAP_DMA_DATA_BURST_16:
if (cpu_is_omap24xx()) {
burst = 0x3;
break;
}
/* OMAP1 don't support burst 16
* fall through
*/
default: default:
BUG(); BUG();
} }
OMAP_DMA_CSDP_REG(lch) |= (burst << 7);
} }
/* Note that dest_port is only for OMAP1 */ /* Note that dest_port is only for OMAP1 */
...@@ -348,30 +372,49 @@ void omap_set_dma_dest_data_pack(int lch, int enable) ...@@ -348,30 +372,49 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{ {
unsigned int burst = 0;
OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
switch (burst_mode) { switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS: case OMAP_DMA_DATA_BURST_DIS:
break; break;
case OMAP_DMA_DATA_BURST_4: case OMAP_DMA_DATA_BURST_4:
OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14); if (cpu_is_omap24xx())
burst = 0x1;
else
burst = 0x2;
break; break;
case OMAP_DMA_DATA_BURST_8: case OMAP_DMA_DATA_BURST_8:
OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14); if (cpu_is_omap24xx())
burst = 0x2;
else
burst = 0x3;
break;
case OMAP_DMA_DATA_BURST_16:
if (cpu_is_omap24xx()) {
burst = 0x3;
break; break;
}
/* OMAP1 don't support burst 16
* fall through
*/
default: default:
printk(KERN_ERR "Invalid DMA burst mode\n"); printk(KERN_ERR "Invalid DMA burst mode\n");
BUG(); BUG();
return; return;
} }
OMAP_DMA_CSDP_REG(lch) |= (burst << 14);
} }
static inline void omap_enable_channel_irq(int lch) static inline void omap_enable_channel_irq(int lch)
{ {
u32 status; u32 status;
/* Read CSR to make sure it's cleared. */ /* Clear CSR */
if (cpu_class_is_omap1())
status = OMAP_DMA_CSR_REG(lch); status = OMAP_DMA_CSR_REG(lch);
else if (cpu_is_omap24xx())
OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
/* Enable some nice interrupts. */ /* Enable some nice interrupts. */
OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
...@@ -470,11 +513,13 @@ int omap_request_dma(int dev_id, const char *dev_name, ...@@ -470,11 +513,13 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan->dev_name = dev_name; chan->dev_name = dev_name;
chan->callback = callback; chan->callback = callback;
chan->data = data; chan->data = data;
chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
OMAP_DMA_BLOCK_IRQ;
if (cpu_is_omap24xx()) if (cpu_class_is_omap1())
chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ; chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
else if (cpu_is_omap24xx())
chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
OMAP2_DMA_TRANS_ERR_IRQ;
if (cpu_is_omap16xx()) { if (cpu_is_omap16xx()) {
/* If the sync device is set, configure it dynamically. */ /* If the sync device is set, configure it dynamically. */
...@@ -494,7 +539,7 @@ int omap_request_dma(int dev_id, const char *dev_name, ...@@ -494,7 +539,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
omap_enable_channel_irq(free_ch); omap_enable_channel_irq(free_ch);
/* Clear the CSR register and IRQ status register */ /* Clear the CSR register and IRQ status register */
OMAP_DMA_CSR_REG(free_ch) = 0x0; OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK;
omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0); omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0);
} }
...@@ -534,7 +579,7 @@ void omap_free_dma(int lch) ...@@ -534,7 +579,7 @@ void omap_free_dma(int lch)
omap_writel(val, OMAP_DMA4_IRQENABLE_L0); omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
/* Clear the CSR register and IRQ status register */ /* Clear the CSR register and IRQ status register */
OMAP_DMA_CSR_REG(lch) = 0x0; OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
val |= 1 << lch; val |= 1 << lch;
...@@ -798,7 +843,7 @@ static int omap1_dma_handle_ch(int ch) ...@@ -798,7 +843,7 @@ static int omap1_dma_handle_ch(int ch)
"%d (CSR %04x)\n", ch, csr); "%d (CSR %04x)\n", ch, csr);
return 0; return 0;
} }
if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
printk(KERN_WARNING "DMA timeout with device %d\n", printk(KERN_WARNING "DMA timeout with device %d\n",
dma_chan[ch].dev_id); dma_chan[ch].dev_id);
if (unlikely(csr & OMAP_DMA_DROP_IRQ)) if (unlikely(csr & OMAP_DMA_DROP_IRQ))
...@@ -846,20 +891,21 @@ static int omap2_dma_handle_ch(int ch) ...@@ -846,20 +891,21 @@ static int omap2_dma_handle_ch(int ch)
return 0; return 0;
if (unlikely(dma_chan[ch].dev_id == -1)) if (unlikely(dma_chan[ch].dev_id == -1))
return 0; return 0;
/* REVISIT: According to 24xx TRM, there's no TOUT_IE */
if (unlikely(status & OMAP_DMA_TOUT_IRQ))
printk(KERN_INFO "DMA timeout with device %d\n",
dma_chan[ch].dev_id);
if (unlikely(status & OMAP_DMA_DROP_IRQ)) if (unlikely(status & OMAP_DMA_DROP_IRQ))
printk(KERN_INFO printk(KERN_INFO
"DMA synchronization event drop occurred with device " "DMA synchronization event drop occurred with device "
"%d\n", dma_chan[ch].dev_id); "%d\n", dma_chan[ch].dev_id);
if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
printk(KERN_INFO "DMA transaction error with device %d\n", printk(KERN_INFO "DMA transaction error with device %d\n",
dma_chan[ch].dev_id); dma_chan[ch].dev_id);
if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ))
printk(KERN_INFO "DMA secure error with device %d\n",
dma_chan[ch].dev_id);
if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ))
printk(KERN_INFO "DMA misaligned error with device %d\n",
dma_chan[ch].dev_id);
OMAP_DMA_CSR_REG(ch) = 0x20; OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK;
val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
/* ch in this function is from 0-31 while in register it is 1-32 */ /* ch in this function is from 0-31 while in register it is 1-32 */
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
* OMAP Dual-Mode Timers * OMAP Dual-Mode Timers
* *
* Copyright (C) 2005 Nokia Corporation * Copyright (C) 2005 Nokia Corporation
* Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> * OMAP2 support by Juha Yrjola
* API improvements and OMAP2 clock framework support by Timo Teras
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
...@@ -26,15 +27,17 @@ ...@@ -26,15 +27,17 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/arch/dmtimer.h> #include <asm/arch/dmtimer.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#define OMAP_TIMER_COUNT 8
/* register offsets */
#define OMAP_TIMER_ID_REG 0x00 #define OMAP_TIMER_ID_REG 0x00
#define OMAP_TIMER_OCP_CFG_REG 0x10 #define OMAP_TIMER_OCP_CFG_REG 0x10
#define OMAP_TIMER_SYS_STAT_REG 0x14 #define OMAP_TIMER_SYS_STAT_REG 0x14
...@@ -50,52 +53,196 @@ ...@@ -50,52 +53,196 @@
#define OMAP_TIMER_CAPTURE_REG 0x3c #define OMAP_TIMER_CAPTURE_REG 0x3c
#define OMAP_TIMER_IF_CTRL_REG 0x40 #define OMAP_TIMER_IF_CTRL_REG 0x40
/* timer control reg bits */
#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
#define OMAP_TIMER_CTRL_PT (1 << 12)
#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* how much to shift the prescaler value */
#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
struct omap_dm_timer {
unsigned long phys_base;
int irq;
#ifdef CONFIG_ARCH_OMAP2
struct clk *iclk, *fclk;
#endif
void __iomem *io_base;
unsigned reserved:1;
};
#ifdef CONFIG_ARCH_OMAP1
static struct omap_dm_timer dm_timers[] = {
{ .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
{ .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
{ .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 },
{ .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 },
{ .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 },
{ .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 },
{ .phys_base = 0xfffb4400, .irq = INT_1610_GPTIMER7 },
{ .phys_base = 0xfffb4c00, .irq = INT_1610_GPTIMER8 },
};
static struct dmtimer_info_struct { #elif defined(CONFIG_ARCH_OMAP2)
struct list_head unused_timers;
struct list_head reserved_timers;
} dm_timer_info;
static struct omap_dm_timer dm_timers[] = { static struct omap_dm_timer dm_timers[] = {
{ .base=0xfffb1400, .irq=INT_1610_GPTIMER1 }, { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
{ .base=0xfffb1c00, .irq=INT_1610_GPTIMER2 }, { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
{ .base=0xfffb2400, .irq=INT_1610_GPTIMER3 }, { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
{ .base=0xfffb2c00, .irq=INT_1610_GPTIMER4 }, { .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
{ .base=0xfffb3400, .irq=INT_1610_GPTIMER5 }, { .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
{ .base=0xfffb3c00, .irq=INT_1610_GPTIMER6 }, { .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
{ .base=0xfffb4400, .irq=INT_1610_GPTIMER7 }, { .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
{ .base=0xfffb4c00, .irq=INT_1610_GPTIMER8 }, { .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
{ .base=0x0 }, { .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
{ .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
};
static const char *dm_source_names[] = {
"sys_ck",
"func_32k_ck",
"alt_ck"
}; };
static struct clk *dm_source_clocks[3];
#else
#error OMAP architecture not supported!
#endif
static const int dm_timer_count = ARRAY_SIZE(dm_timers);
static spinlock_t dm_timer_lock; static spinlock_t dm_timer_lock;
static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
{
return readl(timer->io_base + reg);
}
inline void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value) static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
{ {
omap_writel(value, timer->base + reg); writel(value, timer->io_base + reg);
while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG)) while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
; ;
} }
u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
{ {
return omap_readl(timer->base + reg); int c;
c = 0;
while (!(omap_dm_timer_read_reg(timer, OMAP_TIMER_SYS_STAT_REG) & 1)) {
c++;
if (c > 100000) {
printk(KERN_ERR "Timer failed to reset\n");
return;
}
}
} }
int omap_dm_timers_active(void) static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
u32 l;
if (timer != &dm_timers[0]) {
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
omap_dm_timer_wait_for_reset(timer);
}
omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK);
/* Set to smart-idle mode */
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
l |= 0x02 << 3;
omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
}
static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
#ifdef CONFIG_ARCH_OMAP2
clk_enable(timer->iclk);
clk_enable(timer->fclk);
#endif
omap_dm_timer_reset(timer);
}
struct omap_dm_timer *omap_dm_timer_request(void)
{
struct omap_dm_timer *timer = NULL;
unsigned long flags;
int i;
spin_lock_irqsave(&dm_timer_lock, flags);
for (i = 0; i < dm_timer_count; i++) {
if (dm_timers[i].reserved)
continue;
timer = &dm_timers[i];
timer->reserved = 1;
break;
}
spin_unlock_irqrestore(&dm_timer_lock, flags);
if (timer != NULL)
omap_dm_timer_prepare(timer);
return timer;
}
struct omap_dm_timer *omap_dm_timer_request_specific(int id)
{ {
struct omap_dm_timer *timer; struct omap_dm_timer *timer;
unsigned long flags;
for (timer = &dm_timers[0]; timer->base; ++timer) spin_lock_irqsave(&dm_timer_lock, flags);
if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) {
OMAP_TIMER_CTRL_ST) spin_unlock_irqrestore(&dm_timer_lock, flags);
return 1; printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n",
__FILE__, __LINE__, __FUNCTION__, id);
dump_stack();
return NULL;
}
return 0; timer = &dm_timers[id-1];
timer->reserved = 1;
spin_unlock_irqrestore(&dm_timer_lock, flags);
omap_dm_timer_prepare(timer);
return timer;
} }
void omap_dm_timer_free(struct omap_dm_timer *timer)
{
omap_dm_timer_reset(timer);
#ifdef CONFIG_ARCH_OMAP2
clk_disable(timer->iclk);
clk_disable(timer->fclk);
#endif
WARN_ON(!timer->reserved);
timer->reserved = 0;
}
int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
{
return timer->irq;
}
#if defined(CONFIG_ARCH_OMAP1)
struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
{
BUG();
}
/** /**
* omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
...@@ -103,184 +250,229 @@ int omap_dm_timers_active(void) ...@@ -103,184 +250,229 @@ int omap_dm_timers_active(void)
*/ */
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{ {
int n; int i;
/* If ARMXOR cannot be idled this function call is unnecessary */ /* If ARMXOR cannot be idled this function call is unnecessary */
if (!(inputmask & (1 << 1))) if (!(inputmask & (1 << 1)))
return inputmask; return inputmask;
/* If any active timer is using ARMXOR return modified mask */ /* If any active timer is using ARMXOR return modified mask */
for (n = 0; dm_timers[n].base; ++n) for (i = 0; i < dm_timer_count; i++) {
if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)& u32 l;
OMAP_TIMER_CTRL_ST) {
if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0) l = omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG);
if (l & OMAP_TIMER_CTRL_ST) {
if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
inputmask &= ~(1 << 1); inputmask &= ~(1 << 1);
else else
inputmask &= ~(1 << 2); inputmask &= ~(1 << 2);
} }
}
return inputmask; return inputmask;
} }
#elif defined(CONFIG_ARCH_OMAP2)
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
{ {
int n = (timer - dm_timers) << 1; return timer->fclk;
u32 l; }
l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
l |= source << n; {
omap_writel(l, MOD_CONF_CTRL_1); BUG();
} }
#endif
static void omap_dm_timer_reset(struct omap_dm_timer *timer) void omap_dm_timer_trigger(struct omap_dm_timer *timer)
{ {
/* Reset and set posted mode */ omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, 0x02);
omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_ARMXOR);
} }
void omap_dm_timer_start(struct omap_dm_timer *timer)
{
u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (!(l & OMAP_TIMER_CTRL_ST)) {
l |= OMAP_TIMER_CTRL_ST;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
}
struct omap_dm_timer * omap_dm_timer_request(void) void omap_dm_timer_stop(struct omap_dm_timer *timer)
{ {
struct omap_dm_timer *timer = NULL; u32 l;
unsigned long flags;
spin_lock_irqsave(&dm_timer_lock, flags); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (!list_empty(&dm_timer_info.unused_timers)) { if (l & OMAP_TIMER_CTRL_ST) {
timer = (struct omap_dm_timer *) l &= ~0x1;
dm_timer_info.unused_timers.next; omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
list_move_tail((struct list_head *)timer,
&dm_timer_info.reserved_timers);
} }
spin_unlock_irqrestore(&dm_timer_lock, flags);
return timer;
} }
#ifdef CONFIG_ARCH_OMAP1
void omap_dm_timer_free(struct omap_dm_timer *timer) void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{ {
unsigned long flags; int n = (timer - dm_timers) << 1;
u32 l;
omap_dm_timer_reset(timer);
spin_lock_irqsave(&dm_timer_lock, flags); l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
list_move_tail((struct list_head *)timer, &dm_timer_info.unused_timers); l |= source << n;
spin_unlock_irqrestore(&dm_timer_lock, flags); omap_writel(l, MOD_CONF_CTRL_1);
} }
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, #else
unsigned int value)
{
omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
}
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{ {
return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); if (source < 0 || source >= 3)
} return;
void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) clk_disable(timer->fclk);
{ clk_set_parent(timer->fclk, dm_source_clocks[source]);
omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value); clk_enable(timer->fclk);
/* When the functional clock disappears, too quick writes seem to
* cause an abort. */
__delay(15000);
} }
void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer) #endif
void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
{ {
u32 l; u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload)
l |= OMAP_TIMER_CTRL_AR; l |= OMAP_TIMER_CTRL_AR;
else
l &= ~OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
} }
void omap_dm_timer_trigger(struct omap_dm_timer *timer) void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
{ unsigned int match)
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1);
}
void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value)
{ {
u32 l; u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l |= value & 0x3; if (enable)
l |= OMAP_TIMER_CTRL_CE;
else
l &= ~OMAP_TIMER_CTRL_CE;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
} }
void omap_dm_timer_start(struct omap_dm_timer *timer)
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger)
{ {
u32 l; u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l |= OMAP_TIMER_CTRL_ST; l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
OMAP_TIMER_CTRL_PT | (0x03 << 10));
if (def_on)
l |= OMAP_TIMER_CTRL_SCPWM;
if (toggle)
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
} }
void omap_dm_timer_stop(struct omap_dm_timer *timer) void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
{ {
u32 l; u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~0x1; l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
if (prescaler >= 0x00 && prescaler <= 0x07) {
l |= OMAP_TIMER_CTRL_PRE;
l |= prescaler << 2;
}
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
} }
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
unsigned int value)
{ {
return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
} }
void omap_dm_timer_reset_counter(struct omap_dm_timer *timer) unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{ {
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 0); return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
} }
void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load) void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{ {
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
} }
void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match) unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{ {
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
} }
void omap_dm_timer_enable_compare(struct omap_dm_timer *timer) void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{ {
u32 l; return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l |= OMAP_TIMER_CTRL_CE;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
} }
int omap_dm_timers_active(void)
static inline void __dm_timer_init(void)
{ {
struct omap_dm_timer *timer; int i;
spin_lock_init(&dm_timer_lock); for (i = 0; i < dm_timer_count; i++) {
INIT_LIST_HEAD(&dm_timer_info.unused_timers); struct omap_dm_timer *timer;
INIT_LIST_HEAD(&dm_timer_info.reserved_timers);
timer = &dm_timers[0]; timer = &dm_timers[i];
while (timer->base) { if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
list_add_tail((struct list_head *)timer, &dm_timer_info.unused_timers); OMAP_TIMER_CTRL_ST)
omap_dm_timer_reset(timer); return 1;
timer++;
} }
return 0;
} }
static int __init omap_dm_timer_init(void) int omap_dm_timer_init(void)
{ {
if (cpu_is_omap16xx()) struct omap_dm_timer *timer;
__dm_timer_init(); int i;
if (!(cpu_is_omap16xx() || cpu_is_omap24xx()))
return -ENODEV;
spin_lock_init(&dm_timer_lock);
#ifdef CONFIG_ARCH_OMAP2
for (i = 0; i < ARRAY_SIZE(dm_source_names); i++) {
dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
BUG_ON(dm_source_clocks[i] == NULL);
}
#endif
for (i = 0; i < dm_timer_count; i++) {
#ifdef CONFIG_ARCH_OMAP2
char clk_name[16];
#endif
timer = &dm_timers[i];
timer->io_base = (void __iomem *) io_p2v(timer->phys_base);
#ifdef CONFIG_ARCH_OMAP2
sprintf(clk_name, "gpt%d_ick", i + 1);
timer->iclk = clk_get(NULL, clk_name);
sprintf(clk_name, "gpt%d_fck", i + 1);
timer->fclk = clk_get(NULL, clk_name);
#endif
}
return 0; return 0;
} }
arch_initcall(omap_dm_timer_init);
...@@ -537,6 +537,49 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) ...@@ -537,6 +537,49 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
} }
static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
{
void __iomem *reg = bank->base;
int inv = 0;
u32 l;
u32 mask;
switch (bank->method) {
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT;
mask = 0xffff;
inv = 1;
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK;
mask = 0xffff;
inv = 1;
break;
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_IRQENABLE1;
mask = 0xffff;
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK;
mask = 0xffffffff;
inv = 1;
break;
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQENABLE1;
mask = 0xffffffff;
break;
default:
BUG();
return 0;
}
l = __raw_readl(reg);
if (inv)
l = ~l;
l &= mask;
return l;
}
static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
{ {
void __iomem *reg = bank->base; void __iomem *reg = bank->base;
...@@ -736,6 +779,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -736,6 +779,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
u32 isr; u32 isr;
unsigned int gpio_irq; unsigned int gpio_irq;
struct gpio_bank *bank; struct gpio_bank *bank;
u32 retrigger = 0;
int unmasked = 0;
desc->chip->ack(irq); desc->chip->ack(irq);
...@@ -760,18 +805,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -760,18 +805,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
#endif #endif
while(1) { while(1) {
u32 isr_saved, level_mask = 0; u32 isr_saved, level_mask = 0;
u32 enabled;
isr_saved = isr = __raw_readl(isr_reg); enabled = _get_gpio_irqbank_mask(bank);
isr_saved = isr = __raw_readl(isr_reg) & enabled;
if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
isr &= 0x0000ffff; isr &= 0x0000ffff;
if (cpu_is_omap24xx()) if (cpu_is_omap24xx()) {
level_mask = level_mask =
__raw_readl(bank->base + __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT0) | OMAP24XX_GPIO_LEVELDETECT0) |
__raw_readl(bank->base + __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT1); OMAP24XX_GPIO_LEVELDETECT1);
level_mask &= enabled;
}
/* clear edge sensitive interrupts before handler(s) are /* clear edge sensitive interrupts before handler(s) are
called so that we don't miss any interrupt occurred while called so that we don't miss any interrupt occurred while
...@@ -782,19 +831,54 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -782,19 +831,54 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
/* if there is only edge sensitive GPIO pin interrupts /* if there is only edge sensitive GPIO pin interrupts
configured, we could unmask GPIO bank interrupt immediately */ configured, we could unmask GPIO bank interrupt immediately */
if (!level_mask) if (!level_mask && !unmasked) {
unmasked = 1;
desc->chip->unmask(irq); desc->chip->unmask(irq);
}
isr |= retrigger;
retrigger = 0;
if (!isr) if (!isr)
break; break;
gpio_irq = bank->virtual_irq_start; gpio_irq = bank->virtual_irq_start;
for (; isr != 0; isr >>= 1, gpio_irq++) { for (; isr != 0; isr >>= 1, gpio_irq++) {
struct irqdesc *d; struct irqdesc *d;
int irq_mask;
if (!(isr & 1)) if (!(isr & 1))
continue; continue;
d = irq_desc + gpio_irq; d = irq_desc + gpio_irq;
/* Don't run the handler if it's already running
* or was disabled lazely.
*/
if (unlikely((d->disable_depth || d->running))) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
/* The unmasking will be done by
* enable_irq in case it is disabled or
* after returning from the handler if
* it's already running.
*/
_enable_gpio_irqbank(bank, irq_mask, 0);
if (!d->disable_depth) {
/* Level triggered interrupts
* won't ever be reentered
*/
BUG_ON(level_mask & irq_mask);
d->pending = 1;
}
continue;
}
d->running = 1;
desc_handle_irq(gpio_irq, d, regs); desc_handle_irq(gpio_irq, d, regs);
d->running = 0;
if (unlikely(d->pending && !d->disable_depth)) {
irq_mask = 1 <<
(gpio_irq - bank->virtual_irq_start);
d->pending = 0;
_enable_gpio_irqbank(bank, irq_mask, 1);
retrigger |= irq_mask;
}
} }
if (cpu_is_omap24xx()) { if (cpu_is_omap24xx()) {
...@@ -804,13 +888,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -804,13 +888,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
_enable_gpio_irqbank(bank, isr_saved & level_mask, 1); _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
} }
}
/* if bank has any level sensitive GPIO pin interrupt /* if bank has any level sensitive GPIO pin interrupt
configured, we must unmask the bank interrupt only after configured, we must unmask the bank interrupt only after
handler(s) are executed in order to avoid spurious bank handler(s) are executed in order to avoid spurious bank
interrupt */ interrupt */
if (level_mask) if (!unmasked)
desc->chip->unmask(irq); desc->chip->unmask(irq);
}
} }
static void gpio_ack_irq(unsigned int irq) static void gpio_ack_irq(unsigned int irq)
......
...@@ -158,14 +158,12 @@ static struct map_desc omap_sram_io_desc[] __initdata = { ...@@ -158,14 +158,12 @@ static struct map_desc omap_sram_io_desc[] __initdata = {
{ /* .length gets filled in at runtime */ { /* .length gets filled in at runtime */
.virtual = OMAP1_SRAM_VA, .virtual = OMAP1_SRAM_VA,
.pfn = __phys_to_pfn(OMAP1_SRAM_PA), .pfn = __phys_to_pfn(OMAP1_SRAM_PA),
.type = MT_DEVICE .type = MT_MEMORY
} }
}; };
/* /*
* In order to use last 2kB of SRAM on 1611b, we must round the size * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
* up to multiple of PAGE_SIZE. We cannot use ioremap for SRAM, as
* clock init needs SRAM early.
*/ */
void __init omap_map_sram(void) void __init omap_map_sram(void)
{ {
...@@ -185,8 +183,7 @@ void __init omap_map_sram(void) ...@@ -185,8 +183,7 @@ void __init omap_map_sram(void)
omap_sram_io_desc[0].pfn = __phys_to_pfn(base); omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
} }
omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */
omap_sram_io_desc[0].length *= PAGE_SIZE;
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); 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", printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Partial timer rewrite and additional dynamic tick timer support by * Partial timer rewrite and additional dynamic tick timer support by
* Tony Lindgen <tony@atomide.com> and * Tony Lindgen <tony@atomide.com> and
* Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
* OMAP Dual-mode timer framework support by Timo Teras
* *
* MPU timer code based on the older MPU timer code for OMAP * MPU timer code based on the older MPU timer code for OMAP
* Copyright (C) 2000 RidgeRun, Inc. * Copyright (C) 2000 RidgeRun, Inc.
...@@ -79,18 +80,6 @@ struct sys_timer omap_timer; ...@@ -79,18 +80,6 @@ struct sys_timer omap_timer;
#define OMAP1_32K_TIMER_TVR 0x00 #define OMAP1_32K_TIMER_TVR 0x00
#define OMAP1_32K_TIMER_TCR 0x04 #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) #define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
/* /*
...@@ -102,54 +91,64 @@ struct sys_timer omap_timer; ...@@ -102,54 +91,64 @@ struct sys_timer omap_timer;
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
(((nr_jiffies) * (clock_rate)) / HZ) (((nr_jiffies) * (clock_rate)) / HZ)
#if defined(CONFIG_ARCH_OMAP1)
static inline void omap_32k_timer_write(int val, int reg) static inline void omap_32k_timer_write(int val, int reg)
{ {
if (cpu_class_is_omap1())
omap_writew(val, OMAP1_32K_TIMER_BASE + reg); 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) static inline unsigned long omap_32k_timer_read(int reg)
{ {
if (cpu_class_is_omap1())
return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
}
if (cpu_is_omap24xx()) static inline void omap_32k_timer_start(unsigned long load_val)
return omap_readl(OMAP2_GP_TIMER_BASE + reg); {
omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
} }
/* static inline void omap_32k_timer_stop(void)
* 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); omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
} }
#define omap_32k_timer_ack_irq()
#elif defined(CONFIG_ARCH_OMAP2)
#include <asm/arch/dmtimer.h>
static struct omap_dm_timer *gptimer;
static inline void omap_32k_timer_start(unsigned long load_val) static inline void omap_32k_timer_start(unsigned long load_val)
{ {
if (cpu_class_is_omap1()) { omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val);
omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); omap_dm_timer_start(gptimer);
}
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) static inline void omap_32k_timer_stop(void)
{ {
if (cpu_class_is_omap1()) omap_dm_timer_stop(gptimer);
omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); }
if (cpu_is_omap24xx()) static inline void omap_32k_timer_ack_irq(void)
omap_32k_timer_write(0x0, GP_TIMER_TCLR); {
u32 status = omap_dm_timer_read_status(gptimer);
omap_dm_timer_write_status(gptimer, status);
}
#endif
/*
* 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);
} }
/* /*
...@@ -203,11 +202,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, ...@@ -203,11 +202,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
write_seqlock_irqsave(&xtime_lock, flags); write_seqlock_irqsave(&xtime_lock, flags);
if (cpu_is_omap24xx()) { omap_32k_timer_ack_irq();
u32 status = omap_32k_timer_read(GP_TIMER_TISR);
omap_32k_timer_write(status, GP_TIMER_TISR);
}
now = omap_32k_sync_timer_read(); now = omap_32k_sync_timer_read();
while ((signed long)(now - omap_32k_last_tick) while ((signed long)(now - omap_32k_last_tick)
...@@ -269,9 +264,6 @@ static struct irqaction omap_32k_timer_irq = { ...@@ -269,9 +264,6 @@ static struct irqaction omap_32k_timer_irq = {
.handler = omap_32k_timer_interrupt, .handler = omap_32k_timer_interrupt,
}; };
static struct clk * gpt1_ick;
static struct clk * gpt1_fck;
static __init void omap_init_32k_timer(void) static __init void omap_init_32k_timer(void)
{ {
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
...@@ -280,31 +272,19 @@ static __init void omap_init_32k_timer(void) ...@@ -280,31 +272,19 @@ static __init void omap_init_32k_timer(void)
if (cpu_class_is_omap1()) if (cpu_class_is_omap1())
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); 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_timer.offset = omap_32k_timer_gettimeoffset;
omap_32k_last_tick = omap_32k_sync_timer_read(); omap_32k_last_tick = omap_32k_sync_timer_read();
/* REVISIT: Check 24xx TIOCP_CFG settings after idle works */ /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */
if (cpu_is_omap24xx()) { if (cpu_is_omap24xx()) {
omap_32k_timer_write(0, GP_TIMER_TCLR); gptimer = omap_dm_timer_request_specific(1);
omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */ BUG_ON(gptimer == NULL);
gpt1_ick = clk_get(NULL, "gpt1_ick"); omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
if (IS_ERR(gpt1_ick)) setup_irq(omap_dm_timer_get_irq(gptimer), &omap_32k_timer_irq);
printk(KERN_ERR "Could not get gpt1_ick\n"); omap_dm_timer_set_int_enable(gptimer,
else OMAP_TIMER_INT_CAPTURE | OMAP_TIMER_INT_OVERFLOW |
clk_enable(gpt1_ick); OMAP_TIMER_INT_MATCH);
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); omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
...@@ -317,6 +297,9 @@ static __init void omap_init_32k_timer(void) ...@@ -317,6 +297,9 @@ static __init void omap_init_32k_timer(void)
*/ */
static void __init omap_timer_init(void) static void __init omap_timer_init(void)
{ {
#ifdef CONFIG_OMAP_DM_TIMER
omap_dm_timer_init();
#endif
omap_init_32k_timer(); omap_init_32k_timer();
} }
......
...@@ -663,7 +663,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -663,7 +663,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
return; return;
} }
/* FIXME: We really should do something to _handle_ the errors */ /* FIXME: We really should do something to _handle_ the errors */
if (ch_status & OMAP_DMA_TOUT_IRQ) { if (ch_status & OMAP1_DMA_TOUT_IRQ) {
dev_err(mmc_dev(host->mmc),"DMA timeout\n"); dev_err(mmc_dev(host->mmc),"DMA timeout\n");
return; return;
} }
......
...@@ -773,7 +773,7 @@ static void dma_error(int lch, u16 ch_status, void *data) ...@@ -773,7 +773,7 @@ static void dma_error(int lch, u16 ch_status, void *data)
struct omap_ep *ep = data; struct omap_ep *ep = data;
/* if ch_status & OMAP_DMA_DROP_IRQ ... */ /* if ch_status & OMAP_DMA_DROP_IRQ ... */
/* if ch_status & OMAP_DMA_TOUT_IRQ ... */ /* if ch_status & OMAP1_DMA_TOUT_IRQ ... */
ERR("%s dma error, lch %d status %02x\n", ep->ep.name, lch, ch_status); ERR("%s dma error, lch %d status %02x\n", ep->ep.name, lch, ch_status);
/* complete current transfer ... */ /* complete current transfer ... */
......
/*
* linux/include/asm-arm/arch-omap/board-fsample.h
*
* Board-specific goodies for TI F-Sample.
*
* Copyright (C) 2006 Google, Inc.
* Author: Brian Swetland <swetland@google.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.
*/
#ifndef __ASM_ARCH_OMAP_FSAMPLE_H
#define __ASM_ARCH_OMAP_FSAMPLE_H
/* fsample is pretty close to p2-sample */
#include <asm/arch/board-perseus2.h>
#define fsample_cpld_read(reg) __raw_readb(reg)
#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
#define FSAMPLE_CPLD_BASE 0xE8100000
#define FSAMPLE_CPLD_SIZE SZ_4K
#define FSAMPLE_CPLD_START 0x05080000
#define FSAMPLE_CPLD_REG_A (FSAMPLE_CPLD_BASE + 0x00)
#define FSAMPLE_CPLD_SWITCH (FSAMPLE_CPLD_BASE + 0x02)
#define FSAMPLE_CPLD_UART (FSAMPLE_CPLD_BASE + 0x02)
#define FSAMPLE_CPLD_REG_B (FSAMPLE_CPLD_BASE + 0x04)
#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
#define FSAMPLE_CPLD_BIT_BT_RESET 0
#define FSAMPLE_CPLD_BIT_LCD_RESET 1
#define FSAMPLE_CPLD_BIT_CAM_PWDN 2
#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE 3
#define FSAMPLE_CPLD_BIT_SD_MMC_EN 4
#define FSAMPLE_CPLD_BIT_aGPS_PWREN 5
#define FSAMPLE_CPLD_BIT_BACKLIGHT 6
#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET 7
#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N 8
#define FSAMPLE_CPLD_BIT_OTG_RESET 9
#define fsample_cpld_set(bit) \
fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
#define fsample_cpld_clear(bit) \
fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
#endif
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define OMAP_TAG_UART 0x4f07 #define OMAP_TAG_UART 0x4f07
#define OMAP_TAG_FBMEM 0x4f08 #define OMAP_TAG_FBMEM 0x4f08
#define OMAP_TAG_STI_CONSOLE 0x4f09 #define OMAP_TAG_STI_CONSOLE 0x4f09
#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
#define OMAP_TAG_BOOT_REASON 0x4f80 #define OMAP_TAG_BOOT_REASON 0x4f80
#define OMAP_TAG_FLASH_PART 0x4f81 #define OMAP_TAG_FLASH_PART 0x4f81
...@@ -61,6 +62,12 @@ struct omap_sti_console_config { ...@@ -61,6 +62,12 @@ struct omap_sti_console_config {
u8 channel; u8 channel;
}; };
struct omap_camera_sensor_config {
u16 reset_gpio;
int (*power_on)(void * data);
int (*power_off)(void * data);
};
struct omap_usb_config { struct omap_usb_config {
/* Configure drivers according to the connectors on your board: /* Configure drivers according to the connectors on your board:
* - "A" connector (rectagular) * - "A" connector (rectagular)
......
...@@ -185,8 +185,8 @@ ...@@ -185,8 +185,8 @@
/* DMA channels for 24xx */ /* DMA channels for 24xx */
#define OMAP24XX_DMA_NO_DEVICE 0 #define OMAP24XX_DMA_NO_DEVICE 0
#define OMAP24XX_DMA_XTI_DMA 1 /* S_DMA_0 */ #define OMAP24XX_DMA_XTI_DMA 1 /* S_DMA_0 */
#define OMAP24XX_DMA_EXT_NDMA_REQ0 2 /* S_DMA_1 */ #define OMAP24XX_DMA_EXT_DMAREQ0 2 /* S_DMA_1 */
#define OMAP24XX_DMA_EXT_NDMA_REQ1 3 /* S_DMA_2 */ #define OMAP24XX_DMA_EXT_DMAREQ1 3 /* S_DMA_2 */
#define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */ #define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */
#define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */ #define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */
#define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */ #define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */
...@@ -197,7 +197,9 @@ ...@@ -197,7 +197,9 @@
#define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */ #define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */
#define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */ #define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */
#define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */ #define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */
#define OMAP24XX_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */
#define OMAP24XX_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */
#define OMAP24XX_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */
#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */ #define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */
#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */ #define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */
#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */ #define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
...@@ -244,6 +246,7 @@ ...@@ -244,6 +246,7 @@
#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */ #define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */
#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */ #define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */
#define OMAP24XX_DMA_MS 63 /* SDMA_62 */ #define OMAP24XX_DMA_MS 63 /* SDMA_62 */
#define OMAP24XX_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
...@@ -274,7 +277,7 @@ ...@@ -274,7 +277,7 @@
#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea) #define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4) #define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
#define OMAP_DMA_TOUT_IRQ (1 << 0) /* Only on omap1 */ #define OMAP1_DMA_TOUT_IRQ (1 << 0)
#define OMAP_DMA_DROP_IRQ (1 << 1) #define OMAP_DMA_DROP_IRQ (1 << 1)
#define OMAP_DMA_HALF_IRQ (1 << 2) #define OMAP_DMA_HALF_IRQ (1 << 2)
#define OMAP_DMA_FRAME_IRQ (1 << 3) #define OMAP_DMA_FRAME_IRQ (1 << 3)
...@@ -315,11 +318,11 @@ enum { ...@@ -315,11 +318,11 @@ enum {
OMAP_LCD_DMA_B2_BOTTOM OMAP_LCD_DMA_B2_BOTTOM
}; };
/* REVISIT: Check if BURST_4 is really 1 (or 2) */
enum omap_dma_burst_mode { enum omap_dma_burst_mode {
OMAP_DMA_DATA_BURST_DIS = 0, OMAP_DMA_DATA_BURST_DIS = 0,
OMAP_DMA_DATA_BURST_4, OMAP_DMA_DATA_BURST_4,
OMAP_DMA_DATA_BURST_8 OMAP_DMA_DATA_BURST_8,
OMAP_DMA_DATA_BURST_16,
}; };
enum omap_dma_color_mode { enum omap_dma_color_mode {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Copyright (C) 2005 Nokia Corporation * Copyright (C) 2005 Nokia Corporation
* Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
* PWM and clock framwork support by Timo Teras.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
...@@ -25,69 +26,56 @@ ...@@ -25,69 +26,56 @@
* 675 Mass Ave, Cambridge, MA 02139, USA. * 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef __ASM_ARCH_TIMER_H #ifndef __ASM_ARCH_DMTIMER_H
#define __ASM_ARCH_TIMER_H #define __ASM_ARCH_DMTIMER_H
#include <linux/list.h> /* clock sources */
#define OMAP_TIMER_SRC_SYS_CLK 0x00
#define OMAP_TIMER_SRC_ARMXOR 0x00
#define OMAP_TIMER_SRC_32_KHZ 0x01 #define OMAP_TIMER_SRC_32_KHZ 0x01
#define OMAP_TIMER_SRC_EXT_CLK 0x02 #define OMAP_TIMER_SRC_EXT_CLK 0x02
/* timer control reg bits */
#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
#define OMAP_TIMER_CTRL_PT (1 << 12)
#define OMAP_TIMER_CTRL_TRG_OVERFLOW (0x1 << 10)
#define OMAP_TIMER_CTRL_TRG_OFANDMATCH (0x2 << 10)
#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* how much to shift the prescaler value */
#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
/* timer interrupt enable bits */ /* timer interrupt enable bits */
#define OMAP_TIMER_INT_CAPTURE (1 << 2) #define OMAP_TIMER_INT_CAPTURE (1 << 2)
#define OMAP_TIMER_INT_OVERFLOW (1 << 1) #define OMAP_TIMER_INT_OVERFLOW (1 << 1)
#define OMAP_TIMER_INT_MATCH (1 << 0) #define OMAP_TIMER_INT_MATCH (1 << 0)
/* trigger types */
#define OMAP_TIMER_TRIGGER_NONE 0x00
#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
struct omap_dm_timer { struct omap_dm_timer;
struct list_head timer_list; struct clk;
u32 base; int omap_dm_timer_init(void);
unsigned int irq;
};
u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg); struct omap_dm_timer *omap_dm_timer_request(void);
void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value); struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer * omap_dm_timer_request(void);
void omap_dm_timer_free(struct omap_dm_timer *timer); void omap_dm_timer_free(struct omap_dm_timer *timer);
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value); int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value);
void omap_dm_timer_enable_compare(struct omap_dm_timer *timer); u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer); struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
void omap_dm_timer_trigger(struct omap_dm_timer *timer); void omap_dm_timer_trigger(struct omap_dm_timer *timer);
void omap_dm_timer_start(struct omap_dm_timer *timer); void omap_dm_timer_start(struct omap_dm_timer *timer);
void omap_dm_timer_stop(struct omap_dm_timer *timer); void omap_dm_timer_stop(struct omap_dm_timer *timer);
void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load); void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match); void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer); unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value); void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer); unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
void omap_dm_timer_reset_counter(struct omap_dm_timer *timer); void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
int omap_dm_timers_active(void); int omap_dm_timers_active(void);
u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
#endif /* __ASM_ARCH_TIMER_H */
#endif /* __ASM_ARCH_DMTIMER_H */
/*
* General-Purpose Memory Controller for OMAP2
*
* Copyright (C) 2005-2006 Nokia Corporation
*
* 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 __OMAP2_GPMC_H
#define __OMAP2_GPMC_H
#define GPMC_CS_CONFIG1 0x00
#define GPMC_CS_CONFIG2 0x04
#define GPMC_CS_CONFIG3 0x08
#define GPMC_CS_CONFIG4 0x0c
#define GPMC_CS_CONFIG5 0x10
#define GPMC_CS_CONFIG6 0x14
#define GPMC_CS_CONFIG7 0x18
#define GPMC_CS_NAND_COMMAND 0x1c
#define GPMC_CS_NAND_ADDRESS 0x20
#define GPMC_CS_NAND_DATA 0x24
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 20)
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29)
#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22)
#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21)
#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
#define GPMC_CONFIG1_DEVICETYPE_NAND GPMC_CONFIG1_DEVICETYPE(1)
#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2))
#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
/*
* Note that all values in this struct are in nanoseconds, while
* the register values are in gpmc_fck cycles.
*/
struct gpmc_timings {
/* Minimum clock period for synchronous mode */
u16 sync_clk;
/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
u16 cs_on; /* Assertion time */
u16 cs_rd_off; /* Read deassertion time */
u16 cs_wr_off; /* Write deassertion time */
/* ADV signal timings corresponding to GPMC_CONFIG3 */
u16 adv_on; /* Assertion time */
u16 adv_rd_off; /* Read deassertion time */
u16 adv_wr_off; /* Write deassertion time */
/* WE signals timings corresponding to GPMC_CONFIG4 */
u16 we_on; /* WE assertion time */
u16 we_off; /* WE deassertion time */
/* OE signals timings corresponding to GPMC_CONFIG4 */
u16 oe_on; /* OE assertion time */
u16 oe_off; /* OE deassertion time */
/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
u16 page_burst_access; /* Multiple access word delay */
u16 access; /* Start-cycle to first data valid delay */
u16 rd_cycle; /* Total read cycle time */
u16 wr_cycle; /* Total write cycle time */
};
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
extern u32 gpmc_cs_read_reg(int cs, int idx);
extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
extern unsigned long gpmc_cs_get_base_addr(int cs);
#endif
...@@ -297,6 +297,10 @@ ...@@ -297,6 +297,10 @@
#include "board-perseus2.h" #include "board-perseus2.h"
#endif #endif
#ifdef CONFIG_MACH_OMAP_FSAMPLE
#include "board-fsample.h"
#endif
#ifdef CONFIG_MACH_OMAP_H3 #ifdef CONFIG_MACH_OMAP_H3
#include "board-h3.h" #include "board-h3.h"
#endif #endif
......
...@@ -242,10 +242,24 @@ ...@@ -242,10 +242,24 @@
#define INT_24XX_GPIO_BANK2 30 #define INT_24XX_GPIO_BANK2 30
#define INT_24XX_GPIO_BANK3 31 #define INT_24XX_GPIO_BANK3 31
#define INT_24XX_GPIO_BANK4 32 #define INT_24XX_GPIO_BANK4 32
#define INT_24XX_GPTIMER1 37
#define INT_24XX_GPTIMER2 38
#define INT_24XX_GPTIMER3 39
#define INT_24XX_GPTIMER4 40
#define INT_24XX_GPTIMER5 41
#define INT_24XX_GPTIMER6 42
#define INT_24XX_GPTIMER7 43
#define INT_24XX_GPTIMER8 44
#define INT_24XX_GPTIMER9 45
#define INT_24XX_GPTIMER10 46
#define INT_24XX_GPTIMER11 47
#define INT_24XX_GPTIMER12 48
#define INT_24XX_MCBSP1_IRQ_TX 59 #define INT_24XX_MCBSP1_IRQ_TX 59
#define INT_24XX_MCBSP1_IRQ_RX 60 #define INT_24XX_MCBSP1_IRQ_RX 60
#define INT_24XX_MCBSP2_IRQ_TX 62 #define INT_24XX_MCBSP2_IRQ_TX 62
#define INT_24XX_MCBSP2_IRQ_RX 63 #define INT_24XX_MCBSP2_IRQ_RX 63
#define INT_24XX_UART1_IRQ 72
#define INT_24XX_UART2_IRQ 73
#define INT_24XX_UART3_IRQ 74 #define INT_24XX_UART3_IRQ 74
/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
......
...@@ -410,6 +410,12 @@ enum omap24xx_index { ...@@ -410,6 +410,12 @@ enum omap24xx_index {
/* 24xx clock */ /* 24xx clock */
W14_24XX_SYS_CLKOUT, W14_24XX_SYS_CLKOUT,
/* 24xx GPMC wait pin monitoring */
L3_GPMC_WAIT0,
N7_GPMC_WAIT1,
M1_GPMC_WAIT2,
P1_GPMC_WAIT3,
/* 242X McBSP */ /* 242X McBSP */
Y15_24XX_MCBSP2_CLKX, Y15_24XX_MCBSP2_CLKX,
R14_24XX_MCBSP2_FSX, R14_24XX_MCBSP2_FSX,
...@@ -429,6 +435,26 @@ enum omap24xx_index { ...@@ -429,6 +435,26 @@ enum omap24xx_index {
M15_24XX_GPIO92, M15_24XX_GPIO92,
V14_24XX_GPIO117, V14_24XX_GPIO117,
/* 242x DBG GPIO */
V4_242X_GPIO49,
W2_242X_GPIO50,
U4_242X_GPIO51,
V3_242X_GPIO52,
V2_242X_GPIO53,
V6_242X_GPIO53,
T4_242X_GPIO54,
Y4_242X_GPIO54,
T3_242X_GPIO55,
U2_242X_GPIO56,
/* 24xx external DMA requests */
AA10_242X_DMAREQ0,
AA6_242X_DMAREQ1,
E4_242X_DMAREQ2,
G4_242X_DMAREQ3,
D3_242X_DMAREQ4,
E3_242X_DMAREQ5,
P20_24XX_TSC_IRQ, P20_24XX_TSC_IRQ,
/* UART3 */ /* UART3 */
......
...@@ -299,10 +299,43 @@ enum omap24xx_save_state { ...@@ -299,10 +299,43 @@ enum omap24xx_save_state {
OMAP24XX_SLEEP_SAVE_INTC_MIR0, OMAP24XX_SLEEP_SAVE_INTC_MIR0,
OMAP24XX_SLEEP_SAVE_INTC_MIR1, OMAP24XX_SLEEP_SAVE_INTC_MIR1,
OMAP24XX_SLEEP_SAVE_INTC_MIR2, OMAP24XX_SLEEP_SAVE_INTC_MIR2,
OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_MPU,
OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_CORE,
OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_GFX,
OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_DSP,
OMAP24XX_SLEEP_SAVE_CM_CLKSTCTRL_MDM,
OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_MPU,
OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_CORE,
OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_GFX,
OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_DSP,
OMAP24XX_SLEEP_SAVE_PM_PWSTCTRL_MDM,
OMAP24XX_SLEEP_SAVE_CM_IDLEST1_CORE,
OMAP24XX_SLEEP_SAVE_CM_IDLEST2_CORE,
OMAP24XX_SLEEP_SAVE_CM_IDLEST3_CORE,
OMAP24XX_SLEEP_SAVE_CM_IDLEST4_CORE,
OMAP24XX_SLEEP_SAVE_CM_IDLEST_GFX,
OMAP24XX_SLEEP_SAVE_CM_IDLEST_WKUP,
OMAP24XX_SLEEP_SAVE_CM_IDLEST_CKGEN,
OMAP24XX_SLEEP_SAVE_CM_IDLEST_DSP,
OMAP24XX_SLEEP_SAVE_CM_IDLEST_MDM,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE1_CORE,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE2_CORE,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE3_CORE,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE4_CORE,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_WKUP,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_PLL,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_DSP,
OMAP24XX_SLEEP_SAVE_CM_AUTOIDLE_MDM,
OMAP24XX_SLEEP_SAVE_CM_FCLKEN1_CORE, OMAP24XX_SLEEP_SAVE_CM_FCLKEN1_CORE,
OMAP24XX_SLEEP_SAVE_CM_FCLKEN2_CORE, OMAP24XX_SLEEP_SAVE_CM_FCLKEN2_CORE,
OMAP24XX_SLEEP_SAVE_CM_ICLKEN1_CORE, OMAP24XX_SLEEP_SAVE_CM_ICLKEN1_CORE,
OMAP24XX_SLEEP_SAVE_CM_ICLKEN2_CORE, OMAP24XX_SLEEP_SAVE_CM_ICLKEN2_CORE,
OMAP24XX_SLEEP_SAVE_CM_ICLKEN3_CORE,
OMAP24XX_SLEEP_SAVE_CM_ICLKEN4_CORE, OMAP24XX_SLEEP_SAVE_CM_ICLKEN4_CORE,
OMAP24XX_SLEEP_SAVE_GPIO1_IRQENABLE1, OMAP24XX_SLEEP_SAVE_GPIO1_IRQENABLE1,
OMAP24XX_SLEEP_SAVE_GPIO2_IRQENABLE1, OMAP24XX_SLEEP_SAVE_GPIO2_IRQENABLE1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment