diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-apollon.c | 285 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-h4.c | 174 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 79 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 37 | ||||
-rw-r--r-- | arch/arm/mach-omap2/devices.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-omap2/io.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/memory.c | 102 | ||||
-rw-r--r-- | arch/arm/mach-omap2/memory.h | 34 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 149 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prcm-regs.h (renamed from arch/arm/mach-omap2/prcm.h) | 188 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prcm.c | 40 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sleep.S | 144 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sram-fn.S | 4 |
16 files changed, 1198 insertions, 159 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 578880943cf..537dd2e6d38 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -20,3 +20,6 @@ config MACH_OMAP_H4 bool "OMAP 2420 H4 board" depends on ARCH_OMAP2 && ARCH_OMAP24XX +config MACH_OMAP_APOLLON + bool "OMAP 2420 Apollon board" + depends on ARCH_OMAP2 && ARCH_OMAP24XX diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 42041166435..111eaa64258 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -3,11 +3,15 @@ # # Common support -obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o +obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o + # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o +obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c new file mode 100644 index 00000000000..6c6ba172cdf --- /dev/null +++ b/arch/arm/mach-omap2/board-apollon.c @@ -0,0 +1,285 @@ +/* + * linux/arch/arm/mach-omap/omap2/board-apollon.c + * + * Copyright (C) 2005,2006 Samsung Electronics + * Author: Kyungmin Park <kyungmin.park@samsung.com> + * + * Modified from mach-omap/omap2/board-h4.c + * + * Code for apollon OMAP2 board. Should work on many OMAP2 systems where + * the bootloader passes the board-specific data to the kernel. + * Do not put any board specific code to this file; create a new machine + * type if you need custom low-level initializations. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/onenand.h> +#include <linux/interrupt.h> +#include <linux/delay.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> +#include <asm/arch/board.h> +#include <asm/arch/common.h> +#include "prcm-regs.h" + +/* LED & Switch macros */ +#define LED0_GPIO13 13 +#define LED1_GPIO14 14 +#define LED2_GPIO15 15 +#define SW_ENTER_GPIO16 16 +#define SW_UP_GPIO17 17 +#define SW_DOWN_GPIO58 58 + +static struct mtd_partition apollon_partitions[] = { + { + .name = "X-Loader + U-Boot", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = SZ_16M, + }, + { + .name = "filesystem00", + .offset = MTDPART_OFS_APPEND, + .size = SZ_32M, + }, + { + .name = "filesystem01", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data apollon_flash_data = { + .parts = apollon_partitions, + .nr_parts = ARRAY_SIZE(apollon_partitions), +}; + +static struct resource apollon_flash_resource = { + .start = APOLLON_CS0_BASE, + .end = APOLLON_CS0_BASE + SZ_128K, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device apollon_onenand_device = { + .name = "onenand", + .id = -1, + .dev = { + .platform_data = &apollon_flash_data, + }, + .num_resources = ARRAY_SIZE(&apollon_flash_resource), + .resource = &apollon_flash_resource, +}; + +static struct resource apollon_smc91x_resources[] = { + [0] = { + .start = APOLLON_ETHR_START, /* Physical */ + .end = APOLLON_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), + .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device apollon_smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(apollon_smc91x_resources), + .resource = apollon_smc91x_resources, +}; + +static struct platform_device apollon_lcd_device = { + .name = "apollon_lcd", + .id = -1, +}; + +static struct platform_device *apollon_devices[] __initdata = { + &apollon_onenand_device, + &apollon_smc91x_device, + &apollon_lcd_device, +}; + +static inline void __init apollon_init_smc91x(void) +{ + /* Make sure CS1 timings are correct */ + GPMC_CONFIG1_1 = 0x00011203; + GPMC_CONFIG2_1 = 0x001f1f01; + GPMC_CONFIG3_1 = 0x00080803; + GPMC_CONFIG4_1 = 0x1c091c09; + GPMC_CONFIG5_1 = 0x041f1f1f; + GPMC_CONFIG6_1 = 0x000004c4; + GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); + udelay(100); + + omap_cfg_reg(W4__24XX_GPIO74); + if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", + APOLLON_ETHR_GPIO_IRQ); + return; + } + omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); +} + +static void __init omap_apollon_init_irq(void) +{ + omap2_init_common_hw(); + omap_init_irq(); + omap_gpio_init(); + apollon_init_smc91x(); +} + +static struct omap_uart_config apollon_uart_config __initdata = { + .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), +}; + +static struct omap_mmc_config apollon_mmc_config __initdata = { + .mmc [0] = { + .enabled = 0, + .wire4 = 0, + .wp_pin = -1, + .power_pin = -1, + .switch_pin = -1, + }, +}; + +static struct omap_lcd_config apollon_lcd_config __initdata = { + .ctrl_name = "internal", +}; + +static struct omap_board_config_kernel apollon_config[] = { + { OMAP_TAG_UART, &apollon_uart_config }, + { OMAP_TAG_MMC, &apollon_mmc_config }, + { OMAP_TAG_LCD, &apollon_lcd_config }, +}; + +static void __init apollon_led_init(void) +{ + /* LED0 - AA10 */ + omap_cfg_reg(AA10_242X_GPIO13); + omap_request_gpio(LED0_GPIO13); + omap_set_gpio_direction(LED0_GPIO13, 0); + omap_set_gpio_dataout(LED0_GPIO13, 0); + /* LED1 - AA6 */ + omap_cfg_reg(AA6_242X_GPIO14); + omap_request_gpio(LED1_GPIO14); + omap_set_gpio_direction(LED1_GPIO14, 0); + omap_set_gpio_dataout(LED1_GPIO14, 0); + /* LED2 - AA4 */ + omap_cfg_reg(AA4_242X_GPIO15); + omap_request_gpio(LED2_GPIO15); + omap_set_gpio_direction(LED2_GPIO15, 0); + omap_set_gpio_dataout(LED2_GPIO15, 0); +} + +static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs) +{ + static unsigned int led0, led1, led2; + + if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16)) + omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1); + else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17)) + omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1); + else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58)) + omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1); + + return IRQ_HANDLED; +} + +static void __init apollon_sw_init(void) +{ + /* Enter SW - Y11 */ + omap_cfg_reg(Y11_242X_GPIO16); + omap_request_gpio(SW_ENTER_GPIO16); + omap_set_gpio_direction(SW_ENTER_GPIO16, 1); + /* Up SW - AA12 */ + omap_cfg_reg(AA12_242X_GPIO17); + omap_request_gpio(SW_UP_GPIO17); + omap_set_gpio_direction(SW_UP_GPIO17, 1); + /* Down SW - AA8 */ + omap_cfg_reg(AA8_242X_GPIO58); + omap_request_gpio(SW_DOWN_GPIO58); + omap_set_gpio_direction(SW_DOWN_GPIO58, 1); + + set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING); + if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, + SA_SHIRQ, "enter sw", + &apollon_sw_interrupt)) + return; + set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING); + if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, + SA_SHIRQ, "up sw", + &apollon_sw_interrupt)) + return; + set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING); + if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, + SA_SHIRQ, "down sw", + &apollon_sw_interrupt)) + return; +} + +static void __init omap_apollon_init(void) +{ + apollon_led_init(); + apollon_sw_init(); + + /* REVISIT: where's the correct place */ + omap_cfg_reg(W19_24XX_SYS_NIRQ); + + /* + * Make sure the serial ports are muxed on at this point. + * You have to mux them off in device drivers later on + * if not needed. + */ + platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); + omap_board_config = apollon_config; + omap_board_config_size = ARRAY_SIZE(apollon_config); + omap_serial_init(); +} + +static void __init omap_apollon_map_io(void) +{ + omap2_map_common_io(); +} + +MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") + /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ + .phys_io = 0x48000000, + .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = omap_apollon_map_io, + .init_irq = omap_apollon_init_irq, + .init_machine = omap_apollon_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index a300d634d8a..4933fce766c 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -17,6 +17,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/delay.h> +#include <linux/workqueue.h> +#include <linux/input.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -25,15 +27,57 @@ #include <asm/mach/flash.h> #include <asm/arch/gpio.h> +#include <asm/arch/gpioexpander.h> #include <asm/arch/mux.h> #include <asm/arch/usb.h> +#include <asm/arch/irda.h> #include <asm/arch/board.h> #include <asm/arch/common.h> -#include <asm/arch/prcm.h> +#include <asm/arch/keypad.h> +#include <asm/arch/menelaus.h> +#include <asm/arch/dma.h> +#include "prcm-regs.h" #include <asm/io.h> #include <asm/delay.h> +static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; +static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; + +static int h4_keymap[] = { + KEY(0, 0, KEY_LEFT), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_A), + KEY(0, 3, KEY_B), + KEY(0, 4, KEY_C), + KEY(1, 0, KEY_DOWN), + KEY(1, 1, KEY_UP), + KEY(1, 2, KEY_E), + KEY(1, 3, KEY_F), + KEY(1, 4, KEY_G), + KEY(2, 0, KEY_ENTER), + KEY(2, 1, KEY_I), + KEY(2, 2, KEY_J), + KEY(2, 3, KEY_K), + KEY(2, 4, KEY_3), + KEY(3, 0, KEY_M), + KEY(3, 1, KEY_N), + KEY(3, 2, KEY_O), + KEY(3, 3, KEY_P), + KEY(3, 4, KEY_Q), + KEY(4, 0, KEY_R), + KEY(4, 1, KEY_4), + KEY(4, 2, KEY_T), + KEY(4, 3, KEY_U), + KEY(4, 4, KEY_ENTER), + KEY(5, 0, KEY_V), + KEY(5, 1, KEY_W), + KEY(5, 2, KEY_L), + KEY(5, 3, KEY_S), + KEY(5, 4, KEY_ENTER), + 0 +}; + static struct mtd_partition h4_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -108,9 +152,123 @@ static struct platform_device h4_smc91x_device = { .resource = h4_smc91x_resources, }; +/* Select between the IrDA and aGPS module + */ +static int h4_select_irda(struct device *dev, int state) +{ + unsigned char expa; + int err = 0; + + if ((err = read_gpio_expa(&expa, 0x21))) { + printk(KERN_ERR "Error reading from I/O expander\n"); + return err; + } + + /* 'P6' enable/disable IRDA_TX and IRDA_RX */ + if (state & IR_SEL) { /* IrDa */ + if ((err = write_gpio_expa(expa | 0x01, 0x21))) { + printk(KERN_ERR "Error writing to I/O expander\n"); + return err; + } + } else { + if ((err = write_gpio_expa(expa & ~0x01, 0x21))) { + printk(KERN_ERR "Error writing to I/O expander\n"); + return err; + } + } + return err; +} + +static void set_trans_mode(void *data) +{ + int *mode = data; + unsigned char expa; + int err = 0; + + if ((err = read_gpio_expa(&expa, 0x20)) != 0) { + printk(KERN_ERR "Error reading from I/O expander\n"); + } + + expa &= ~0x01; + + if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */ + expa |= 0x01; + } + + if ((err = write_gpio_expa(expa, 0x20)) != 0) { + printk(KERN_ERR "Error writing to I/O expander\n"); + } +} + +static int h4_transceiver_mode(struct device *dev, int mode) +{ + struct omap_irda_config *irda_config = dev->platform_data; + + cancel_delayed_work(&irda_config->gpio_expa); + PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); + schedule_work(&irda_config->gpio_expa); + + return 0; +} + +static struct omap_irda_config h4_irda_data = { + .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, + .transceiver_mode = h4_transceiver_mode, + .select_irda = h4_select_irda, + .rx_channel = OMAP24XX_DMA_UART3_RX, + .tx_channel = OMAP24XX_DMA_UART3_TX, + .dest_start = OMAP_UART3_BASE, + .src_start = OMAP_UART3_BASE, + .tx_trigger = OMAP24XX_DMA_UART3_TX, + .rx_trigger = OMAP24XX_DMA_UART3_RX, +}; + +static struct resource h4_irda_resources[] = { + [0] = { + .start = INT_24XX_UART3_IRQ, + .end = INT_24XX_UART3_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device h4_irda_device = { + .name = "omapirda", + .id = -1, + .dev = { + .platform_data = &h4_irda_data, + }, + .num_resources = 1, + .resource = h4_irda_resources, +}; + +static struct omap_kp_platform_data h4_kp_data = { + .rows = 6, + .cols = 7, + .keymap = h4_keymap, + .rep = 1, + .row_gpios = row_gpios, + .col_gpios = col_gpios, +}; + +static struct platform_device h4_kp_device = { + .name = "omap-keypad", + .id = -1, + .dev = { + .platform_data = &h4_kp_data, + }, +}; + +static struct platform_device h4_lcd_device = { + .name = "lcd_h4", + .id = -1, +}; + static struct platform_device *h4_devices[] __initdata = { &h4_smc91x_device, &h4_flash_device, + &h4_irda_device, + &h4_kp_device, + &h4_lcd_device, }; static inline void __init h4_init_smc91x(void) @@ -157,7 +315,6 @@ static struct omap_mmc_config h4_mmc_config __initdata = { }; static struct omap_lcd_config h4_lcd_config __initdata = { - .panel_name = "h4", .ctrl_name = "internal", }; @@ -174,6 +331,19 @@ static void __init omap_h4_init(void) * You have to mux them off in device drivers later on * if not needed. */ +#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) + omap_cfg_reg(K15_24XX_UART3_TX); + omap_cfg_reg(K14_24XX_UART3_RX); +#endif + +#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) + if (omap_has_menelaus()) { + row_gpios[5] = 0; + col_gpios[2] = 15; + col_gpios[6] = 18; + } +#endif + platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); omap_board_config = h4_config; omap_board_config_size = ARRAY_SIZE(h4_config); diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 180f675c906..72eb4bf571a 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -28,14 +28,14 @@ #include <asm/arch/clock.h> #include <asm/arch/sram.h> -#include <asm/arch/prcm.h> +#include "prcm-regs.h" +#include "memory.h" #include "clock.h" //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ static struct prcm_config *curr_prcm_set; -static struct memory_timings mem_timings; static u32 curr_perf_level = PRCM_FULL_SPEED; /*------------------------------------------------------------------------- @@ -54,11 +54,13 @@ static void omap2_sys_clk_recalc(struct clk * clk) static u32 omap2_get_dpll_rate(struct clk * tclk) { - int dpll_clk, dpll_mult, dpll_div, amult; + long long dpll_clk; + int dpll_mult, dpll_div, amult; dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ - dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1); + dpll_clk = (long long)tclk->parent->rate * dpll_mult; + do_div(dpll_clk, dpll_div + 1); amult = CM_CLKSEL2_PLL & 0x3; dpll_clk *= amult; @@ -385,75 +387,23 @@ static u32 omap2_dll_force_needed(void) return 0; } -static void omap2_init_memory_params(u32 force_lock_to_unlock_mode) -{ - unsigned long dll_cnt; - u32 fast_dll = 0; - - mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ - - /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. - * In the case of 2422, its ok to use CS1 instead of CS0. - */ - -#if 0 /* FIXME: Enable after 24xx cpu detection works */ - ctype = get_cpu_type(); - if (cpu_is_omap2422()) - mem_timings.base_cs = 1; - else -#endif - mem_timings.base_cs = 0; - - if (mem_timings.m_type != M_DDR) - return; - - /* With DDR we need to determine the low frequency DLL value */ - if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) - mem_timings.dll_mode = M_UNLOCK; - else - mem_timings.dll_mode = M_LOCK; - - if (mem_timings.base_cs == 0) { - fast_dll = SDRC_DLLA_CTRL; - dll_cnt = SDRC_DLLA_STATUS & 0xff00; - } else { - fast_dll = SDRC_DLLB_CTRL; - dll_cnt = SDRC_DLLB_STATUS & 0xff00; - } - if (force_lock_to_unlock_mode) { - fast_dll &= ~0xff00; - fast_dll |= dll_cnt; /* Current lock mode */ - } - mem_timings.fast_dll_ctrl = fast_dll; - - /* No disruptions, DDR will be offline & C-ABI not followed */ - omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, - mem_timings.fast_dll_ctrl, - mem_timings.base_cs, - force_lock_to_unlock_mode); - mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ - - /* Turn status into unlock ctrl */ - mem_timings.slow_dll_ctrl |= - ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); - - /* 90 degree phase for anything below 133Mhz */ - mem_timings.slow_dll_ctrl |= (1 << 1); -} - static u32 omap2_reprogram_sdrc(u32 level, u32 force) { + u32 slow_dll_ctrl, fast_dll_ctrl, m_type; u32 prev = curr_perf_level, flags; if ((curr_perf_level == level) && !force) return prev; + m_type = omap2_memory_get_type(); + slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl(); + fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl(); + if (level == PRCM_HALF_SPEED) { local_irq_save(flags); PRCM_VOLTSETUP = 0xffff; omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, - mem_timings.slow_dll_ctrl, - mem_timings.m_type); + slow_dll_ctrl, m_type); curr_perf_level = PRCM_HALF_SPEED; local_irq_restore(flags); } @@ -461,8 +411,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force) local_irq_save(flags); PRCM_VOLTSETUP = 0xffff; omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, - mem_timings.fast_dll_ctrl, - mem_timings.m_type); + fast_dll_ctrl, m_type); curr_perf_level = PRCM_FULL_SPEED; local_irq_restore(flags); } @@ -650,7 +599,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask, case 13: /* dss2 */ mask = 0x1; break; case 25: /* usb */ - mask = 0xf; break; + mask = 0x7; break; } } diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 6cab20b1d3c..6c78d471fab 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -33,20 +33,6 @@ static u32 omap2_clksel_get_divisor(struct clk *clk); #define RATE_IN_242X (1 << 0) #define RATE_IN_243X (1 << 1) -/* Memory timings */ -#define M_DDR 1 -#define M_LOCK_CTRL (1 << 2) -#define M_UNLOCK 0 -#define M_LOCK 1 - -struct memory_timings { - u32 m_type; /* ddr = 1, sdr = 0 */ - u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ - u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ - u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ - u32 base_cs; /* base chip select to use for calculations */ -}; - /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM @@ -731,6 +717,16 @@ static struct clk sys_clkout2 = { .recalc = &omap2_clksel_recalc, }; +static struct clk emul_ck = { + .name = "emul_ck", + .parent = &func_54m_ck, + .flags = CLOCK_IN_OMAP242X, + .enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL, + .enable_bit = 0, + .recalc = &omap2_propagate_rate, + +}; + /* * MPU clock domain * Clocks: @@ -1702,7 +1698,8 @@ static struct clk hdq_fck = { }; static struct clk i2c2_ick = { - .name = "i2c2_ick", + .name = "i2c_ick", + .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1711,7 +1708,8 @@ static struct clk i2c2_ick = { }; static struct clk i2c2_fck = { - .name = "i2c2_fck", + .name = "i2c_fck", + .id = 2, .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1729,7 +1727,8 @@ static struct clk i2chs2_fck = { }; static struct clk i2c1_ick = { - .name = "i2c1_ick", + .name = "i2c_ick", + .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1738,7 +1737,8 @@ static struct clk i2c1_ick = { }; static struct clk i2c1_fck = { - .name = "i2c1_fck", + .name = "i2c_fck", + .id = 1, .parent = &func_12m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1971,6 +1971,7 @@ static struct clk *onchip_clks[] = { &wdt1_osc_ck, &sys_clkout, &sys_clkout2, + &emul_ck, /* mpu domain clocks */ &mpu_ck, /* dsp domain clocks */ diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 7181edb8935..fb7f91da1aa 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -25,10 +25,6 @@ #include <asm/arch/mux.h> #include <asm/arch/gpio.h> -extern void omap_nop_release(struct device *dev); - -/*-------------------------------------------------------------------------*/ - #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) #define OMAP2_I2C_BASE2 0x48072000 @@ -49,9 +45,6 @@ static struct resource i2c_resources2[] = { static struct platform_device omap_i2c_device2 = { .name = "i2c_omap", .id = 2, - .dev = { - .release = omap_nop_release, - }, .num_resources = ARRAY_SIZE(i2c_resources2), .resource = i2c_resources2, }; @@ -74,6 +67,44 @@ static void omap_init_i2c(void) {} #endif +#if defined(CONFIG_OMAP_STI) + +#define OMAP2_STI_BASE IO_ADDRESS(0x48068000) +#define OMAP2_STI_CHANNEL_BASE 0x54000000 +#define OMAP2_STI_IRQ 4 + +static struct resource sti_resources[] = { + { + .start = OMAP2_STI_BASE, + .end = OMAP2_STI_BASE + 0x7ff, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP2_STI_CHANNEL_BASE, + .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP2_STI_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device sti_device = { + .name = "sti", + .id = -1, + .num_resources = ARRAY_SIZE(sti_resources), + .resource = sti_resources, +}; + +static inline void omap_init_sti(void) +{ + platform_device_register(&sti_device); +} +#else +static inline void omap_init_sti(void) {} +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -82,6 +113,7 @@ static int __init omap2_init_devices(void) * in alphabetical order so they're easier to sort through. */ omap_init_i2c(); + omap_init_sti(); return 0; } diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 8ea67bf196a..7d5711611f2 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -16,9 +16,13 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <asm/mach/map.h> +#include <asm/tlb.h> #include <asm/io.h> + +#include <asm/mach/map.h> + #include <asm/arch/mux.h> +#include <asm/arch/omapfb.h> extern void omap_sram_init(void); extern int omap2_clk_init(void); @@ -43,11 +47,24 @@ static struct map_desc omap2_io_desc[] __initdata = { } }; -void __init omap_map_common_io(void) +void __init omap2_map_common_io(void) { iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); + + /* Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but we must also do it here because of the CPU + * revision check below. + */ + local_flush_tlb_all(); + flush_cache_all(); + omap2_check_revision(); omap_sram_init(); + omapfb_reserve_mem(); +} + +void __init omap2_init_common_hw(void) +{ omap2_mux_init(); omap2_clk_init(); } diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c new file mode 100644 index 00000000000..1d925d69fc3 --- /dev/null +++ b/arch/arm/mach-omap2/memory.c @@ -0,0 +1,102 @@ +/* + * linux/arch/arm/mach-omap2/memory.c + * + * Memory timing related functions for OMAP24XX + * + * Copyright (C) 2005 Texas Instruments Inc. + * Richard Woodruff <r-woodruff2@ti.com> + * + * Copyright (C) 2005 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/clk.h> + +#include <asm/io.h> + +#include <asm/arch/clock.h> +#include <asm/arch/sram.h> + +#include "prcm-regs.h" +#include "memory.h" + +static struct memory_timings mem_timings; + +u32 omap2_memory_get_slow_dll_ctrl(void) +{ + return mem_timings.slow_dll_ctrl; +} + +u32 omap2_memory_get_fast_dll_ctrl(void) +{ + return mem_timings.fast_dll_ctrl; +} + +u32 omap2_memory_get_type(void) +{ + return mem_timings.m_type; +} + +void omap2_init_memory_params(u32 force_lock_to_unlock_mode) +{ + unsigned long dll_cnt; + u32 fast_dll = 0; + + mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ + + /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. + * In the case of 2422, its ok to use CS1 instead of CS0. + */ + if (cpu_is_omap2422()) + mem_timings.base_cs = 1; + else + mem_timings.base_cs = 0; + + if (mem_timings.m_type != M_DDR) + return; + + /* With DDR we need to determine the low frequency DLL value */ + if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) + mem_timings.dll_mode = M_UNLOCK; + else + mem_timings.dll_mode = M_LOCK; + + if (mem_timings.base_cs == 0) { + fast_dll = SDRC_DLLA_CTRL; + dll_cnt = SDRC_DLLA_STATUS & 0xff00; + } else { + fast_dll = SDRC_DLLB_CTRL; + dll_cnt = SDRC_DLLB_STATUS & 0xff00; + } + if (force_lock_to_unlock_mode) { + fast_dll &= ~0xff00; + fast_dll |= dll_cnt; /* Current lock mode */ + } + /* set fast timings with DLL filter disabled */ + mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8)); + + /* No disruptions, DDR will be offline & C-ABI not followed */ + omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, + mem_timings.fast_dll_ctrl, + mem_timings.base_cs, + force_lock_to_unlock_mode); + mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ + + /* Turn status into unlock ctrl */ + mem_timings.slow_dll_ctrl |= + ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); + + /* 90 degree phase for anything below 133Mhz + disable DLL filter */ + mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); +} diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h new file mode 100644 index 00000000000..d212eea83a0 --- /dev/null +++ b/arch/arm/mach-omap2/memory.h @@ -0,0 +1,34 @@ +/* + * linux/arch/arm/mach-omap2/memory.h + * + * Interface for memory timing related functions for OMAP24XX + * + * Copyright (C) 2005 Texas Instruments Inc. + * Richard Woodruff <r-woodruff2@ti.com> + * + * Copyright (C) 2005 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Memory timings */ +#define M_DDR 1 +#define M_LOCK_CTRL (1 << 2) +#define M_UNLOCK 0 +#define M_LOCK 1 + +struct memory_timings { + u32 m_type; /* ddr = 1, sdr = 0 */ + u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ + u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ + u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ + u32 base_cs; /* base chip select to use for calculations */ +}; + +extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode); +extern u32 omap2_memory_get_slow_dll_ctrl(void); +extern u32 omap2_memory_get_fast_dll_ctrl(void); +extern u32 omap2_memory_get_type(void); |