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
  ...
This commit is contained in:
Russell King
2006-06-29 16:23:47 +01:00
committed by Russell King
41 changed files with 2266 additions and 472 deletions
+1 -1
View File
@@ -678,7 +678,7 @@ config XIP_PHYS_ADDR
endmenu
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1)
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
menu "CPU Frequency scaling"
+7
View File
@@ -62,6 +62,13 @@ config MACH_OMAP_PERSEUS2
Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
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
bool "Voiceblue"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
+1
View File
@@ -17,6 +17,7 @@ obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
obj-$(CONFIG_MACH_OMAP_FSAMPLE) += board-fsample.o
obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
+7
View File
@@ -80,8 +80,15 @@ static struct omap_uart_config ams_delta_uart_config __initdata = {
.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[] = {
{ OMAP_TAG_UART, &ams_delta_uart_config },
{ OMAP_TAG_USB, &ams_delta_usb_config },
};
static struct platform_device ams_delta_led_device = {
+319
View File
@@ -0,0 +1,319 @@
/*
* 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
+75
View File
@@ -37,6 +37,8 @@
#include <asm/arch/usb.h>
#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
#include <asm/arch/mcbsp.h>
#include <asm/arch/omap-alsa.h>
static int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
@@ -112,6 +114,42 @@ static struct platform_device innovator_flash_device = {
.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[] = {
[0] = {
.start = INT_KEYBOARD,
@@ -139,6 +177,10 @@ static struct platform_device innovator_kp_device = {
#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 */
static struct map_desc innovator1510_io_desc[] __initdata = {
{
@@ -174,13 +216,44 @@ static struct platform_device innovator1510_lcd_device = {
.id = -1,
};
static struct platform_device innovator1510_spi_device = {
.name = "spi_inn1510",
.id = -1,
};
static struct platform_device *innovator1510_devices[] __initdata = {
&innovator_flash_device,
&innovator1510_smc91x_device,
&innovator_mcbsp1_device,
&innovator_kp_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 */
#ifdef CONFIG_ARCH_OMAP16XX
@@ -311,6 +384,8 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
spi_register_board_info(innovator1510_boardinfo,
ARRAY_SIZE(innovator1510_boardinfo));
}
#endif
#ifdef CONFIG_ARCH_OMAP16XX
+94 -53
View File
@@ -33,7 +33,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -45,25 +44,10 @@
#include <asm/arch/usb.h>
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
#include <asm/arch/mcbsp.h>
#include <asm/arch/omap-alsa.h>
static int osk_keymap[] = {
KEY(0, 0, KEY_F1),
KEY(0, 3, KEY_UP),
KEY(1, 1, KEY_LEFTCTRL),
KEY(1, 2, KEY_LEFT),
KEY(2, 0, KEY_SPACE),
KEY(2, 1, KEY_ESC),
KEY(2, 2, KEY_DOWN),
KEY(3, 2, KEY_ENTER),
KEY(3, 3, KEY_RIGHT),
0
};
static struct mtd_partition osk_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -181,48 +165,17 @@ static struct omap_alsa_codec_config alsa_config = {
static struct platform_device osk5912_mcbsp1_device = {
.name = "omap_alsa_mcbsp",
.id = 1,
.id = 1,
.dev = {
.platform_data = &alsa_config,
},
};
static struct resource osk5912_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
.end = INT_KEYBOARD,
.flags = IORESOURCE_IRQ,
},
};
static struct omap_kp_platform_data osk_kp_data = {
.rows = 8,
.cols = 8,
.keymap = osk_keymap,
};
static struct platform_device osk5912_kp_device = {
.name = "omap-keypad",
.id = -1,
.dev = {
.platform_data = &osk_kp_data,
},
.num_resources = ARRAY_SIZE(osk5912_kp_resources),
.resource = osk5912_kp_resources,
};
static struct platform_device osk5912_lcd_device = {
.name = "lcd_osk",
.id = -1,
};
static struct platform_device *osk5912_devices[] __initdata = {
&osk5912_flash_device,
&osk5912_smc91x_device,
&osk5912_cf_device,
&osk5912_mcbsp1_device,
&osk5912_kp_device,
&osk5912_lcd_device,
};
static void __init osk_init_smc91x(void)
@@ -276,18 +229,100 @@ static struct omap_uart_config osk_uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
#ifdef CONFIG_OMAP_OSK_MISTRAL
static struct omap_lcd_config osk_lcd_config __initdata = {
.ctrl_name = "internal",
};
#endif
static struct omap_board_config_kernel osk_config[] = {
{ OMAP_TAG_USB, &osk_usb_config },
{ OMAP_TAG_UART, &osk_uart_config },
#ifdef CONFIG_OMAP_OSK_MISTRAL
{ OMAP_TAG_LCD, &osk_lcd_config },
#endif
};
#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
static irqreturn_t
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)
{
/* FIXME here's where to feed in framebuffer, touchpad, and
* keyboard setup ... not in the drivers for those devices!
*
* NOTE: we could actually tell if there's a Mistral board
/* NOTE: we could actually tell if there's a Mistral board
* 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 */
omap_cfg_reg(N15_1610_MPUIO2);
if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
@@ -329,6 +368,8 @@ static void __init osk_mistral_init(void)
#endif
} else
printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices));
}
#else
static void __init osk_mistral_init(void) { }
+14 -4
View File
@@ -1,3 +1,4 @@
//kernel/linux-omap-fsample/arch/arm/mach-omap1/clock.c#2 - edit change 3808 (text)
/*
* linux/arch/arm/mach-omap1/clock.c
*
@@ -20,6 +21,7 @@
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/usb.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
@@ -270,8 +272,12 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
/*
* In most cases we should not need to reprogram DPLL.
* Reprogramming the DPLL is tricky, it must be done from SRAM.
* (on 730, bit 13 must always be 1)
*/
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
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);
ck_dpll1.rate = ptr->pll_rate;
propagate_rate(&ck_dpll1);
@@ -748,7 +754,7 @@ int __init omap1_clk_init(void)
printk(KERN_ERR "System frequencies not set. Check your config.\n");
/* Guess sane values (60MHz) */
omap_writew(0x2290, DPLL_CTL);
omap_writew(0x1005, ARM_CKCTL);
omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
ck_dpll1.rate = 60000000;
propagate_rate(&ck_dpll1);
}
@@ -761,13 +767,17 @@ int __init omap1_clk_init(void)
ck_dpll1.rate / 1000000, (ck_dpll1.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 */
omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
#endif
/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
/* (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);
/* Put DSP/MPUI into reset until needed */
omap_writew(0, ARM_RSTCT1);
+5 -2
View File
@@ -1,3 +1,4 @@
//kernel/linux-omap-fsample/arch/arm/mach-omap1/pm.c#3 - integrate change 4545 (text)
/*
* linux/arch/arm/mach-omap1/pm.c
*
@@ -50,6 +51,7 @@
#include <asm/mach/irq.h>
#include <asm/mach-types.h>
#include <asm/arch/cpu.h>
#include <asm/arch/irqs.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
@@ -326,8 +328,9 @@ void omap_pm_suspend(void)
/* stop DSP */
omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
/* shut down dsp_ck */
omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
/* shut down dsp_ck */
if (!cpu_is_omap730())
omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
/* temporarily enabling api_ck to access DSP registers */
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
+1 -1
View File
@@ -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
* 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
* framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
*/
+1
View File
@@ -8,6 +8,7 @@ config ARCH_OMAP24XX
config ARCH_OMAP2420
bool "OMAP2420 support"
depends on ARCH_OMAP24XX
select OMAP_DM_TIMER
comment "OMAP Board Type"
depends on ARCH_OMAP2
+3 -2
View File
@@ -3,12 +3,13 @@
#
# 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
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
+23 -14
View File
@@ -660,26 +660,35 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
/* Isolate control register */
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);
if(validrate != rate)
if (validrate != rate)
return(ret);
field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
if (div_sel == 0)
return ret;
if(clk->flags & CM_SYSCLKOUT_SEL1){
switch(new_div){
case 16: field_val = 4; break;
case 8: field_val = 3; break;
case 4: field_val = 2; break;
case 2: field_val = 1; break;
case 1: field_val = 0; break;
if (clk->flags & CM_SYSCLKOUT_SEL1) {
switch (new_div) {
case 16:
field_val = 4;
break;
case 8:
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;
reg = (void __iomem *)div_sel;
@@ -744,7 +753,7 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
val = 0x2;
break;
case CM_WKUP_SEL1:
src_reg_addr = (u32)&CM_CLKSEL2_CORE;
src_reg_addr = (u32)&CM_CLKSEL_WKUP;
mask = 0x3;
if (src_clk == &func_32k_ck)
val = 0x0;
@@ -784,9 +793,9 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
val = 0;
if (src_clk == &sys_ck)
val = 1;
if (src_clk == &func_54m_ck)
val = 2;
if (src_clk == &func_96m_ck)
val = 2;
if (src_clk == &func_54m_ck)
val = 3;
break;
}
+1 -1
View File
@@ -1062,7 +1062,7 @@ static struct clk gpt2_ick = {
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit4 */
.enable_bit = 0,
.enable_bit = 4,
.recalc = &omap2_followparent_recalc,
};
+46
View File
@@ -105,6 +105,51 @@ static inline void omap_init_sti(void)
static inline void omap_init_sti(void) {}
#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)
@@ -113,6 +158,7 @@ static int __init omap2_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
omap_init_i2c();
omap_init_mcspi();
omap_init_sti();
return 0;
+209
View File
@@ -0,0 +1,209 @@
/*
* 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);
}
+2
View File
@@ -27,6 +27,7 @@
extern void omap_sram_init(void);
extern int omap2_clk_init(void);
extern void omap2_check_revision(void);
extern void gpmc_init(void);
/*
* The machine specific code may provide the extra mapping besides the
@@ -67,4 +68,5 @@ void __init omap2_init_common_hw(void)
{
omap2_mux_init();
omap2_clk_init();
gpmc_init();
}
+32 -6
View File
@@ -53,6 +53,12 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
/* 24xx clocks */
MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
/* 24xx 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 */
MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1)
MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
@@ -60,18 +66,38 @@ MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
/* 24xx GPIO */
MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
/* 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 */
MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
+300
View File
@@ -0,0 +1,300 @@
/*
* 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);
}
+265 -6
View File
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -36,11 +37,18 @@
#include <asm/arch/sram.h>
#include <asm/arch/pm.h>
#include "prcm-regs.h"
static struct clk *vclk;
static void (*omap2_sram_idle)(void);
static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
static void (*saved_idle)(void);
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)
{
local_irq_disable();
@@ -87,23 +95,272 @@ static int omap2_pm_prepare(suspend_state_t state)
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)
{
int ret = 0;
switch (state)
{
case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
/* FIXME: Add suspend */
ret = omap2_pm_suspend();
break;
case PM_SUSPEND_DISK:
return -ENOTSUPP;
ret = -ENOTSUPP;
break;
default:
return -EINVAL;
ret = -EINVAL;
}
return 0;
return ret;
}
static int omap2_pm_finish(suspend_state_t state)
@@ -143,6 +400,8 @@ int __init omap2_pm_init(void)
pm_set_ops(&omap_pm_ops);
pm_idle = omap2_pm_idle;
pmdomain_init();
return 0;
}

Some files were not shown because too many files have changed in this diff Show More