diff options
Diffstat (limited to 'arch/arm/mach-omap1')
-rw-r--r-- | arch/arm/mach-omap1/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-fsample.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-h2.c | 59 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-h3.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-htcherald.c | 64 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-innovator.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-nokia770.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-osk.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-perseus2.c | 58 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-voiceblue.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap1/clock.c | 501 | ||||
-rw-r--r-- | arch/arm/mach-omap1/clock.h | 652 | ||||
-rw-r--r-- | arch/arm/mach-omap1/clock_data.c | 847 | ||||
-rw-r--r-- | arch/arm/mach-omap1/devices.c | 35 | ||||
-rw-r--r-- | arch/arm/mach-omap1/i2c.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-omap1/include/mach/lcd_dma.h | 78 | ||||
-rw-r--r-- | arch/arm/mach-omap1/include/mach/lcdc.h | 57 | ||||
-rw-r--r-- | arch/arm/mach-omap1/io.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap1/lcd_dma.c | 448 | ||||
-rw-r--r-- | arch/arm/mach-omap1/mux.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-omap1/opp.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap1/opp_data.c | 59 |
22 files changed, 2055 insertions, 1059 deletions
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 87e539aa8ad9..9ce17f13d3f1 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -3,7 +3,8 @@ # # Common support -obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o +obj-y := io.o id.o sram.o irq.o mux.o serial.o devices.o +obj-y += clock.o clock_data.o opp_data.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o @@ -17,6 +18,9 @@ obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o mailbox_mach-objs := mailbox.o +i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o +obj-y += $(i2c-omap-m) $(i2c-omap-y) + led-y := leds.o # Specific board support @@ -48,3 +52,7 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o obj-$(CONFIG_LEDS) += $(led-y) + +ifneq ($(CONFIG_FB_OMAP),) +obj-y += lcd_dma.o +endif diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index f4b72c1654f5..7e70c3c08da6 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -19,6 +19,7 @@ #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/input.h> +#include <linux/smc91x.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -30,7 +31,6 @@ #include <mach/gpio.h> #include <plat/mux.h> #include <plat/fpga.h> -#include <plat/nand.h> #include <plat/keypad.h> #include <plat/common.h> #include <plat/board.h> @@ -100,6 +100,12 @@ static int fsample_keymap[] = { 0 }; +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { [0] = { .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ @@ -167,8 +173,40 @@ static struct platform_device nor_device = { .resource = &nor_resource, }; -static struct omap_nand_platform_data nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, +static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long mask; + + if (cmd == NAND_CMD_NONE) + return; + + mask = (ctrl & NAND_CLE) ? 0x02 : 0; + if (ctrl & NAND_ALE) + mask |= 0x04; + writeb(cmd, (unsigned long)this->IO_ADDR_W | mask); +} + +#define FSAMPLE_NAND_RB_GPIO_PIN 62 + +static int nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN); +} + +static const char *part_probes[] = { "cmdlinepart", NULL }; + +static struct platform_nand_data nand_data = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .options = NAND_SAMSUNG_LP_OPTIONS, + .part_probe_types = part_probes, + }, + .ctrl = { + .cmd_ctrl = nand_cmd_ctl, + .dev_ready = nand_dev_ready, + }, }; static struct resource nand_resource = { @@ -178,7 +216,7 @@ static struct resource nand_resource = { }; static struct platform_device nand_device = { - .name = "omapnand", + .name = "gen_nand", .id = 0, .dev = { .platform_data = &nand_data, @@ -190,6 +228,9 @@ static struct platform_device nand_device = { static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &smc91x_info, + }, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; @@ -233,13 +274,6 @@ static struct platform_device *devices[] __initdata = { &lcd_device, }; -#define P2_NAND_RB_GPIO_PIN 62 - -static int nand_dev_ready(struct omap_nand_platform_data *data) -{ - return gpio_get_value(P2_NAND_RB_GPIO_PIN); -} - static struct omap_lcd_config fsample_lcd_config __initdata = { .ctrl_name = "internal", }; @@ -250,9 +284,9 @@ static struct omap_board_config_kernel fsample_config[] = { static void __init omap_fsample_init(void) { - if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0) + if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0) BUG(); - nand_data.dev_ready = nand_dev_ready; + gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN); omap_cfg_reg(L3_1610_FLASH_CS2B_OE); omap_cfg_reg(M8_1610_FLASH_CS2B_WE); diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 89ba8ec4bbf4..fa7cecea19f9 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -28,6 +28,7 @@ #include <linux/mtd/partitions.h> #include <linux/input.h> #include <linux/i2c/tps65010.h> +#include <linux/smc91x.h> #include <mach/hardware.h> #include <asm/gpio.h> @@ -40,7 +41,6 @@ #include <plat/mux.h> #include <plat/dma.h> #include <plat/tc.h> -#include <plat/nand.h> #include <plat/irda.h> #include <plat/usb.h> #include <plat/keypad.h> @@ -179,11 +179,43 @@ static struct mtd_partition h2_nand_partitions[] = { }, }; -/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */ -static struct omap_nand_platform_data h2_nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, - .parts = h2_nand_partitions, - .nr_parts = ARRAY_SIZE(h2_nand_partitions), +static void h2_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long mask; + + if (cmd == NAND_CMD_NONE) + return; + + mask = (ctrl & NAND_CLE) ? 0x02 : 0; + if (ctrl & NAND_ALE) + mask |= 0x04; + writeb(cmd, (unsigned long)this->IO_ADDR_W | mask); +} + +#define H2_NAND_RB_GPIO_PIN 62 + +static int h2_nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(H2_NAND_RB_GPIO_PIN); +} + +static const char *h2_part_probes[] = { "cmdlinepart", NULL }; + +struct platform_nand_data h2_nand_platdata = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .nr_partitions = ARRAY_SIZE(h2_nand_partitions), + .partitions = h2_nand_partitions, + .options = NAND_SAMSUNG_LP_OPTIONS, + .part_probe_types = h2_part_probes, + }, + .ctrl = { + .cmd_ctrl = h2_nand_cmd_ctl, + .dev_ready = h2_nand_dev_ready, + + }, }; static struct resource h2_nand_resource = { @@ -191,15 +223,21 @@ static struct resource h2_nand_resource = { }; static struct platform_device h2_nand_device = { - .name = "omapnand", + .name = "gen_nand", .id = 0, .dev = { - .platform_data = &h2_nand_data, + .platform_data = &h2_nand_platdata, }, .num_resources = 1, .resource = &h2_nand_resource, }; +static struct smc91x_platdata h2_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource h2_smc91x_resources[] = { [0] = { .start = OMAP1610_ETHR_START, /* Physical */ @@ -216,6 +254,9 @@ static struct resource h2_smc91x_resources[] = { static struct platform_device h2_smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &h2_smc91x_info, + }, .num_resources = ARRAY_SIZE(h2_smc91x_resources), .resource = h2_smc91x_resources, }; @@ -368,8 +409,6 @@ static struct omap_board_config_kernel h2_config[] __initdata = { { OMAP_TAG_LCD, &h2_lcd_config }, }; -#define H2_NAND_RB_GPIO_PIN 62 - static void __init h2_init(void) { /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index f5cc0a730524..6a7f9c391cf1 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -28,6 +28,7 @@ #include <linux/input.h> #include <linux/spi/spi.h> #include <linux/i2c/tps65010.h> +#include <linux/smc91x.h> #include <asm/setup.h> #include <asm/page.h> @@ -42,7 +43,6 @@ #include <mach/irqs.h> #include <plat/mux.h> #include <plat/tc.h> -#include <plat/nand.h> #include <plat/usb.h> #include <plat/keypad.h> #include <plat/dma.h> @@ -181,11 +181,43 @@ static struct mtd_partition nand_partitions[] = { }, }; -/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */ -static struct omap_nand_platform_data nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, - .parts = nand_partitions, - .nr_parts = ARRAY_SIZE(nand_partitions), +static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long mask; + + if (cmd == NAND_CMD_NONE) + return; + + mask = (ctrl & NAND_CLE) ? 0x02 : 0; + if (ctrl & NAND_ALE) + mask |= 0x04; + writeb(cmd, (unsigned long)this->IO_ADDR_W | mask); +} + +#define H3_NAND_RB_GPIO_PIN 10 + +static int nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(H3_NAND_RB_GPIO_PIN); +} + +static const char *part_probes[] = { "cmdlinepart", NULL }; + +struct platform_nand_data nand_platdata = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .nr_partitions = ARRAY_SIZE(nand_partitions), + .partitions = nand_partitions, + .options = NAND_SAMSUNG_LP_OPTIONS, + .part_probe_types = part_probes, + }, + .ctrl = { + .cmd_ctrl = nand_cmd_ctl, + .dev_ready = nand_dev_ready, + + }, }; static struct resource nand_resource = { @@ -193,15 +225,21 @@ static struct resource nand_resource = { }; static struct platform_device nand_device = { - .name = "omapnand", + .name = "gen_nand", .id = 0, .dev = { - .platform_data = &nand_data, + .platform_data = &nand_platdata, }, .num_resources = 1, .resource = &nand_resource, }; +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { [0] = { .start = OMAP1710_ETHR_START, /* Physical */ @@ -218,6 +256,9 @@ static struct resource smc91x_resources[] = { static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &smc91x_info, + }, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; @@ -332,13 +373,6 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { }, }; -#define H3_NAND_RB_GPIO_PIN 10 - -static int nand_dev_ready(struct omap_nand_platform_data *data) -{ - return gpio_get_value(H3_NAND_RB_GPIO_PIN); -} - static void __init h3_init(void) { /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped @@ -356,7 +390,7 @@ static void __init h3_init(void) nand_resource.end += SZ_4K - 1; if (gpio_request(H3_NAND_RB_GPIO_PIN, "NAND ready") < 0) BUG(); - nand_data.dev_ready = nand_dev_ready; + gpio_direction_input(H3_NAND_RB_GPIO_PIN); /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */ /* GPIO10 pullup/down register, Enable pullup on GPIO10 */ diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 5f28a5ceacac..e36639f66150 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -39,6 +39,7 @@ #include <plat/common.h> #include <plat/board.h> #include <plat/keypad.h> +#include <plat/usb.h> #include <mach/irqs.h> @@ -140,6 +141,15 @@ static struct platform_device kp_device = { .resource = kp_resources, }; +/* USB Device */ +static struct omap_usb_config htcherald_usb_config __initdata = { + .otg = 0, + .register_host = 0, + .register_dev = 1, + .hmc_mode = 4, + .pins[0] = 2, +}; + /* LCD Device resources */ static struct platform_device lcd_device = { .name = "lcd_htcherald", @@ -214,6 +224,57 @@ static void __init htcherald_disable_watchdog(void) } } +#define HTCHERALD_GPIO_USB_EN1 33 +#define HTCHERALD_GPIO_USB_EN2 73 +#define HTCHERALD_GPIO_USB_DM 35 +#define HTCHERALD_GPIO_USB_DP 36 + +static void __init htcherald_usb_enable(void) +{ + unsigned int tries = 20; + unsigned int value = 0; + + /* Request the GPIOs we need to control here */ + if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0) + goto err1; + + if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0) + goto err2; + + if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0) + goto err3; + + if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0) + goto err4; + + /* force USB_EN GPIO to 0 */ + do { + /* output low */ + gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0); + } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 && + --tries); + + if (value == 1) + printk(KERN_WARNING "Unable to reset USB, trying to continue\n"); + + gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */ + gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */ + gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */ + + goto done; + +err4: + gpio_free(HTCHERALD_GPIO_USB_DM); +err3: + gpio_free(HTCHERALD_GPIO_USB_EN2); +err2: + gpio_free(HTCHERALD_GPIO_USB_EN1); +err1: + printk(KERN_ERR "Unabled to request GPIO for USB\n"); +done: + printk(KERN_INFO "USB setup complete.\n"); +} + static void __init htcherald_init(void) { printk(KERN_INFO "HTC Herald init.\n"); @@ -225,6 +286,9 @@ static void __init htcherald_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); htcherald_disable_watchdog(); + + htcherald_usb_enable(); + omap_usb_init(&htcherald_usb_config); } static void __init htcherald_init_irq(void) diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index cf0fdb9c182f..2133b006f6a3 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -23,6 +23,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/input.h> +#include <linux/smc91x.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -142,6 +143,11 @@ static struct platform_device innovator_kp_device = { .resource = innovator_kp_resources, }; +static struct smc91x_platdata innovator_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; #ifdef CONFIG_ARCH_OMAP15XX @@ -175,6 +181,9 @@ static struct resource innovator1510_smc91x_resources[] = { static struct platform_device innovator1510_smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &innovator_smc91x_info, + }, .num_resources = ARRAY_SIZE(innovator1510_smc91x_resources), .resource = innovator1510_smc91x_resources, }; @@ -241,6 +250,9 @@ static struct resource innovator1610_smc91x_resources[] = { static struct platform_device innovator1610_smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &innovator_smc91x_info, + }, .num_resources = ARRAY_SIZE(innovator1610_smc91x_resources), .resource = innovator1610_smc91x_resources, }; diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 5a275bab2dfe..71e1a3fad0ea 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/input.h> #include <linux/clk.h> +#include <linux/omapfb.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> @@ -32,7 +33,6 @@ #include <plat/keypad.h> #include <plat/common.h> #include <plat/dsp_common.h> -#include <plat/omapfb.h> #include <plat/hwa742.h> #include <plat/lcd_mipid.h> #include <plat/mmc.h> diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 50c92c13e48a..ccea4f448e9a 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -33,6 +33,7 @@ #include <linux/irq.h> #include <linux/i2c.h> #include <linux/leds.h> +#include <linux/smc91x.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -115,6 +116,12 @@ static struct platform_device osk5912_flash_device = { .resource = &osk_flash_resource, }; +static struct smc91x_platdata osk5912_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource osk5912_smc91x_resources[] = { [0] = { .start = OMAP_OSK_ETHR_START, /* Physical */ @@ -131,6 +138,9 @@ static struct resource osk5912_smc91x_resources[] = { static struct platform_device osk5912_smc91x_device = { .name = "smc91x", .id = -1, + .dev = { + .platform_data = &osk5912_smc91x_info, + }, .num_resources = ARRAY_SIZE(osk5912_smc91x_resources), .resource = osk5912_smc91x_resources, }; diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index ca7df1e93efc..1387a4f15da9 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -19,6 +19,7 @@ #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/input.h> +#include <linux/smc91x.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -30,7 +31,6 @@ #include <mach/gpio.h> #include <plat/mux.h> #include <plat/fpga.h> -#include <plat/nand.h> #include <plat/keypad.h> #include <plat/common.h> #include <plat/board.h> @@ -67,6 +67,12 @@ static int p2_keymap[] = { 0 }; +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource smc91x_resources[] = { [0] = { .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ @@ -134,8 +140,40 @@ static struct platform_device nor_device = { .resource = &nor_resource, }; -static struct omap_nand_platform_data nand_data = { - .options = NAND_SAMSUNG_LP_OPTIONS, +static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long mask; + + if (cmd == NAND_CMD_NONE) + return; + + mask = (ctrl & NAND_CLE) ? 0x02 : 0; + if (ctrl & NAND_ALE) + mask |= 0x04; + writeb(cmd, (unsigned long)this->IO_ADDR_W | mask); +} + +#define P2_NAND_RB_GPIO_PIN 62 + +static int nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(P2_NAND_RB_GPIO_PIN); +} + +static const char *part_probes[] = { "cmdlinepart", NULL }; + +static struct platform_nand_data nand_data = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .options = NAND_SAMSUNG_LP_OPTIONS, + .part_probe_types = part_probes, + }, + .ctrl = { + .cmd_ctrl = nand_cmd_ctl, + .dev_ready = nand_dev_ready, + }, }; static struct resource nand_resource = { @@ -145,7 +183,7 @@ static struct resource nand_resource = { }; static struct platform_device nand_device = { - .name = "omapnand", + .name = "gen_nand", .id = 0, .dev = { .platform_data = &nand_data, @@ -157,6 +195,9 @@ static struct platform_device nand_device = { static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &smc91x_info, + }, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; @@ -201,13 +242,6 @@ static struct platform_device *devices[] __initdata = { &lcd_device, }; -#define P2_NAND_RB_GPIO_PIN 62 - -static int nand_dev_ready(struct omap_nand_platform_data *data) -{ - return gpio_get_value(P2_NAND_RB_GPIO_PIN); -} - static struct omap_lcd_config perseus2_lcd_config __initdata = { .ctrl_name = "internal", }; @@ -220,7 +254,7 @@ static void __init omap_perseus2_init(void) { if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0) BUG(); - nand_data.dev_ready = nand_dev_ready; + gpio_direction_input(P2_NAND_RB_GPIO_PIN); omap_cfg_reg(L3_1610_FLASH_CS2B_OE); omap_cfg_reg(M8_1610_FLASH_CS2B_WE); diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 35c75c1bd0aa..169183537997 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -22,6 +22,7 @@ #include <linux/reboot.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> +#include <linux/smc91x.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -106,6 +107,12 @@ static struct platform_device voiceblue_flash_device = { .resource = &voiceblue_flash_resource, }; +static struct smc91x_platdata voiceblue_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + static struct resource voiceblue_smc91x_resources[] = { [0] = { .start = OMAP_CS2_PHYS + 0x300, @@ -122,6 +129,9 @@ static struct resource voiceblue_smc91x_resources[] = { static struct platform_device voiceblue_smc91x_device = { .name = "smc91x", .id = 0, + .dev = { + .platform_data = &voiceblue_smc91x_info, + }, .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources), .resource = voiceblue_smc91x_resources, }; diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 42cbe203da36..2ba9ab953731 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-omap1/clock.c * - * Copyright (C) 2004 - 2005 Nokia corporation + * Copyright (C) 2004 - 2005, 2009 Nokia corporation * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * * Modified to use omap shared clock framework by @@ -26,12 +26,17 @@ #include <plat/usb.h> #include <plat/clock.h> #include <plat/sram.h> - -static const struct clkops clkops_generic; -static const struct clkops clkops_uart; -static const struct clkops clkops_dspck; +#include <plat/clkdev_omap.h> #include "clock.h" +#include "opp.h" + +__u32 arm_idlect1_mask; +struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; + +/*------------------------------------------------------------------------- + * Omap1 specific clock functions + *-------------------------------------------------------------------------*/ static int clk_omap1_dummy_enable(struct clk *clk) { @@ -42,134 +47,24 @@ static void clk_omap1_dummy_disable(struct clk *clk) { } -static const struct clkops clkops_dummy = { - .enable = clk_omap1_dummy_enable, - .disable = clk_omap1_dummy_disable, -}; - -static struct clk dummy_ck = { - .name = "dummy", - .ops = &clkops_dummy, - .flags = RATE_FIXED, -}; - -struct omap_clk { - u32 cpu; - struct clk_lookup lk; +const struct clkops clkops_dummy = { + .enable = clk_omap1_dummy_enable, + .disable = clk_omap1_dummy_disable, }; -#define CLK(dev, con, ck, cp) \ - { \ - .cpu = cp, \ - .lk = { \ - .dev_id = dev, \ - .con_id = con, \ - .clk = ck, \ - }, \ - } - -#define CK_310 (1 << 0) -#define CK_7XX (1 << 1) -#define CK_1510 (1 << 2) -#define CK_16XX (1 << 3) - -static struct omap_clk omap_clks[] = { - /* non-ULPD clocks */ - CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310), - /* CK_GEN1 clocks */ - CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), - CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), - CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310), - CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX), - CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310), - CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310), - CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX), - /* CK_GEN2 clocks */ - CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310), - /* CK_GEN3 clocks */ - CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310), - CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX | CK_7XX), - CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX), - CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), - CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), - CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), - CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), - CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), - CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_7XX), - CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310), - /* ULPD clocks */ - CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310), - CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX), - CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310), - CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX), - CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), - CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), - CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX), - CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), - CLK(NULL, "mclk", &mclk_16xx, CK_16XX), - CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), - CLK(NULL, "bclk", &bclk_16xx, CK_16XX), - CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310), - CLK("mmci-omap.0", "fck", &mmc3_ck, CK_7XX), - CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX), - CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX), - /* Virtual clocks */ - CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310), - CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310), - CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX), - CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310), - CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), - CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), - CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX), - CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310), - CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX), - CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310), - CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), - CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), - CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), -}; - -static int omap1_clk_enable_generic(struct clk * clk); -static int omap1_clk_enable(struct clk *clk); -static void omap1_clk_disable_generic(struct clk * clk); -static void omap1_clk_disable(struct clk *clk); - -__u32 arm_idlect1_mask; - -/*------------------------------------------------------------------------- - * Omap1 specific clock functions - *-------------------------------------------------------------------------*/ - -static unsigned long omap1_watchdog_recalc(struct clk *clk) +/* XXX can be replaced with a fixed_divisor_recalc */ +unsigned long omap1_watchdog_recalc(struct clk *clk) { return clk->parent->rate / 14; } -static unsigned long omap1_uart_recalc(struct clk *clk) +unsigned long omap1_uart_recalc(struct clk *clk) { unsigned int val = __raw_readl(clk->enable_reg); return val & clk->enable_bit ? 48000000 : 12000000; } -static unsigned long omap1_sossi_recalc(struct clk *clk) +unsigned long omap1_sossi_recalc(struct clk *clk) { u32 div = omap_readl(MOD_CONF_CTRL_1); @@ -179,64 +74,6 @@ static unsigned long omap1_sossi_recalc(struct clk *clk) return clk->parent->rate / div; } -static int omap1_clk_enable_dsp_domain(struct clk *clk) -{ - int retval; - - retval = omap1_clk_enable(&api_ck.clk); - if (!retval) { - retval = omap1_clk_enable_generic(clk); - omap1_clk_disable(&api_ck.clk); - } - - return retval; -} - -static void omap1_clk_disable_dsp_domain(struct clk *clk) -{ - if (omap1_clk_enable(&api_ck.clk) == 0) { - omap1_clk_disable_generic(clk); - omap1_clk_disable(&api_ck.clk); - } -} - -static const struct clkops clkops_dspck = { - .enable = &omap1_clk_enable_dsp_domain, - .disable = &omap1_clk_disable_dsp_domain, -}; - -static int omap1_clk_enable_uart_functional(struct clk *clk) -{ - int ret; - struct uart_clk *uclk; - - ret = omap1_clk_enable_generic(clk); - if (ret == 0) { - /* Set smart idle acknowledgement mode */ - uclk = (struct uart_clk *)clk; - omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8, - uclk->sysc_addr); - } - - return ret; -} - -static void omap1_clk_disable_uart_functional(struct clk *clk) -{ - struct uart_clk *uclk; - - /* Set force idle acknowledgement mode */ - uclk = (struct uart_clk *)clk; - omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr); - - omap1_clk_disable_generic(clk); -} - -static const struct clkops clkops_uart = { - .enable = &omap1_clk_enable_uart_functional, - .disable = &omap1_clk_disable_uart_functional, -}; - static void omap1_clk_allow_idle(struct clk *clk) { struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; @@ -344,7 +181,7 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) return dsor_exp; } -static unsigned long omap1_ckctl_recalc(struct clk *clk) +unsigned long omap1_ckctl_recalc(struct clk *clk) { /* Calculate divisor encoded as 2-bit exponent */ int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); @@ -352,7 +189,7 @@ static unsigned long omap1_ckctl_recalc(struct clk *clk) return clk->parent->rate / dsor; } -static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) +unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) { int dsor; @@ -363,28 +200,29 @@ static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) * Note that DSP_CKCTL virt addr = phys addr, so * we must use __raw_readw() instead of omap_readw(). */ - omap1_clk_enable(&api_ck.clk); + omap1_clk_enable(api_ck_p); dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); - omap1_clk_disable(&api_ck.clk); + omap1_clk_disable(api_ck_p); return clk->parent->rate / dsor; } /* MPU virtual clock functions */ -static int omap1_select_table_rate(struct clk * clk, unsigned long rate) +int omap1_select_table_rate(struct clk *clk, unsigned long rate) { /* Find the highest supported frequency <= rate and switch to it */ struct mpu_rate * ptr; + unsigned long dpll1_rate, ref_rate; - if (clk != &virtual_ck_mpu) - return -EINVAL; + dpll1_rate = clk_get_rate(ck_dpll1_p); + ref_rate = clk_get_rate(ck_ref_p); - for (ptr = rate_table; ptr->rate; ptr++) { - if (ptr->xtal != ck_ref.rate) + for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (ptr->xtal != ref_rate) continue; /* DPLL1 cannot be reprogrammed without risking system crash */ - if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate) + if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate) continue; /* Can check only after xtal frequency check */ @@ -405,11 +243,13 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate) else omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); - ck_dpll1.rate = ptr->pll_rate; + /* XXX Do we need to recalculate the tree below DPLL1 at this point? */ + ck_dpll1_p->rate = ptr->pll_rate; + return 0; } -static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) +int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) { int dsor_exp; u16 regval; @@ -429,7 +269,7 @@ static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) return 0; } -static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) +long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) { int dsor_exp = calc_dsor_exp(clk, rate); if (dsor_exp < 0) @@ -439,7 +279,7 @@ static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) return clk->parent->rate / (1 << dsor_exp); } -static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) +int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) { int dsor_exp; u16 regval; @@ -459,19 +299,19 @@ static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) return 0; } -static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) +long omap1_round_to_table_rate(struct clk *clk, unsigned long rate) { /* Find the highest supported frequency <= rate */ struct mpu_rate * ptr; - long highest_rate; + long highest_rate; + unsigned long ref_rate; - if (clk != &virtual_ck_mpu) - return -EINVAL; + ref_rate = clk_get_rate(ck_ref_p); highest_rate = -EINVAL; - for (ptr = rate_table; ptr->rate; ptr++) { - if (ptr->xtal != ck_ref.rate) + for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (ptr->xtal != ref_rate) continue; highest_rate = ptr->rate; @@ -506,8 +346,8 @@ static unsigned calc_ext_dsor(unsigned long rate) return dsor; } -/* Only needed on 1510 */ -static int omap1_set_uart_rate(struct clk * clk, unsigned long rate) +/* XXX Only needed on 1510 */ +int omap1_set_uart_rate(struct clk *clk, unsigned long rate) { unsigned int val; @@ -525,7 +365,7 @@ static int omap1_set_uart_rate(struct clk * clk, unsigned long rate) } /* External clock (MCLK & BCLK) functions */ -static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) +int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate) { unsigned dsor; __u16 ratio_bits; @@ -543,7 +383,7 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) return 0; } -static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) +int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) { u32 l; int div; @@ -566,12 +406,12 @@ static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) return 0; } -static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate) +long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate) { return 96000000 / calc_ext_dsor(rate); } -static void omap1_init_ext_clk(struct clk * clk) +void omap1_init_ext_clk(struct clk *clk) { unsigned dsor; __u16 ratio_bits; @@ -589,7 +429,7 @@ static void omap1_init_ext_clk(struct clk * clk) clk-> rate = 96000000 / dsor; } -static int omap1_clk_enable(struct clk *clk) +int omap1_clk_enable(struct clk *clk) { int ret = 0; @@ -617,7 +457,7 @@ err: return ret; } -static void omap1_clk_disable(struct clk *clk) +void omap1_clk_disable(struct clk *clk) { if (clk->usecount > 0 && !(--clk->usecount)) { clk->ops->disable(clk); @@ -672,12 +512,70 @@ static void omap1_clk_disable_generic(struct clk *clk) } } -static const struct clkops clkops_generic = { - .enable = &omap1_clk_enable_generic, - .disable = &omap1_clk_disable_generic, +const struct clkops clkops_generic = { + .enable = omap1_clk_enable_generic, + .disable = omap1_clk_disable_generic, +}; + +static int omap1_clk_enable_dsp_domain(struct clk *clk) +{ + int retval; + + retval = omap1_clk_enable(api_ck_p); + if (!retval) { + retval = omap1_clk_enable_generic(clk); + omap1_clk_disable(api_ck_p); + } + + return retval; +} + +static void omap1_clk_disable_dsp_domain(struct clk *clk) +{ + if (omap1_clk_enable(api_ck_p) == 0) { + omap1_clk_disable_generic(clk); + omap1_clk_disable(api_ck_p); + } +} + +const struct clkops clkops_dspck = { + .enable = omap1_clk_enable_dsp_domain, + .disable = omap1_clk_disable_dsp_domain, +}; + +static int omap1_clk_enable_uart_functional(struct clk *clk) +{ + int ret; + struct uart_clk *uclk; + + ret = omap1_clk_enable_generic(clk); + if (ret == 0) { + /* Set smart idle acknowledgement mode */ + uclk = (struct uart_clk *)clk; + omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8, + uclk->sysc_addr); + } + + return ret; +} + +static void omap1_clk_disable_uart_functional(struct clk *clk) +{ + struct uart_clk *uclk; + + /* Set force idle acknowledgement mode */ + uclk = (struct uart_clk *)clk; + omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr); + + omap1_clk_disable_generic(clk); +} + +const struct clkops clkops_uart = { + .enable = omap1_clk_enable_uart_functional, + .disable = omap1_clk_disable_uart_functional, }; -static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) +long omap1_clk_round_rate(struct clk *clk, unsigned long rate) { if (clk->flags & RATE_FIXED) return clk->rate; @@ -688,7 +586,7 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) return clk->rate; } -static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) +int omap1_clk_set_rate(struct clk *clk, unsigned long rate) { int ret = -EINVAL; @@ -703,7 +601,7 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) #ifdef CONFIG_OMAP_RESET_CLOCKS -static void __init omap1_clk_disable_unused(struct clk *clk) +void __init omap1_clk_disable_unused(struct clk *clk) { __u32 regval32; @@ -724,184 +622,9 @@ static void __init omap1_clk_disable_unused(struct clk *clk) if ((regval32 & (1 << clk->enable_bit)) == 0) return; - /* FIXME: This clock seems to be necessary but no-one - * has asked for its activation. */ - if (clk == &tc2_ck /* FIX: pm.c (SRAM), CCP, Camera */ - || clk == &ck_dpll1out.clk /* FIX: SoSSI, SSR */ - || clk == &arm_gpio_ck /* FIX: GPIO code for 1510 */ - ) { - printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", - clk->name); - return; - } - printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); clk->ops->disable(clk); printk(" done\n"); } -#else -#define omap1_clk_disable_unused NULL #endif - -static struct clk_functions omap1_clk_functions = { - .clk_enable = omap1_clk_enable, - .clk_disable = omap1_clk_disable, - .clk_round_rate = omap1_clk_round_rate, - .clk_set_rate = omap1_clk_set_rate, - .clk_disable_unused = omap1_clk_disable_unused, -}; - -int __init omap1_clk_init(void) -{ - struct omap_clk *c; - const struct omap_clock_config *info; - int crystal_type = 0; /* Default 12 MHz */ - u32 reg, cpu_mask; - -#ifdef CONFIG_DEBUG_LL - /* Resets some clocks that may be left on from bootloader, - * but leaves serial clocks on. - */ - omap_writel(0x3 << 29, MOD_CONF_CTRL_0); -#endif - - /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ - reg = omap_readw(SOFT_REQ_REG) & (1 << 4); - omap_writew(reg, SOFT_REQ_REG); - if (!cpu_is_omap15xx()) - omap_writew(0, SOFT_REQ_REG2); - - clk_init(&omap1_clk_functions); - - /* By default all idlect1 clocks are allowed to idle */ - arm_idlect1_mask = ~0; - - for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) - clk_preinit(c->lk.clk); - - cpu_mask = 0; - if (cpu_is_omap16xx()) - cpu_mask |= CK_16XX; - if (cpu_is_omap1510()) - cpu_mask |= CK_1510; - if (cpu_is_omap7xx()) - cpu_mask |= CK_7XX; - if (cpu_is_omap310()) - cpu_mask |= CK_310; - - for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) - if (c->cpu & cpu_mask) { - clkdev_add(&c->lk); - clk_register(c->lk.clk); - } - - info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); - if (info != NULL) { - if (!cpu_is_omap15xx()) - crystal_type = info->system_clock_type; - } - -#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) - ck_ref.rate = 13000000; -#elif defined(CONFIG_ARCH_OMAP16XX) - if (crystal_type == 2) - ck_ref.rate = 19200000; -#endif - - printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", - omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), - omap_readw(ARM_CKCTL)); - - /* We want to be in syncronous scalable mode */ - omap_writew(0x1000, ARM_SYSST); - -#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER - /* Use values set by bootloader. Determine PLL rate and recalculate - * dependent clocks as if kernel had changed PLL or divisors. - */ - { - unsigned pll_ctl_val = omap_readw(DPLL_CTL); - - ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ - if (pll_ctl_val & 0x10) { - /* PLL enabled, apply multiplier and divisor */ - if (pll_ctl_val & 0xf80) - ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; - ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; - } else { - /* PLL disabled, apply bypass divisor */ - switch (pll_ctl_val & 0xc) { - case 0: - break; - case 0x4: - ck_dpll1.rate /= 2; - break; - default: - ck_dpll1.rate /= 4; - break; - } - } - } -#else - /* Find the highest supported frequency and enable it */ - if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { - printk(KERN_ERR "System frequencies not set. Check your config.\n"); - /* Guess sane values (60MHz) */ - omap_writew(0x2290, DPLL_CTL); - omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); - ck_dpll1.rate = 60000000; - } -#endif - propagate_rate(&ck_dpll1); - /* Cache rates for clocks connected to ck_ref (not dpll1) */ - propagate_rate(&ck_ref); - printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " - "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", - ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, - ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, - arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); - -#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE) - /* Select slicer output as OMAP input clock */ - omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, OMAP7XX_PCC_UPLD_CTRL); -#endif - - /* Amstrad Delta wants BCLK high when inactive */ - if (machine_is_ams_delta()) - omap_writel(omap_readl(ULPD_CLOCK_CTRL) | - (1 << SDW_MCLK_INV_BIT), - ULPD_CLOCK_CTRL); - - /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ - /* (on 730, bit 13 must not be cleared) */ - if (cpu_is_omap7xx()) - 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); - omap_writew(1, ARM_RSTCT2); - omap_writew(0x400, ARM_IDLECT1); - - /* - * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) - * of the ARM_IDLECT2 register must be set to zero. The power-on - * default value of this bit is one. - */ - omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ - - /* - * Only enable those clocks we will need, let the drivers - * enable other clocks as necessary - */ - clk_enable(&armper_ck.clk); - clk_enable(&armxor_ck.clk); - clk_enable(&armtim_ck.clk); /* This should be done by timer code */ - - if (cpu_is_omap15xx()) - clk_enable(&arm_gpio_ck); - - return 0; -} diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 29ffa97dc7f3..a4190afb8614 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-omap1/clock.h * - * Copyright (C) 2004 - 2005 Nokia corporation + * Copyright (C) 2004 - 2005, 2009 Nokia corporation * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc * @@ -13,30 +13,36 @@ #ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H #define __ARCH_ARM_MACH_OMAP1_CLOCK_H -static unsigned long omap1_ckctl_recalc(struct clk *clk); -static unsigned long omap1_watchdog_recalc(struct clk *clk); -static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate); -static unsigned long omap1_sossi_recalc(struct clk *clk); -static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk); -static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate); -static int omap1_set_uart_rate(struct clk * clk, unsigned long rate); -static unsigned long omap1_uart_recalc(struct clk *clk); -static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate); -static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate); -static void omap1_init_ext_clk(struct clk * clk); -static int omap1_select_table_rate(struct clk * clk, unsigned long rate); -static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); - -static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate); -static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate); - -struct mpu_rate { - unsigned long rate; - unsigned long xtal; - unsigned long pll_rate; - __u16 ckctl_val; - __u16 dpllctl_val; -}; +#include <linux/clk.h> + +#include <plat/clock.h> + +extern int __init omap1_clk_init(void); +extern int omap1_clk_enable(struct clk *clk); +extern void omap1_clk_disable(struct clk *clk); +extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate); +extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate); +extern unsigned long omap1_ckctl_recalc(struct clk *clk); +extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate); +extern unsigned long omap1_sossi_recalc(struct clk *clk); +extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk); +extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate); +extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate); +extern unsigned long omap1_uart_recalc(struct clk *clk); +extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate); +extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate); +extern void omap1_init_ext_clk(struct clk *clk); +extern int omap1_select_table_rate(struct clk *clk, unsigned long rate); +extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate); +extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate); +extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate); +extern unsigned long omap1_watchdog_recalc(struct clk *clk); + +#ifdef CONFIG_OMAP_RESET_CLOCKS +extern void __init omap1_clk_disable_unused(struct clk *clk); +#else +#define omap1_clk_disable_unused NULL +#endif struct uart_clk { struct clk clk; @@ -96,596 +102,12 @@ struct arm_idlect1_clk { #define SOFT_REQ_REG 0xfffe0834 #define SOFT_REQ_REG2 0xfffe0880 -/*------------------------------------------------------------------------- - * Omap1 MPU rate table - *-------------------------------------------------------------------------*/ -static struct mpu_rate rate_table[] = { - /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL - * NOTE: Comment order here is different from bits in CKCTL value: - * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv - */ -#if defined(CONFIG_OMAP_ARM_216MHZ) - { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_195MHZ) - { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_192MHZ) - { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ - { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ - { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ - { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ - { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_182MHZ) - { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_168MHZ) - { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_150MHZ) - { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_120MHZ) - { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_96MHZ) - { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_60MHZ) - { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_30MHZ) - { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ -#endif - { 0, 0, 0, 0, 0 }, -}; - -/*------------------------------------------------------------------------- - * Omap1 clocks - *-------------------------------------------------------------------------*/ - -static struct clk ck_ref = { - .name = "ck_ref", - .ops = &clkops_null, - .rate = 12000000, -}; - -static struct clk ck_dpll1 = { - .name = "ck_dpll1", - .ops = &clkops_null, - .parent = &ck_ref, -}; - -static struct arm_idlect1_clk ck_dpll1out = { - .clk = { - .name = "ck_dpll1out", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_CKOUT_ARM, - .recalc = &followparent_recalc, - }, - .idlect_shift = 12, -}; - -static struct clk sossi_ck = { - .name = "ck_sossi", - .ops = &clkops_generic, - .parent = &ck_dpll1out.clk, - .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1), - .enable_bit = 16, - .recalc = &omap1_sossi_recalc, - .set_rate = &omap1_set_sossi_rate, -}; - -static struct clk arm_ck = { - .name = "arm_ck", - .ops = &clkops_null, - .parent = &ck_dpll1, - .rate_offset = CKCTL_ARMDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, -}; - -static struct arm_idlect1_clk armper_ck = { - .clk = { - .name = "armper_ck", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_PERCK, - .rate_offset = CKCTL_PERDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, - }, - .idlect_shift = 2, -}; - -static struct clk arm_gpio_ck = { - .name = "arm_gpio_ck", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_GPIOCK, - .recalc = &followparent_recalc, -}; - -static struct arm_idlect1_clk armxor_ck = { - .clk = { - .name = "armxor_ck", - .ops = &clkops_generic, - .parent = &ck_ref, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_XORPCK, - .recalc = &followparent_recalc, - }, - .idlect_shift = 1, -}; - -static struct arm_idlect1_clk armtim_ck = { - .clk = { - .name = "armtim_ck", - .ops = &clkops_generic, - .parent = &ck_ref, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_TIMCK, - .recalc = &followparent_recalc, - }, - .idlect_shift = 9, -}; - -static struct arm_idlect1_clk armwdt_ck = { - .clk = { - .name = "armwdt_ck", - .ops = &clkops_generic, - .parent = &ck_ref, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_WDTCK, - .recalc = &omap1_watchdog_recalc, - }, - .idlect_shift = 0, -}; - -static struct clk arminth_ck16xx = { - .name = "arminth_ck", - .ops = &clkops_null, - .parent = &arm_ck, - .recalc = &followparent_recalc, - /* Note: On 16xx the frequency can be divided by 2 by programming - * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 - * - * 1510 version is in TC clocks. - */ -}; - -static struct clk dsp_ck = { - .name = "dsp_ck", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL), - .enable_bit = EN_DSPCK, - .rate_offset = CKCTL_DSPDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, -}; - -static struct clk dspmmu_ck = { - .name = "dspmmu_ck", - .ops = &clkops_null, - .parent = &ck_dpll1, - .rate_offset = CKCTL_DSPMMUDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, -}; - -static struct clk dspper_ck = { - .name = "dspper_ck", - .ops = &clkops_dspck, - .parent = &ck_dpll1, - .enable_reg = DSP_IDLECT2, - .enable_bit = EN_PERCK, - .rate_offset = CKCTL_PERDIV_OFFSET, - .recalc = &omap1_ckctl_recalc_dsp_domain, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = &omap1_clk_set_rate_dsp_domain, -}; - -static struct clk dspxor_ck = { - .name = "dspxor_ck", - .ops = &clkops_dspck, - .parent = &ck_ref, - .enable_reg = DSP_IDLECT2, - .enable_bit = EN_XORPCK, - .recalc = &followparent_recalc, -}; - -static struct clk dsptim_ck = { - .name = "dsptim_ck", - .ops = &clkops_dspck, - .parent = &ck_ref, - .enable_reg = DSP_IDLECT2, - .enable_bit = EN_DSPTIMCK, - .recalc = &followparent_recalc, -}; - -/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */ -static struct arm_idlect1_clk tc_ck = { - .clk = { - .name = "tc_ck", - .ops = &clkops_null, - .parent = &ck_dpll1, - .flags = CLOCK_IDLE_CONTROL, - .rate_offset = CKCTL_TCDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, - }, - .idlect_shift = 6, -}; - -static struct clk arminth_ck1510 = { - .name = "arminth_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, - /* Note: On 1510 the frequency follows TC_CK - * - * 16xx version is in MPU clocks. - */ -}; - -static struct clk tipb_ck = { - /* No-idle controlled by "tc_ck" */ - .name = "tipb_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct clk l3_ocpi_ck = { - /* No-idle controlled by "tc_ck" */ - .name = "l3_ocpi_ck", - .ops = &clkops_generic, - .parent = &tc_ck.clk, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), - .enable_bit = EN_OCPI_CK, - .recalc = &followparent_recalc, -}; - -static struct clk tc1_ck = { - .name = "tc1_ck", - .ops = &clkops_generic, - .parent = &tc_ck.clk, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), - .enable_bit = EN_TC1_CK, - .recalc = &followparent_recalc, -}; +extern __u32 arm_idlect1_mask; +extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; -static struct clk tc2_ck = { - .name = "tc2_ck", - .ops = &clkops_generic, - .parent = &tc_ck.clk, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), - .enable_bit = EN_TC2_CK, - .recalc = &followparent_recalc, -}; - -static struct clk dma_ck = { - /* No-idle controlled by "tc_ck" */ - .name = "dma_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct clk dma_lcdfree_ck = { - .name = "dma_lcdfree_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct arm_idlect1_clk api_ck = { - .clk = { - .name = "api_ck", - .ops = &clkops_generic, - .parent = &tc_ck.clk, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_APICK, - .recalc = &followparent_recalc, - }, - .idlect_shift = 8, -}; - -static struct arm_idlect1_clk lb_ck = { - .clk = { - .name = "lb_ck", - .ops = &clkops_generic, - .parent = &tc_ck.clk, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_LBCK, - .recalc = &followparent_recalc, - }, - .idlect_shift = 4, -}; - -static struct clk rhea1_ck = { - .name = "rhea1_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct clk rhea2_ck = { - .name = "rhea2_ck", - .ops = &clkops_null, - .parent = &tc_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct clk lcd_ck_16xx = { - .name = "lcd_ck", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_LCDCK, - .rate_offset = CKCTL_LCDDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, -}; - -static struct arm_idlect1_clk lcd_ck_1510 = { - .clk = { - .name = "lcd_ck", - .ops = &clkops_generic, - .parent = &ck_dpll1, - .flags = CLOCK_IDLE_CONTROL, - .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), - .enable_bit = EN_LCDCK, - .rate_offset = CKCTL_LCDDIV_OFFSET, - .recalc = &omap1_ckctl_recalc, - .round_rate = omap1_clk_round_rate_ckctl_arm, - .set_rate = omap1_clk_set_rate_ckctl_arm, - }, - .idlect_shift = 3, -}; - -static struct clk uart1_1510 = { - .name = "uart1_ck", - .ops = &clkops_null, - /* Direct from ULPD, no real parent */ - .parent = &armper_ck.clk, - .rate = 12000000, - .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ - .set_rate = &omap1_set_uart_rate, - .recalc = &omap1_uart_recalc, -}; - -static struct uart_clk uart1_16xx = { - .clk = { - .name = "uart1_ck", - .ops = &clkops_uart, - /* Direct from ULPD, no real parent */ - .parent = &armper_ck.clk, - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 29, - }, - .sysc_addr = 0xfffb0054, -}; - -static struct clk uart2_ck = { - .name = "uart2_ck", - .ops = &clkops_null, - /* Direct from ULPD, no real parent */ - .parent = &armper_ck.clk, - .rate = 12000000, - .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ - .set_rate = &omap1_set_uart_rate, - .recalc = &omap1_uart_recalc, -}; - -static struct clk uart3_1510 = { - .name = "uart3_ck", - .ops = &clkops_null, - /* Direct from ULPD, no real parent */ - .parent = &armper_ck.clk, - .rate = 12000000, - .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ - .set_rate = &omap1_set_uart_rate, - .recalc = &omap1_uart_recalc, -}; - -static struct uart_clk uart3_16xx = { - .clk = { - .name = "uart3_ck", - .ops = &clkops_uart, - /* Direct from ULPD, no real parent */ - .parent = &armper_ck.clk, - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 31, - }, - .sysc_addr = 0xfffb9854, -}; - -static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ - .name = "usb_clko", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 6000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL), - .enable_bit = USB_MCLK_EN_BIT, -}; - -static struct clk usb_hhc_ck1510 = { - .name = "usb_hhc_ck", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ - .flags = RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = USB_HOST_HHC_UHOST_EN, -}; - -static struct clk usb_hhc_ck16xx = { - .name = "usb_hhc_ck", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 48000000, - /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ - .flags = RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */ - .enable_bit = 8 /* UHOST_EN */, -}; - -static struct clk usb_dc_ck = { - .name = "usb_dc_ck", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 48000000, - .flags = RATE_FIXED, - .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), - .enable_bit = 4, -}; - -static struct clk usb_dc_ck7xx = { - .name = "usb_dc_ck", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 48000000, - .flags = RATE_FIXED, - .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), - .enable_bit = 8, -}; - -static struct clk mclk_1510 = { - .name = "mclk", - .ops = &clkops_generic, - /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .rate = 12000000, - .flags = RATE_FIXED, - .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), - .enable_bit = 6, -}; - -static struct clk mclk_16xx = { - .name = "mclk", - .ops = &clkops_generic, - /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL), - .enable_bit = COM_ULPD_PLL_CLK_REQ, - .set_rate = &omap1_set_ext_clk_rate, - .round_rate = &omap1_round_ext_clk_rate, - .init = &omap1_init_ext_clk, -}; - -static struct clk bclk_1510 = { - .name = "bclk", - .ops = &clkops_generic, - /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .rate = 12000000, - .flags = RATE_FIXED, -}; - -static struct clk bclk_16xx = { - .name = "bclk", - .ops = &clkops_generic, - /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL), - .enable_bit = SWD_ULPD_PLL_CLK_REQ, - .set_rate = &omap1_set_ext_clk_rate, - .round_rate = &omap1_round_ext_clk_rate, - .init = &omap1_init_ext_clk, -}; - -static struct clk mmc1_ck = { - .name = "mmc_ck", - .ops = &clkops_generic, - /* Functional clock is direct from ULPD, interface clock is ARMPER */ - .parent = &armper_ck.clk, - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 23, -}; - -static struct clk mmc2_ck = { - .name = "mmc_ck", - .id = 1, - .ops = &clkops_generic, - /* Functional clock is direct from ULPD, interface clock is ARMPER */ - .parent = &armper_ck.clk, - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), - .enable_bit = 20, -}; - -static struct clk mmc3_ck = { - .name = "mmc_ck", - .id = 2, - .ops = &clkops_generic, - /* Functional clock is direct from ULPD, interface clock is ARMPER */ - .parent = &armper_ck.clk, - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), - .enable_bit = 12, -}; - -static struct clk virtual_ck_mpu = { - .name = "mpu", - .ops = &clkops_null, - .parent = &arm_ck, /* Is smarter alias for */ - .recalc = &followparent_recalc, - .set_rate = &omap1_select_table_rate, - .round_rate = &omap1_round_to_table_rate, -}; - -/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK -remains active during MPU idle whenever this is enabled */ -static struct clk i2c_fck = { - .name = "i2c_fck", - .id = 1, - .ops = &clkops_null, - .flags = CLOCK_NO_IDLE_PARENT, - .parent = &armxor_ck.clk, - .recalc = &followparent_recalc, -}; - -static struct clk i2c_ick = { - .name = "i2c_ick", - .id = 1, - .ops = &clkops_null, - .flags = CLOCK_NO_IDLE_PARENT, - .parent = &armper_ck.clk, - .recalc = &followparent_recalc, -}; +extern const struct clkops clkops_dspck; +extern const struct clkops clkops_dummy; +extern const struct clkops clkops_uart; +extern const struct clkops clkops_generic; #endif diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c new file mode 100644 index 000000000000..65e7b5b85d83 --- /dev/null +++ b/arch/arm/mach-omap1/clock_data.c @@ -0,0 +1,847 @@ +/* + * linux/arch/arm/mach-omap1/clock_data.c + * + * Copyright (C) 2004 - 2005, 2009 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <asm/mach-types.h> /* for machine_is_* */ + +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/clkdev_omap.h> +#include <plat/usb.h> /* for OTG_BASE */ + +#include "clock.h" + +/*------------------------------------------------------------------------ + * Omap1 clocks + *-------------------------------------------------------------------------*/ + +/* XXX is this necessary? */ +static struct clk dummy_ck = { + .name = "dummy", + .ops = &clkops_dummy, + .flags = RATE_FIXED, +}; + +static struct clk ck_ref = { + .name = "ck_ref", + .ops = &clkops_null, + .rate = 12000000, +}; + +static struct clk ck_dpll1 = { + .name = "ck_dpll1", + .ops = &clkops_null, + .parent = &ck_ref, +}; + +/* + * FIXME: This clock seems to be necessary but no-one has asked for its + * activation. [ FIX: SoSSI, SSR ] + */ +static struct arm_idlect1_clk ck_dpll1out = { + .clk = { + .name = "ck_dpll1out", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT | + ENABLE_ON_INIT, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_CKOUT_ARM, + .recalc = &followparent_recalc, + }, + .idlect_shift = 12, +}; + +static struct clk sossi_ck = { + .name = "ck_sossi", + .ops = &clkops_generic, + .parent = &ck_dpll1out.clk, + .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1), + .enable_bit = 16, + .recalc = &omap1_sossi_recalc, + .set_rate = &omap1_set_sossi_rate, +}; + +static struct clk arm_ck = { + .name = "arm_ck", + .ops = &clkops_null, + .parent = &ck_dpll1, + .rate_offset = CKCTL_ARMDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, +}; + +static struct arm_idlect1_clk armper_ck = { + .clk = { + .name = "armper_ck", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_PERCK, + .rate_offset = CKCTL_PERDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, + }, + .idlect_shift = 2, +}; + +/* + * FIXME: This clock seems to be necessary but no-one has asked for its + * activation. [ GPIO code for 1510 ] + */ +static struct clk arm_gpio_ck = { + .name = "arm_gpio_ck", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .flags = ENABLE_ON_INIT, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_GPIOCK, + .recalc = &followparent_recalc, +}; + +static struct arm_idlect1_clk armxor_ck = { + .clk = { + .name = "armxor_ck", + .ops = &clkops_generic, + .parent = &ck_ref, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_XORPCK, + .recalc = &followparent_recalc, + }, + .idlect_shift = 1, +}; + +static struct arm_idlect1_clk armtim_ck = { + .clk = { + .name = "armtim_ck", + .ops = &clkops_generic, + .parent = &ck_ref, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_TIMCK, + .recalc = &followparent_recalc, + }, + .idlect_shift = 9, +}; + +static struct arm_idlect1_clk armwdt_ck = { + .clk = { + .name = "armwdt_ck", + .ops = &clkops_generic, + .parent = &ck_ref, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_WDTCK, + .recalc = &omap1_watchdog_recalc, + }, + .idlect_shift = 0, +}; + +static struct clk arminth_ck16xx = { + .name = "arminth_ck", + .ops = &clkops_null, + .parent = &arm_ck, + .recalc = &followparent_recalc, + /* Note: On 16xx the frequency can be divided by 2 by programming + * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 + * + * 1510 version is in TC clocks. + */ +}; + +static struct clk dsp_ck = { + .name = "dsp_ck", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL), + .enable_bit = EN_DSPCK, + .rate_offset = CKCTL_DSPDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, +}; + +static struct clk dspmmu_ck = { + .name = "dspmmu_ck", + .ops = &clkops_null, + .parent = &ck_dpll1, + .rate_offset = CKCTL_DSPMMUDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, +}; + +static struct clk dspper_ck = { + .name = "dspper_ck", + .ops = &clkops_dspck, + .parent = &ck_dpll1, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_PERCK, + .rate_offset = CKCTL_PERDIV_OFFSET, + .recalc = &omap1_ckctl_recalc_dsp_domain, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = &omap1_clk_set_rate_dsp_domain, +}; + +static struct clk dspxor_ck = { + .name = "dspxor_ck", + .ops = &clkops_dspck, + .parent = &ck_ref, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_XORPCK, + .recalc = &followparent_recalc, +}; + +static struct clk dsptim_ck = { + .name = "dsptim_ck", + .ops = &clkops_dspck, + .parent = &ck_ref, + .enable_reg = DSP_IDLECT2, + .enable_bit = EN_DSPTIMCK, + .recalc = &followparent_recalc, +}; + +/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */ +static struct arm_idlect1_clk tc_ck = { + .clk = { + .name = "tc_ck", + .ops = &clkops_null, + .parent = &ck_dpll1, + .flags = CLOCK_IDLE_CONTROL, + .rate_offset = CKCTL_TCDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, + }, + .idlect_shift = 6, +}; + +static struct clk arminth_ck1510 = { + .name = "arminth_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, + /* Note: On 1510 the frequency follows TC_CK + * + * 16xx version is in MPU clocks. + */ +}; + +static struct clk tipb_ck = { + /* No-idle controlled by "tc_ck" */ + .name = "tipb_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct clk l3_ocpi_ck = { + /* No-idle controlled by "tc_ck" */ + .name = "l3_ocpi_ck", + .ops = &clkops_generic, + .parent = &tc_ck.clk, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), + .enable_bit = EN_OCPI_CK, + .recalc = &followparent_recalc, +}; + +static struct clk tc1_ck = { + .name = "tc1_ck", + .ops = &clkops_generic, + .parent = &tc_ck.clk, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), + .enable_bit = EN_TC1_CK, + .recalc = &followparent_recalc, +}; + +/* + * FIXME: This clock seems to be necessary but no-one has asked for its + * activation. [ pm.c (SRAM), CCP, Camera ] + */ +static struct clk tc2_ck = { + .name = "tc2_ck", + .ops = &clkops_generic, + .parent = &tc_ck.clk, + .flags = ENABLE_ON_INIT, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), + .enable_bit = EN_TC2_CK, + .recalc = &followparent_recalc, +}; + +static struct clk dma_ck = { + /* No-idle controlled by "tc_ck" */ + .name = "dma_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct clk dma_lcdfree_ck = { + .name = "dma_lcdfree_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct arm_idlect1_clk api_ck = { + .clk = { + .name = "api_ck", + .ops = &clkops_generic, + .parent = &tc_ck.clk, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_APICK, + .recalc = &followparent_recalc, + }, + .idlect_shift = 8, +}; + +static struct arm_idlect1_clk lb_ck = { + .clk = { + .name = "lb_ck", + .ops = &clkops_generic, + .parent = &tc_ck.clk, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_LBCK, + .recalc = &followparent_recalc, + }, + .idlect_shift = 4, +}; + +static struct clk rhea1_ck = { + .name = "rhea1_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct clk rhea2_ck = { + .name = "rhea2_ck", + .ops = &clkops_null, + .parent = &tc_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct clk lcd_ck_16xx = { + .name = "lcd_ck", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_LCDCK, + .rate_offset = CKCTL_LCDDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, +}; + +static struct arm_idlect1_clk lcd_ck_1510 = { + .clk = { + .name = "lcd_ck", + .ops = &clkops_generic, + .parent = &ck_dpll1, + .flags = CLOCK_IDLE_CONTROL, + .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), + .enable_bit = EN_LCDCK, + .rate_offset = CKCTL_LCDDIV_OFFSET, + .recalc = &omap1_ckctl_recalc, + .round_rate = omap1_clk_round_rate_ckctl_arm, + .set_rate = omap1_clk_set_rate_ckctl_arm, + }, + .idlect_shift = 3, +}; + +static struct clk uart1_1510 = { + .name = "uart1_ck", + .ops = &clkops_null, + /* Direct from ULPD, no real parent */ + .parent = &armper_ck.clk, + .rate = 12000000, + .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ + .set_rate = &omap1_set_uart_rate, + .recalc = &omap1_uart_recalc, +}; + +static struct uart_clk uart1_16xx = { + .clk = { + .name = "uart1_ck", + .ops = &clkops_uart, + /* Direct from ULPD, no real parent */ + .parent = &armper_ck.clk, + .rate = 48000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT | + CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 29, + }, + .sysc_addr = 0xfffb0054, +}; + +static struct clk uart2_ck = { + .name = "uart2_ck", + .ops = &clkops_null, + /* Direct from ULPD, no real parent */ + .parent = &armper_ck.clk, + .rate = 12000000, + .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ + .set_rate = &omap1_set_uart_rate, + .recalc = &omap1_uart_recalc, +}; + +static struct clk uart3_1510 = { + .name = "uart3_ck", + .ops = &clkops_null, + /* Direct from ULPD, no real parent */ + .parent = &armper_ck.clk, + .rate = 12000000, + .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ + .set_rate = &omap1_set_uart_rate, + .recalc = &omap1_uart_recalc, +}; + +static struct uart_clk uart3_16xx = { + .clk = { + .name = "uart3_ck", + .ops = &clkops_uart, + /* Direct from ULPD, no real parent */ + .parent = &armper_ck.clk, + .rate = 48000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT | + CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 31, + }, + .sysc_addr = 0xfffb9854, +}; + +static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ + .name = "usb_clko", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 6000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL), + .enable_bit = USB_MCLK_EN_BIT, +}; + +static struct clk usb_hhc_ck1510 = { + .name = "usb_hhc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ + .flags = RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = USB_HOST_HHC_UHOST_EN, +}; + +static struct clk usb_hhc_ck16xx = { + .name = "usb_hhc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, + /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ + .flags = RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */ + .enable_bit = 8 /* UHOST_EN */, +}; + +static struct clk usb_dc_ck = { + .name = "usb_dc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = RATE_FIXED, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = 4, +}; + +static struct clk usb_dc_ck7xx = { + .name = "usb_dc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = RATE_FIXED, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = 8, +}; + +static struct clk mclk_1510 = { + .name = "mclk", + .ops = &clkops_generic, + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .rate = 12000000, + .flags = RATE_FIXED, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = 6, +}; + +static struct clk mclk_16xx = { + .name = "mclk", + .ops = &clkops_generic, + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL), + .enable_bit = COM_ULPD_PLL_CLK_REQ, + .set_rate = &omap1_set_ext_clk_rate, + .round_rate = &omap1_round_ext_clk_rate, + .init = &omap1_init_ext_clk, +}; + +static struct clk bclk_1510 = { + .name = "bclk", + .ops = &clkops_generic, + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk bclk_16xx = { + .name = "bclk", + .ops = &clkops_generic, + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL), + .enable_bit = SWD_ULPD_PLL_CLK_REQ, + .set_rate = &omap1_set_ext_clk_rate, + .round_rate = &omap1_round_ext_clk_rate, + .init = &omap1_init_ext_clk, +}; + +static struct clk mmc1_ck = { + .name = "mmc_ck", + .ops = &clkops_generic, + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck.clk, + .rate = 48000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 23, +}; + +static struct clk mmc2_ck = { + .name = "mmc_ck", + .id = 1, + .ops = &clkops_generic, + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck.clk, + .rate = 48000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), + .enable_bit = 20, +}; + +static struct clk mmc3_ck = { + .name = "mmc_ck", + .id = 2, + .ops = &clkops_generic, + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck.clk, + .rate = 48000000, + .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = 12, +}; + +static struct clk virtual_ck_mpu = { + .name = "mpu", + .ops = &clkops_null, + .parent = &arm_ck, /* Is smarter alias for */ + .recalc = &followparent_recalc, + .set_rate = &omap1_select_table_rate, + .round_rate = &omap1_round_to_table_rate, +}; + +/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK +remains active during MPU idle whenever this is enabled */ +static struct clk i2c_fck = { + .name = "i2c_fck", + .id = 1, + .ops = &clkops_null, + .flags = CLOCK_NO_IDLE_PARENT, + .parent = &armxor_ck.clk, + .recalc = &followparent_recalc, +}; + +static struct clk i2c_ick = { + .name = "i2c_ick", + .id = 1, + .ops = &clkops_null, + .flags = CLOCK_NO_IDLE_PARENT, + .parent = &armper_ck.clk, + .recalc = &followparent_recalc, +}; + +/* + * clkdev integration + */ + +static struct omap_clk omap_clks[] = { + /* non-ULPD clocks */ + CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX), + /* CK_GEN1 clocks */ + CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), + CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), + CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310), + CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX), + CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310), + CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310), + CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX), + /* CK_GEN2 clocks */ + CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310), + /* CK_GEN3 clocks */ + CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310), + CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX | CK_7XX), + CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX), + CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), + CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), + CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), + CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), + CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), + CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_7XX), + CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310), + /* ULPD clocks */ + CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310), + CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX), + CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310), + CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX), + CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), + CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX), + CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), + CLK(NULL, "mclk", &mclk_16xx, CK_16XX), + CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), + CLK(NULL, "bclk", &bclk_16xx, CK_16XX), + CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310), + CLK("mmci-omap.0", "fck", &mmc3_ck, CK_7XX), + CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX), + CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX), + /* Virtual clocks */ + CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310), + CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX), + CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX), + CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX), + CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX), + CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), + CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), + CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX), + CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310), + CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX), + CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310), + CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), + CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310), +}; + +/* + * init + */ + +static struct clk_functions omap1_clk_functions = { + .clk_enable = omap1_clk_enable, + .clk_disable = omap1_clk_disable, + .clk_round_rate = omap1_clk_round_rate, + .clk_set_rate = omap1_clk_set_rate, + .clk_disable_unused = omap1_clk_disable_unused, +}; + +int __init omap1_clk_init(void) +{ + struct omap_clk *c; + const struct omap_clock_config *info; + int crystal_type = 0; /* Default 12 MHz */ + u32 reg, cpu_mask; + +#ifdef CONFIG_DEBUG_LL + /* + * Resets some clocks that may be left on from bootloader, + * but leaves serial clocks on. + */ + omap_writel(0x3 << 29, MOD_CONF_CTRL_0); +#endif + + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ + reg = omap_readw(SOFT_REQ_REG) & (1 << 4); + omap_writew(reg, SOFT_REQ_REG); + if (!cpu_is_omap15xx()) + omap_writew(0, SOFT_REQ_REG2); + + clk_init(&omap1_clk_functions); + + /* By default all idlect1 clocks are allowed to idle */ + arm_idlect1_mask = ~0; + + for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) + clk_preinit(c->lk.clk); + + cpu_mask = 0; + if (cpu_is_omap16xx()) + cpu_mask |= CK_16XX; + if (cpu_is_omap1510()) + cpu_mask |= CK_1510; + if (cpu_is_omap7xx()) + cpu_mask |= CK_7XX; + if (cpu_is_omap310()) + cpu_mask |= CK_310; + + for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) + if (c->cpu & cpu_mask) { + clkdev_add(&c->lk); + clk_register(c->lk.clk); + } + + /* Pointers to these clocks are needed by code in clock.c */ + api_ck_p = clk_get(NULL, "api_ck"); + ck_dpll1_p = clk_get(NULL, "ck_dpll1"); + ck_ref_p = clk_get(NULL, "ck_ref"); + + info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); + if (info != NULL) { + if (!cpu_is_omap15xx()) + crystal_type = info->system_clock_type; + } + +#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) + ck_ref.rate = 13000000; +#elif defined(CONFIG_ARCH_OMAP16XX) + if (crystal_type == 2) + ck_ref.rate = 19200000; +#endif + + pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: " + "0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), + omap_readw(ARM_CKCTL)); + + /* We want to be in syncronous scalable mode */ + omap_writew(0x1000, ARM_SYSST); + +#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER + /* Use values set by bootloader. Determine PLL rate and recalculate + * dependent clocks as if kernel had changed PLL or divisors. + */ + { + unsigned pll_ctl_val = omap_readw(DPLL_CTL); + + ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ + if (pll_ctl_val & 0x10) { + /* PLL enabled, apply multiplier and divisor */ + if (pll_ctl_val & 0xf80) + ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; + ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; + } else { + /* PLL disabled, apply bypass divisor */ + switch (pll_ctl_val & 0xc) { + case 0: + break; + case 0x4: + ck_dpll1.rate /= 2; + break; + default: + ck_dpll1.rate /= 4; + break; + } + } + } +#else + /* Find the highest supported frequency and enable it */ + if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { + printk(KERN_ERR "System frequencies not set. Check your config.\n"); + /* Guess sane values (60MHz) */ + omap_writew(0x2290, DPLL_CTL); + omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); + ck_dpll1.rate = 60000000; + } +#endif + propagate_rate(&ck_dpll1); + /* Cache rates for clocks connected to ck_ref (not dpll1) */ + propagate_rate(&ck_ref); + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " + "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", + ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, + ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, + arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); + +#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE) + /* Select slicer output as OMAP input clock */ + omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, OMAP7XX_PCC_UPLD_CTRL); +#endif + + /* Amstrad Delta wants BCLK high when inactive */ + if (machine_is_ams_delta()) + omap_writel(omap_readl(ULPD_CLOCK_CTRL) | + (1 << SDW_MCLK_INV_BIT), + ULPD_CLOCK_CTRL); + + /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ + /* (on 730, bit 13 must not be cleared) */ + if (cpu_is_omap7xx()) + 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); + omap_writew(1, ARM_RSTCT2); + omap_writew(0x400, ARM_IDLECT1); + + /* + * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) + * of the ARM_IDLECT2 register must be set to zero. The power-on + * default value of this bit is one. + */ + omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ + + /* + * Only enable those clocks we will need, let the drivers + * enable other clocks as necessary + */ + clk_enable(&armper_ck.clk); + clk_enable(&armxor_ck.clk); + clk_enable(&armtim_ck.clk); /* This should be done by timer code */ + + if (cpu_is_omap15xx()) + clk_enable(&arm_gpio_ck); + + return 0; +} diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 23ded2d49600..a2d07aa75c9e 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/spi/spi.h> #include <mach/hardware.h> #include <asm/mach/map.h> @@ -23,6 +24,7 @@ #include <plat/mux.h> #include <mach/gpio.h> #include <plat/mmc.h> +#include <plat/omap7xx.h> /*-------------------------------------------------------------------------*/ @@ -196,6 +198,38 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, /*-------------------------------------------------------------------------*/ +/* OMAP7xx SPI support */ +#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE) + +struct platform_device omap_spi1 = { + .name = "omap1_spi100k", + .id = 1, +}; + +struct platform_device omap_spi2 = { + .name = "omap1_spi100k", + .id = 2, +}; + +static void omap_init_spi100k(void) +{ + omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff); + if (omap_spi1.dev.platform_data) + platform_device_register(&omap_spi1); + + omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff); + if (omap_spi2.dev.platform_data) + platform_device_register(&omap_spi2); +} + +#else +static inline void omap_init_spi100k(void) +{ +} +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_OMAP_STI) #define OMAP1_STI_BASE 0xfffea000 @@ -263,6 +297,7 @@ static int __init omap1_init_devices(void) omap_init_mbox(); omap_init_rtc(); + omap_init_spi100k(); omap_init_sti(); return 0; diff --git a/arch/arm/mach-omap1/i2c.c b/arch/arm/mach-omap1/i2c.c new file mode 100644 index 000000000000..1bf4735e27a6 --- /dev/null +++ b/arch/arm/mach-omap1/i2c.c @@ -0,0 +1,39 @@ +/* + * Helper module for board specific I2C bus registration + * + * Copyright (C) 2009 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <plat/i2c.h> +#include <plat/mux.h> +#include <plat/cpu.h> + +int __init omap_register_i2c_bus(int bus_id, u32 clkrate, + struct i2c_board_info const *info, + unsigned len) +{ + if (cpu_is_omap7xx()) { + omap_cfg_reg(I2C_7XX_SDA); + omap_cfg_reg(I2C_7XX_SCL); + } else { + omap_cfg_reg(I2C_SDA); + omap_cfg_reg(I2C_SCL); + } + + return omap_plat_register_i2c_bus(bus_id, clkrate, info, len); +} diff --git a/arch/arm/mach-omap1/include/mach/lcd_dma.h b/arch/arm/mach-omap1/include/mach/lcd_dma.h new file mode 100644 index 000000000000..d7a457bbcb7f --- /dev/null +++ b/arch/arm/mach-omap1/include/mach/lcd_dma.h @@ -0,0 +1,78 @@ +/* + * arch/arm/mach-omap1/include/mach/lcd_dma.h + * + * Extracted from arch/arm/plat-omap/include/plat/dma.h + * Copyright (C) 2003 Nokia Corporation + * Author: Juha Yrjölä <juha.yrjola@nokia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __MACH_OMAP1_LCD_DMA_H__ +#define __MACH_OMAP1_LCD_DMA_H__ + +/* Hardware registers for LCD DMA */ +#define OMAP1510_DMA_LCD_BASE (0xfffedb00) +#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00) +#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02) +#define OMAP1510_DMA_LCD_TOP_F1_U (OMAP1510_DMA_LCD_BASE + 0x04) +#define OMAP1510_DMA_LCD_BOT_F1_L (OMAP1510_DMA_LCD_BASE + 0x06) +#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08) + +#define OMAP1610_DMA_LCD_BASE (0xfffee300) +#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0) +#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2) +#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4) +#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8) +#define OMAP1610_DMA_LCD_TOP_B1_U (OMAP1610_DMA_LCD_BASE + 0xca) +#define OMAP1610_DMA_LCD_BOT_B1_L (OMAP1610_DMA_LCD_BASE + 0xcc) +#define OMAP1610_DMA_LCD_BOT_B1_U (OMAP1610_DMA_LCD_BASE + 0xce) +#define OMAP1610_DMA_LCD_TOP_B2_L (OMAP1610_DMA_LCD_BASE + 0xd0) +#define OMAP1610_DMA_LCD_TOP_B2_U (OMAP1610_DMA_LCD_BASE + 0xd2) +#define OMAP1610_DMA_LCD_BOT_B2_L (OMAP1610_DMA_LCD_BASE + 0xd4) +#define OMAP1610_DMA_LCD_BOT_B2_U (OMAP1610_DMA_LCD_BASE + 0xd6) +#define OMAP1610_DMA_LCD_SRC_EI_B1 (OMAP1610_DMA_LCD_BASE + 0xd8) +#define OMAP1610_DMA_LCD_SRC_FI_B1_L (OMAP1610_DMA_LCD_BASE + 0xda) +#define OMAP1610_DMA_LCD_SRC_EN_B1 (OMAP1610_DMA_LCD_BASE + 0xe0) +#define OMAP1610_DMA_LCD_SRC_FN_B1 (OMAP1610_DMA_LCD_BASE + 0xe4) +#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea) +#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4) + +/* LCD DMA block numbers */ +enum { + OMAP_LCD_DMA_B1_TOP, + OMAP_LCD_DMA_B1_BOTTOM, + OMAP_LCD_DMA_B2_TOP, + OMAP_LCD_DMA_B2_BOTTOM +}; + +/* LCD DMA functions */ +extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data), + void *data); +extern void omap_free_lcd_dma(void); +extern void omap_setup_lcd_dma(void); +extern void omap_enable_lcd_dma(void); +extern void omap_stop_lcd_dma(void); +extern void omap_set_lcd_dma_ext_controller(int external); +extern void omap_set_lcd_dma_single_transfer(int single); +extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, + int data_type); +extern void omap_set_lcd_dma_b1_rotation(int rotate); +extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres); +extern void omap_set_lcd_dma_b1_mirror(int mirror); +extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale); + +extern int omap_lcd_dma_running(void); + +#endif /* __MACH_OMAP1_LCD_DMA_H__ */ diff --git a/arch/arm/mach-omap1/include/mach/lcdc.h b/arch/arm/mach-omap1/include/mach/lcdc.h new file mode 100644 index 000000000000..89bd703adaf6 --- /dev/null +++ b/arch/arm/mach-omap1/include/mach/lcdc.h @@ -0,0 +1,57 @@ +/* + * arch/arm/mach-omap1/include/mach/lcdc.h + * + * Extracted from drivers/video/omap/lcdc.c + * Copyright (C) 2004 Nokia Corporation + * Author: Imre Deak <imre.deak@nokia.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __MACH_LCDC_H__ +#define __MACH_LCDC_H__ + +#define OMAP_LCDC_BASE 0xfffec000 +#define OMAP_LCDC_SIZE 256 +#define OMAP_LCDC_IRQ INT_LCD_CTRL + +#define OMAP_LCDC_CONTROL (OMAP_LCDC_BASE + 0x00) +#define OMAP_LCDC_TIMING0 (OMAP_LCDC_BASE + 0x04) +#define OMAP_LCDC_TIMING1 (OMAP_LCDC_BASE + 0x08) +#define OMAP_LCDC_TIMING2 (OMAP_LCDC_BASE + 0x0c) +#define OMAP_LCDC_STATUS (OMAP_LCDC_BASE + 0x10) +#define OMAP_LCDC_SUBPANEL (OMAP_LCDC_BASE + 0x14) +#define OMAP_LCDC_LINE_INT (OMAP_LCDC_BASE + 0x18) +#define OMAP_LCDC_DISPLAY_STATUS (OMAP_LCDC_BASE + 0x1c) + +#define OMAP_LCDC_STAT_DONE (1 << 0) +#define OMAP_LCDC_STAT_VSYNC (1 << 1) +#define OMAP_LCDC_STAT_SYNC_LOST (1 << 2) +#define OMAP_LCDC_STAT_ABC (1 << 3) +#define OMAP_LCDC_STAT_LINE_INT (1 << 4) +#define OMAP_LCDC_STAT_FUF (1 << 5) +#define OMAP_LCDC_STAT_LOADED_PALETTE (1 << 6) + +#define OMAP_LCDC_CTRL_LCD_EN (1 << 0) +#define OMAP_LCDC_CTRL_LCD_TFT (1 << 7) +#define OMAP_LCDC_CTRL_LINE_IRQ_CLR_SEL (1 << 10) + +#define OMAP_LCDC_IRQ_VSYNC (1 << 2) +#define OMAP_LCDC_IRQ_DONE (1 << 3) +#define OMAP_LCDC_IRQ_LOADED_PALETTE (1 << 4) +#define OMAP_LCDC_IRQ_LINE_NIRQ (1 << 5) +#define OMAP_LCDC_IRQ_LINE (1 << 6) +#define OMAP_LCDC_IRQ_MASK (((1 << 5) - 1) << 2) + +#endif /* __MACH_LCDC_H__ */ diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 2a6d68aa3489..d9b8d82530ae 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -18,7 +18,8 @@ #include <plat/mux.h> #include <plat/tc.h> -extern int omap1_clk_init(void); +#include "clock.h" + extern void omap_check_revision(void); extern void omap_sram_init(void); extern void omapfb_reserve_sdram(void); diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c new file mode 100644 index 000000000000..3be11af687bb --- /dev/null +++ b/arch/arm/mach-omap1/lcd_dma.c @@ -0,0 +1,448 @@ +/* + * linux/arch/arm/mach-omap1/lcd_dma.c + * + * Extracted from arch/arm/plat-omap/dma.c + * Copyright (C) 2003 - 2008 Nokia Corporation + * Author: Juha Yrjölä <juha.yrjola@nokia.com> + * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> + * Graphics DMA and LCD DMA graphics tranformations + * by Imre Deak <imre.deak@nokia.com> + * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. + * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com> + * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. + * + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Support functions for the OMAP internal DMA channels. + * + * 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/module.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/lcdc.h> +#include <plat/dma.h> + +int omap_lcd_dma_running(void) +{ + /* + * On OMAP1510, internal LCD controller will start the transfer + * when it gets enabled, so assume DMA running if LCD enabled. + */ + if (cpu_is_omap1510()) + if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN) + return 1; + + /* Check if LCD DMA is running */ + if (cpu_is_omap16xx()) + if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) + return 1; + + return 0; +} + +static struct lcd_dma_info { + spinlock_t lock; + int reserved; + void (*callback)(u16 status, void *data); + void *cb_data; + + int active; + unsigned long addr, size; + int rotate, data_type, xres, yres; + int vxres; + int mirror; + int xscale, yscale; + int ext_ctrl; + int src_port; + int single_transfer; +} lcd_dma; + +void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, + int data_type) +{ + lcd_dma.addr = addr; + lcd_dma.data_type = data_type; + lcd_dma.xres = fb_xres; + lcd_dma.yres = fb_yres; +} +EXPORT_SYMBOL(omap_set_lcd_dma_b1); + +void omap_set_lcd_dma_src_port(int port) +{ + lcd_dma.src_port = port; +} + +void omap_set_lcd_dma_ext_controller(int external) +{ + lcd_dma.ext_ctrl = external; +} +EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); + +void omap_set_lcd_dma_single_transfer(int single) +{ + lcd_dma.single_transfer = single; +} +EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); + +void omap_set_lcd_dma_b1_rotation(int rotate) +{ + if (cpu_is_omap1510()) { + printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n"); + BUG(); + return; + } + lcd_dma.rotate = rotate; +} +EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); + +void omap_set_lcd_dma_b1_mirror(int mirror) +{ + if (cpu_is_omap1510()) { + printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n"); + BUG(); + } + lcd_dma.mirror = mirror; +} +EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); + +void omap_set_lcd_dma_b1_vxres(unsigned long vxres) +{ + if (cpu_is_omap1510()) { + printk(KERN_ERR "DMA virtual resulotion is not supported " + "in 1510 mode\n"); + BUG(); + } + lcd_dma.vxres = vxres; +} +EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); + +void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) +{ + if (cpu_is_omap1510()) { + printk(KERN_ERR "DMA scale is not supported in 1510 mode\n"); + BUG(); + } + lcd_dma.xscale = xscale; + lcd_dma.yscale = yscale; +} +EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); + +static void set_b1_regs(void) +{ + unsigned long top, bottom; + int es; + u16 w; + unsigned long en, fn; + long ei, fi; + unsigned long vxres; + unsigned int xscale, yscale; + + switch (lcd_dma.data_type) { + case OMAP_DMA_DATA_TYPE_S8: + es = 1; + break; + case OMAP_DMA_DATA_TYPE_S16: + es = 2; + break; + case OMAP_DMA_DATA_TYPE_S32: + es = 4; + break; + default: + BUG(); + return; + } + + vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres; + xscale = lcd_dma.xscale ? lcd_dma.xscale : 1; + yscale = lcd_dma.yscale ? lcd_dma.yscale : 1; + BUG_ON(vxres < lcd_dma.xres); + +#define PIXADDR(x, y) (lcd_dma.addr + \ + ((y) * vxres * yscale + (x) * xscale) * es) +#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1) + + switch (lcd_dma.rotate) { + case 0: + if (!lcd_dma.mirror) { + top = PIXADDR(0, 0); + bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + /* 1510 DMA requires the bottom address to be 2 more + * than the actual last memory access location. */ + if (cpu_is_omap1510() && + lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) + bottom += 2; + ei = PIXSTEP(0, 0, 1, 0); + fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1); + } else { + top = PIXADDR(lcd_dma.xres - 1, 0); + bottom = PIXADDR(0, lcd_dma.yres - 1); + ei = PIXSTEP(1, 0, 0, 0); + fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1); + } + en = lcd_dma.xres; + fn = lcd_dma.yres; + break; + case 90: + if (!lcd_dma.mirror) { + top = PIXADDR(0, lcd_dma.yres - 1); + bottom = PIXADDR(lcd_dma.xres - 1, 0); + ei = PIXSTEP(0, 1, 0, 0); + fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1); + } else { + top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + bottom = PIXADDR(0, 0); + ei = PIXSTEP(0, 1, 0, 0); + fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1); + } + en = lcd_dma.yres; + fn = lcd_dma.xres; + break; + case 180: + if (!lcd_dma.mirror) { + top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + bottom = PIXADDR(0, 0); + ei = PIXSTEP(1, 0, 0, 0); + fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0); + } else { + top = PIXADDR(0, lcd_dma.yres - 1); + bottom = PIXADDR(lcd_dma.xres - 1, 0); + ei = PIXSTEP(0, 0, 1, 0); + fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0); + } + en = lcd_dma.xres; + fn = lcd_dma.yres; + break; + case 270: + if (!lcd_dma.mirror) { + top = PIXADDR(lcd_dma.xres - 1, 0); + bottom = PIXADDR(0, lcd_dma.yres - 1); + ei = PIXSTEP(0, 0, 0, 1); + fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0); + } else { + top = PIXADDR(0, 0); + bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + ei = PIXSTEP(0, 0, 0, 1); + fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0); + } + en = lcd_dma.yres; + fn = lcd_dma.xres; + break; + default: + BUG(); + return; /* Suppress warning about uninitialized vars */ + } + + if (cpu_is_omap1510()) { + omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U); + omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L); + omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U); + omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L); + + return; + } + + /* 1610 regs */ + omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U); + omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L); + omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U); + omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L); + + omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1); + omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1); + + w = omap_readw(OMAP1610_DMA_LCD_CSDP); + w &= ~0x03; + w |= lcd_dma.data_type; + omap_writew(w, OMAP1610_DMA_LCD_CSDP); + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + /* Always set the source port as SDRAM for now*/ + w &= ~(0x03 << 6); + if (lcd_dma.callback != NULL) + w |= 1 << 1; /* Block interrupt enable */ + else + w &= ~(1 << 1); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + + if (!(lcd_dma.rotate || lcd_dma.mirror || + lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale)) + return; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + /* Set the double-indexed addressing mode */ + w |= (0x03 << 12); + omap_writew(w, OMAP1610_DMA_LCD_CCR); + + omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1); + omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U); + omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); +} + +static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id) +{ + u16 w; + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + if (unlikely(!(w & (1 << 3)))) { + printk(KERN_WARNING "Spurious LCD DMA IRQ\n"); + return IRQ_NONE; + } + /* Ack the IRQ */ + w |= (1 << 3); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + lcd_dma.active = 0; + if (lcd_dma.callback != NULL) + lcd_dma.callback(w, lcd_dma.cb_data); + + return IRQ_HANDLED; +} + +int omap_request_lcd_dma(void (*callback)(u16 status, void *data), + void *data) +{ + spin_lock_irq(&lcd_dma.lock); + if (lcd_dma.reserved) { + spin_unlock_irq(&lcd_dma.lock); + printk(KERN_ERR "LCD DMA channel already reserved\n"); + BUG(); + return -EBUSY; + } + lcd_dma.reserved = 1; + spin_unlock_irq(&lcd_dma.lock); + lcd_dma.callback = callback; + lcd_dma.cb_data = data; + lcd_dma.active = 0; + lcd_dma.single_transfer = 0; + lcd_dma.rotate = 0; + lcd_dma.vxres = 0; + lcd_dma.mirror = 0; + lcd_dma.xscale = 0; + lcd_dma.yscale = 0; + lcd_dma.ext_ctrl = 0; + lcd_dma.src_port = 0; + + return 0; +} +EXPORT_SYMBOL(omap_request_lcd_dma); + +void omap_free_lcd_dma(void) +{ + spin_lock(&lcd_dma.lock); + if (!lcd_dma.reserved) { + spin_unlock(&lcd_dma.lock); + printk(KERN_ERR "LCD DMA is not reserved\n"); + BUG(); + return; + } + if (!cpu_is_omap1510()) + omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, + OMAP1610_DMA_LCD_CCR); + lcd_dma.reserved = 0; + spin_unlock(&lcd_dma.lock); +} +EXPORT_SYMBOL(omap_free_lcd_dma); + +void omap_enable_lcd_dma(void) +{ + u16 w; + + /* + * Set the Enable bit only if an external controller is + * connected. Otherwise the OMAP internal controller will + * start the transfer when it gets enabled. + */ + if (cpu_is_omap1510() || !lcd_dma.ext_ctrl) + return; + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w |= 1 << 8; + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + + lcd_dma.active = 1; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + w |= 1 << 7; + omap_writew(w, OMAP1610_DMA_LCD_CCR); +} +EXPORT_SYMBOL(omap_enable_lcd_dma); + +void omap_setup_lcd_dma(void) +{ + BUG_ON(lcd_dma.active); + if (!cpu_is_omap1510()) { + /* Set some reasonable defaults */ + omap_writew(0x5440, OMAP1610_DMA_LCD_CCR); + omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP); + omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL); + } + set_b1_regs(); + if (!cpu_is_omap1510()) { + u16 w; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + /* + * If DMA was already active set the end_prog bit to have + * the programmed register set loaded into the active + * register set. + */ + w |= 1 << 11; /* End_prog */ + if (!lcd_dma.single_transfer) + w |= (3 << 8); /* Auto_init, repeat */ + omap_writew(w, OMAP1610_DMA_LCD_CCR); + } +} +EXPORT_SYMBOL(omap_setup_lcd_dma); + +void omap_stop_lcd_dma(void) +{ + u16 w; + + lcd_dma.active = 0; + if (cpu_is_omap1510() || !lcd_dma.ext_ctrl) + return; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + w &= ~(1 << 7); + omap_writew(w, OMAP1610_DMA_LCD_CCR); + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w &= ~(1 << 8); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); +} +EXPORT_SYMBOL(omap_stop_lcd_dma); + +static int __init omap_init_lcd_dma(void) +{ + int r; + + if (cpu_is_omap16xx()) { + u16 w; + + /* this would prevent OMAP sleep */ + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w &= ~(1 << 8); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + } + + spin_lock_init(&lcd_dma.lock); + + r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, + "LCD DMA", NULL); + if (r != 0) + printk(KERN_ERR "unable to request IRQ for LCD DMA " + "(error %d)\n", r); + + return r; +} + +arch_initcall(omap_init_lcd_dma); + diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 785371e982fc..84341377232d 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -50,12 +50,26 @@ MUX_CFG_7XX("E3_7XX_KBC4", 13, 25, 0, 24, 1, 0) MUX_CFG_7XX("AA17_7XX_USB_DM", 2, 21, 0, 20, 0, 0) MUX_CFG_7XX("W16_7XX_USB_PU_EN", 2, 25, 0, 24, 0, 0) -MUX_CFG_7XX("W17_7XX_USB_VBUSI", 2, 29, 0, 28, 0, 0) +MUX_CFG_7XX("W17_7XX_USB_VBUSI", 2, 29, 6, 28, 1, 0) +MUX_CFG_7XX("W18_7XX_USB_DMCK_OUT",3, 3, 1, 2, 0, 0) +MUX_CFG_7XX("W19_7XX_USB_DCRST", 3, 7, 1, 6, 0, 0) /* MMC Pins */ MUX_CFG_7XX("MMC_7XX_CMD", 2, 9, 0, 8, 1, 0) MUX_CFG_7XX("MMC_7XX_CLK", 2, 13, 0, 12, 1, 0) MUX_CFG_7XX("MMC_7XX_DAT0", 2, 17, 0, 16, 1, 0) + +/* I2C interface */ +MUX_CFG_7XX("I2C_7XX_SCL", 5, 1, 0, 0, 1, 0) +MUX_CFG_7XX("I2C_7XX_SDA", 5, 5, 0, 0, 1, 0) + +/* SPI pins */ +MUX_CFG_7XX("SPI_7XX_1", 6, 5, 4, 4, 1, 0) +MUX_CFG_7XX("SPI_7XX_2", 6, 9, 4, 8, 1, 0) +MUX_CFG_7XX("SPI_7XX_3", 6, 13, 4, 12, 1, 0) +MUX_CFG_7XX("SPI_7XX_4", 6, 17, 4, 16, 1, 0) +MUX_CFG_7XX("SPI_7XX_5", 8, 25, 0, 24, 0, 0) +MUX_CFG_7XX("SPI_7XX_6", 9, 5, 0, 4, 0, 0) }; #define OMAP7XX_PINS_SZ ARRAY_SIZE(omap7xx_pins) #else diff --git a/arch/arm/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h new file mode 100644 index 000000000000..07074d79adce --- /dev/null +++ b/arch/arm/mach-omap1/opp.h @@ -0,0 +1,28 @@ +/* + * linux/arch/arm/mach-omap1/opp.h + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP1_OPP_H +#define __ARCH_ARM_MACH_OMAP1_OPP_H + +#include <linux/types.h> + +struct mpu_rate { + unsigned long rate; + unsigned long xtal; + unsigned long pll_rate; + __u16 ckctl_val; + __u16 dpllctl_val; +}; + +extern struct mpu_rate omap1_rate_table[]; + +#endif diff --git a/arch/arm/mach-omap1/opp_data.c b/arch/arm/mach-omap1/opp_data.c new file mode 100644 index 000000000000..75a546514994 --- /dev/null +++ b/arch/arm/mach-omap1/opp_data.c @@ -0,0 +1,59 @@ +/* + * linux/arch/arm/mach-omap1/opp_data.c + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "opp.h" + +/*------------------------------------------------------------------------- + * Omap1 MPU rate table + *-------------------------------------------------------------------------*/ +struct mpu_rate omap1_rate_table[] = { + /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL + * NOTE: Comment order here is different from bits in CKCTL value: + * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv + */ +#if defined(CONFIG_OMAP_ARM_216MHZ) + { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_195MHZ) + { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_192MHZ) + { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ + { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ + { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ + { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ + { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_182MHZ) + { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_168MHZ) + { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_150MHZ) + { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ +#endif +#if defined(CONFIG_OMAP_ARM_120MHZ) + { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ +#endif +#if defined(CONFIG_OMAP_ARM_96MHZ) + { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ +#endif +#if defined(CONFIG_OMAP_ARM_60MHZ) + { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ +#endif +#if defined(CONFIG_OMAP_ARM_30MHZ) + { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ +#endif + { 0, 0, 0, 0, 0 }, +}; + |