diff options
Diffstat (limited to 'arch/arm/mach-gemini')
22 files changed, 1390 insertions, 0 deletions
diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig new file mode 100644 index 000000000000..515b75cf2e8b --- /dev/null +++ b/arch/arm/mach-gemini/Kconfig | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | if ARCH_GEMINI | ||
| 2 | |||
| 3 | menu "Cortina Systems Gemini Implementations" | ||
| 4 | |||
| 5 | config MACH_RUT100 | ||
| 6 | bool "Teltonika RUT100" | ||
| 7 | select GEMINI_MEM_SWAP | ||
| 8 | help | ||
| 9 | Say Y here if you intend to run this kernel on a | ||
| 10 | Teltonika 3G Router RUT100. | ||
| 11 | |||
| 12 | endmenu | ||
| 13 | |||
| 14 | config GEMINI_MEM_SWAP | ||
| 15 | bool "Gemini memory is swapped" | ||
| 16 | help | ||
| 17 | Say Y here if Gemini memory is swapped by bootloader. | ||
| 18 | |||
| 19 | endif | ||
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile new file mode 100644 index 000000000000..719505b81821 --- /dev/null +++ b/arch/arm/mach-gemini/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the linux kernel. | ||
| 3 | # | ||
| 4 | |||
| 5 | # Object file lists. | ||
| 6 | |||
| 7 | obj-y := irq.o mm.o time.o devices.o gpio.o | ||
| 8 | |||
| 9 | # Board-specific support | ||
| 10 | obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o | ||
diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot new file mode 100644 index 000000000000..22a52c228d93 --- /dev/null +++ b/arch/arm/mach-gemini/Makefile.boot | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | ifeq ($(CONFIG_GEMINI_MEM_SWAP),y) | ||
| 2 | zreladdr-y := 0x00008000 | ||
| 3 | params_phys-y := 0x00000100 | ||
| 4 | initrd_phys-y := 0x00800000 | ||
| 5 | else | ||
| 6 | zreladdr-y := 0x10008000 | ||
| 7 | params_phys-y := 0x10000100 | ||
| 8 | initrd_phys-y := 0x10800000 | ||
| 9 | endif | ||
diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c new file mode 100644 index 000000000000..e0de968e32a6 --- /dev/null +++ b/arch/arm/mach-gemini/board-rut1xx.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* | ||
| 2 | * Support for Teltonika RUT1xx | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/leds.h> | ||
| 15 | #include <linux/input.h> | ||
| 16 | #include <linux/gpio_keys.h> | ||
| 17 | |||
| 18 | #include <asm/mach-types.h> | ||
| 19 | #include <asm/mach/arch.h> | ||
| 20 | #include <asm/mach/time.h> | ||
| 21 | |||
| 22 | #include "common.h" | ||
| 23 | |||
| 24 | static struct gpio_keys_button rut1xx_keys[] = { | ||
| 25 | { | ||
| 26 | .code = KEY_SETUP, | ||
| 27 | .gpio = 60, | ||
| 28 | .active_low = 1, | ||
| 29 | .desc = "Reset to defaults", | ||
| 30 | .type = EV_KEY, | ||
| 31 | }, | ||
| 32 | }; | ||
| 33 | |||
| 34 | static struct gpio_keys_platform_data rut1xx_keys_data = { | ||
| 35 | .buttons = rut1xx_keys, | ||
| 36 | .nbuttons = ARRAY_SIZE(rut1xx_keys), | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct platform_device rut1xx_keys_device = { | ||
| 40 | .name = "gpio-keys", | ||
| 41 | .id = -1, | ||
| 42 | .dev = { | ||
| 43 | .platform_data = &rut1xx_keys_data, | ||
| 44 | }, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static struct gpio_led rut100_leds[] = { | ||
| 48 | { | ||
| 49 | .name = "Power", | ||
| 50 | .default_trigger = "heartbeat", | ||
| 51 | .gpio = 17, | ||
| 52 | }, | ||
| 53 | { | ||
| 54 | .name = "GSM", | ||
| 55 | .default_trigger = "default-on", | ||
| 56 | .gpio = 7, | ||
| 57 | .active_low = 1, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct gpio_led_platform_data rut100_leds_data = { | ||
| 62 | .num_leds = ARRAY_SIZE(rut100_leds), | ||
| 63 | .leds = rut100_leds, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct platform_device rut1xx_leds = { | ||
| 67 | .name = "leds-gpio", | ||
| 68 | .id = -1, | ||
| 69 | .dev = { | ||
| 70 | .platform_data = &rut100_leds_data, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static struct sys_timer rut1xx_timer = { | ||
| 75 | .init = gemini_timer_init, | ||
| 76 | }; | ||
| 77 | |||
| 78 | static void __init rut1xx_init(void) | ||
| 79 | { | ||
| 80 | gemini_gpio_init(); | ||
| 81 | platform_register_uart(); | ||
| 82 | platform_register_pflash(SZ_8M, NULL, 0); | ||
| 83 | platform_device_register(&rut1xx_leds); | ||
| 84 | platform_device_register(&rut1xx_keys_device); | ||
| 85 | } | ||
| 86 | |||
| 87 | MACHINE_START(RUT100, "Teltonika RUT100") | ||
| 88 | .phys_io = 0x7fffc000, | ||
| 89 | .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, | ||
| 90 | .boot_params = 0x100, | ||
| 91 | .map_io = gemini_map_io, | ||
| 92 | .init_irq = gemini_init_irq, | ||
| 93 | .timer = &rut1xx_timer, | ||
| 94 | .init_machine = rut1xx_init, | ||
| 95 | MACHINE_END | ||
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h new file mode 100644 index 000000000000..9392834a214f --- /dev/null +++ b/arch/arm/mach-gemini/common.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * Common Gemini architecture functions | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __GEMINI_COMMON_H__ | ||
| 13 | #define __GEMINI_COMMON_H__ | ||
| 14 | |||
| 15 | struct mtd_partition; | ||
| 16 | |||
| 17 | extern void gemini_map_io(void); | ||
| 18 | extern void gemini_init_irq(void); | ||
| 19 | extern void gemini_timer_init(void); | ||
| 20 | extern void gemini_gpio_init(void); | ||
| 21 | |||
| 22 | /* Common platform devices registration functions */ | ||
| 23 | extern int platform_register_uart(void); | ||
| 24 | extern int platform_register_pflash(unsigned int size, | ||
| 25 | struct mtd_partition *parts, | ||
| 26 | unsigned int nr_parts); | ||
| 27 | |||
| 28 | #endif /* __GEMINI_COMMON_H__ */ | ||
diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c new file mode 100644 index 000000000000..6b525253d027 --- /dev/null +++ b/arch/arm/mach-gemini/devices.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * Common devices definition for Gemini | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/io.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/serial_8250.h> | ||
| 15 | #include <linux/mtd/physmap.h> | ||
| 16 | |||
| 17 | #include <mach/irqs.h> | ||
| 18 | #include <mach/hardware.h> | ||
| 19 | #include <mach/global_reg.h> | ||
| 20 | |||
| 21 | static struct plat_serial8250_port serial_platform_data[] = { | ||
| 22 | { | ||
| 23 | .membase = (void *)IO_ADDRESS(GEMINI_UART_BASE), | ||
| 24 | .mapbase = GEMINI_UART_BASE, | ||
| 25 | .irq = IRQ_UART, | ||
| 26 | .uartclk = UART_CLK, | ||
| 27 | .regshift = 2, | ||
| 28 | .iotype = UPIO_MEM, | ||
| 29 | .type = PORT_16550A, | ||
| 30 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE, | ||
| 31 | }, | ||
| 32 | {}, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static struct platform_device serial_device = { | ||
| 36 | .name = "serial8250", | ||
| 37 | .id = PLAT8250_DEV_PLATFORM, | ||
| 38 | .dev = { | ||
| 39 | .platform_data = serial_platform_data, | ||
| 40 | }, | ||
| 41 | }; | ||
| 42 | |||
| 43 | int platform_register_uart(void) | ||
| 44 | { | ||
| 45 | return platform_device_register(&serial_device); | ||
| 46 | } | ||
| 47 | |||
| 48 | static struct resource flash_resource = { | ||
| 49 | .start = GEMINI_FLASH_BASE, | ||
| 50 | .flags = IORESOURCE_MEM, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static struct physmap_flash_data pflash_platform_data = {}; | ||
| 54 | |||
| 55 | static struct platform_device pflash_device = { | ||
| 56 | .name = "physmap-flash", | ||
| 57 | .id = 0, | ||
| 58 | .dev = { | ||
| 59 | .platform_data = &pflash_platform_data, | ||
| 60 | }, | ||
| 61 | .resource = &flash_resource, | ||
| 62 | .num_resources = 1, | ||
| 63 | }; | ||
| 64 | |||
| 65 | int platform_register_pflash(unsigned int size, struct mtd_partition *parts, | ||
| 66 | unsigned int nr_parts) | ||
| 67 | { | ||
| 68 | unsigned int reg; | ||
| 69 | |||
| 70 | reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS); | ||
| 71 | |||
| 72 | if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL) | ||
| 73 | return -ENXIO; | ||
| 74 | |||
| 75 | if (reg & FLASH_WIDTH_16BIT) | ||
| 76 | pflash_platform_data.width = 2; | ||
| 77 | else | ||
| 78 | pflash_platform_data.width = 1; | ||
| 79 | |||
| 80 | /* enable parallel flash pins and disable others */ | ||
| 81 | reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); | ||
| 82 | reg &= ~PFLASH_PADS_DISABLE; | ||
| 83 | reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE; | ||
| 84 | __raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); | ||
| 85 | |||
| 86 | flash_resource.end = flash_resource.start + size - 1; | ||
| 87 | |||
| 88 | pflash_platform_data.parts = parts; | ||
| 89 | pflash_platform_data.nr_parts = nr_parts; | ||
| 90 | |||
| 91 | return platform_device_register(&pflash_device); | ||
| 92 | } | ||
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c new file mode 100644 index 000000000000..e7263854bc7b --- /dev/null +++ b/arch/arm/mach-gemini/gpio.c | |||
| @@ -0,0 +1,232 @@ | |||
| 1 | /* | ||
| 2 | * Gemini gpiochip and interrupt routines | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * Based on plat-mxc/gpio.c: | ||
| 7 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
| 8 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | |||
| 22 | #include <mach/hardware.h> | ||
| 23 | #include <mach/irqs.h> | ||
| 24 | |||
| 25 | #define GPIO_BASE(x) IO_ADDRESS(GEMINI_GPIO_BASE(x)) | ||
| 26 | |||
| 27 | /* GPIO registers definition */ | ||
| 28 | #define GPIO_DATA_OUT 0x0 | ||
| 29 | #define GPIO_DATA_IN 0x4 | ||
| 30 | #define GPIO_DIR 0x8 | ||
| 31 | #define GPIO_DATA_SET 0x10 | ||
| 32 | #define GPIO_DATA_CLR 0x14 | ||
| 33 | #define GPIO_PULL_EN 0x18 | ||
| 34 | #define GPIO_PULL_TYPE 0x1C | ||
| 35 | #define GPIO_INT_EN 0x20 | ||
| 36 | #define GPIO_INT_STAT 0x24 | ||
| 37 | #define GPIO_INT_MASK 0x2C | ||
| 38 | #define GPIO_INT_CLR 0x30 | ||
| 39 | #define GPIO_INT_TYPE 0x34 | ||
| 40 | #define GPIO_INT_BOTH_EDGE 0x38 | ||
| 41 | #define GPIO_INT_LEVEL 0x3C | ||
| 42 | #define GPIO_DEBOUNCE_EN 0x40 | ||
| 43 | #define GPIO_DEBOUNCE_PRESCALE 0x44 | ||
| 44 | |||
| 45 | #define GPIO_PORT_NUM 3 | ||
| 46 | |||
| 47 | static void _set_gpio_irqenable(unsigned int base, unsigned int index, | ||
| 48 | int enable) | ||
| 49 | { | ||
| 50 | unsigned int reg; | ||
| 51 | |||
| 52 | reg = __raw_readl(base + GPIO_INT_EN); | ||
| 53 | reg = (reg & (~(1 << index))) | (!!enable << index); | ||
| 54 | __raw_writel(reg, base + GPIO_INT_EN); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void gpio_ack_irq(unsigned int irq) | ||
| 58 | { | ||
| 59 | unsigned int gpio = irq_to_gpio(irq); | ||
| 60 | unsigned int base = GPIO_BASE(gpio / 32); | ||
| 61 | |||
| 62 | __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void gpio_mask_irq(unsigned int irq) | ||
| 66 | { | ||
| 67 | unsigned int gpio = irq_to_gpio(irq); | ||
| 68 | unsigned int base = GPIO_BASE(gpio / 32); | ||
| 69 | |||
| 70 | _set_gpio_irqenable(base, gpio % 32, 0); | ||
| 71 | } | ||
| 72 | |||
| 73 | static void gpio_unmask_irq(unsigned int irq) | ||
| 74 | { | ||
| 75 | unsigned int gpio = irq_to_gpio(irq); | ||
| 76 | unsigned int base = GPIO_BASE(gpio / 32); | ||
| 77 | |||
| 78 | _set_gpio_irqenable(base, gpio % 32, 1); | ||
| 79 | } | ||
| 80 | |||
| 81 | static int gpio_set_irq_type(unsigned int irq, unsigned int type) | ||
| 82 | { | ||
| 83 | unsigned int gpio = irq_to_gpio(irq); | ||
| 84 | unsigned int gpio_mask = 1 << (gpio % 32); | ||
| 85 | unsigned int base = GPIO_BASE(gpio / 32); | ||
| 86 | unsigned int reg_both, reg_level, reg_type; | ||
| 87 | |||
| 88 | reg_type = __raw_readl(base + GPIO_INT_TYPE); | ||
| 89 | reg_level = __raw_readl(base + GPIO_INT_BOTH_EDGE); | ||
| 90 | reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE); | ||
| 91 | |||
| 92 | switch (type) { | ||
| 93 | case IRQ_TYPE_EDGE_BOTH: | ||
| 94 | reg_type &= ~gpio_mask; | ||
| 95 | reg_both |= gpio_mask; | ||
| 96 | break; | ||
| 97 | case IRQ_TYPE_EDGE_RISING: | ||
| 98 | reg_type &= ~gpio_mask; | ||
| 99 | reg_both &= ~gpio_mask; | ||
| 100 | reg_level &= ~gpio_mask; | ||
| 101 | break; | ||
| 102 | case IRQ_TYPE_EDGE_FALLING: | ||
| 103 | reg_type &= ~gpio_mask; | ||
| 104 | reg_both &= ~gpio_mask; | ||
| 105 | reg_level |= gpio_mask; | ||
| 106 | break; | ||
| 107 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 108 | reg_type |= gpio_mask; | ||
| 109 | reg_level &= ~gpio_mask; | ||
| 110 | break; | ||
| 111 | case IRQ_TYPE_LEVEL_LOW: | ||
| 112 | reg_type |= gpio_mask; | ||
| 113 | reg_level |= gpio_mask; | ||
| 114 | break; | ||
| 115 | default: | ||
| 116 | return -EINVAL; | ||
| 117 | } | ||
| 118 | |||
| 119 | __raw_writel(reg_type, base + GPIO_INT_TYPE); | ||
| 120 | __raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE); | ||
| 121 | __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); | ||
| 122 | |||
| 123 | gpio_ack_irq(irq); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 129 | { | ||
| 130 | unsigned int gpio_irq_no, irq_stat; | ||
| 131 | unsigned int port = (unsigned int)get_irq_data(irq); | ||
| 132 | |||
| 133 | irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); | ||
| 134 | |||
| 135 | gpio_irq_no = GPIO_IRQ_BASE + port * 32; | ||
| 136 | for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { | ||
| 137 | |||
| 138 | if ((irq_stat & 1) == 0) | ||
| 139 | continue; | ||
| 140 | |||
| 141 | BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); | ||
| 142 | irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, | ||
| 143 | &irq_desc[gpio_irq_no]); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static struct irq_chip gpio_irq_chip = { | ||
| 148 | .name = "GPIO", | ||
| 149 | .ack = gpio_ack_irq, | ||
| 150 | .mask = gpio_mask_irq, | ||
| 151 | .unmask = gpio_unmask_irq, | ||
| 152 | .set_type = gpio_set_irq_type, | ||
| 153 | }; | ||
| 154 | |||
| 155 | static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | ||
| 156 | int dir) | ||
| 157 | { | ||
| 158 | unsigned int base = GPIO_BASE(offset / 32); | ||
| 159 | unsigned int reg; | ||
| 160 | |||
| 161 | reg = __raw_readl(base + GPIO_DIR); | ||
| 162 | if (dir) | ||
| 163 | reg |= 1 << (offset % 32); | ||
| 164 | else | ||
| 165 | reg &= ~(1 << (offset % 32)); | ||
| 166 | __raw_writel(reg, base + GPIO_DIR); | ||
| 167 | } | ||
| 168 | |||
| 169 | static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 170 | { | ||
| 171 | unsigned int base = GPIO_BASE(offset / 32); | ||
| 172 | |||
| 173 | if (value) | ||
| 174 | __raw_writel(1 << (offset % 32), base + GPIO_DATA_SET); | ||
| 175 | else | ||
| 176 | __raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR); | ||
| 177 | } | ||
| 178 | |||
| 179 | static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 180 | { | ||
| 181 | unsigned int base = GPIO_BASE(offset / 32); | ||
| 182 | |||
| 183 | return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1; | ||
| 184 | } | ||
| 185 | |||
| 186 | static int gemini_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 187 | { | ||
| 188 | _set_gpio_direction(chip, offset, 0); | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static int gemini_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 193 | int value) | ||
| 194 | { | ||
| 195 | _set_gpio_direction(chip, offset, 1); | ||
| 196 | gemini_gpio_set(chip, offset, value); | ||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static struct gpio_chip gemini_gpio_chip = { | ||
| 201 | .label = "Gemini", | ||
| 202 | .direction_input = gemini_gpio_direction_input, | ||
| 203 | .get = gemini_gpio_get, | ||
| 204 | .direction_output = gemini_gpio_direction_output, | ||
| 205 | .set = gemini_gpio_set, | ||
| 206 | .base = 0, | ||
| 207 | .ngpio = GPIO_PORT_NUM * 32, | ||
| 208 | }; | ||
| 209 | |||
| 210 | void __init gemini_gpio_init(void) | ||
| 211 | { | ||
| 212 | int i, j; | ||
| 213 | |||
| 214 | for (i = 0; i < GPIO_PORT_NUM; i++) { | ||
| 215 | /* disable, unmask and clear all interrupts */ | ||
| 216 | __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN); | ||
| 217 | __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK); | ||
| 218 | __raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR); | ||
| 219 | |||
| 220 | for (j = GPIO_IRQ_BASE + i * 32; | ||
| 221 | j < GPIO_IRQ_BASE + (i + 1) * 32; j++) { | ||
| 222 | set_irq_chip(j, &gpio_irq_chip); | ||
| 223 | set_irq_handler(j, handle_edge_irq); | ||
| 224 | set_irq_flags(j, IRQF_VALID); | ||
| 225 | } | ||
| 226 | |||
| 227 | set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler); | ||
| 228 | set_irq_data(IRQ_GPIO(i), (void *)i); | ||
| 229 | } | ||
| 230 | |||
| 231 | BUG_ON(gpiochip_add(&gemini_gpio_chip)); | ||
| 232 | } | ||
diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S new file mode 100644 index 000000000000..d04a6eaeae14 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/debug-macro.S | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * Debugging macro include header | ||
| 3 | * | ||
| 4 | * Copyright (C) 1994-1999 Russell King | ||
| 5 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 6 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | #include <mach/hardware.h> | ||
| 13 | |||
| 14 | .macro addruart,rx | ||
| 15 | mrc p15, 0, \rx, c1, c0 | ||
| 16 | tst \rx, #1 @ MMU enabled? | ||
| 17 | ldreq \rx, =GEMINI_UART_BASE @ physical | ||
| 18 | ldrne \rx, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual | ||
| 19 | .endm | ||
| 20 | |||
| 21 | #define UART_SHIFT 2 | ||
| 22 | #define FLOW_CONTROL | ||
| 23 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S new file mode 100644 index 000000000000..1624f91a2b8b --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/entry-macro.S | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * Low-level IRQ helper macros for Gemini platform. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | #include <mach/hardware.h> | ||
| 12 | |||
| 13 | #define IRQ_STATUS 0x14 | ||
| 14 | |||
| 15 | .macro disable_fiq | ||
| 16 | .endm | ||
| 17 | |||
| 18 | .macro get_irqnr_preamble, base, tmp | ||
| 19 | .endm | ||
| 20 | |||
| 21 | .macro arch_ret_to_user, tmp1, tmp2 | ||
| 22 | .endm | ||
| 23 | |||
| 24 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 25 | ldr \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS) | ||
| 26 | ldr \irqnr, [\irqstat] | ||
| 27 | cmp \irqnr, #0 | ||
| 28 | beq 2313f | ||
| 29 | mov \tmp, \irqnr | ||
| 30 | mov \irqnr, #0 | ||
| 31 | 2312: | ||
| 32 | tst \tmp, #1 | ||
| 33 | bne 2313f | ||
| 34 | add \irqnr, \irqnr, #1 | ||
| 35 | mov \tmp, \tmp, lsr #1 | ||
| 36 | cmp \irqnr, #31 | ||
| 37 | bcc 2312b | ||
| 38 | 2313: | ||
| 39 | .endm | ||
diff --git a/arch/arm/mach-gemini/include/mach/global_reg.h b/arch/arm/mach-gemini/include/mach/global_reg.h new file mode 100644 index 000000000000..de7ff7e849fc --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/global_reg.h | |||
| @@ -0,0 +1,278 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the hardware definitions for Gemini. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #ifndef __MACH_GLOBAL_REG_H | ||
| 12 | #define __MACH_GLOBAL_REG_H | ||
| 13 | |||
| 14 | /* Global Word ID Register*/ | ||
| 15 | #define GLOBAL_ID 0x00 | ||
| 16 | |||
| 17 | #define CHIP_ID(reg) ((reg) >> 8) | ||
| 18 | #define CHIP_REVISION(reg) ((reg) & 0xFF) | ||
| 19 | |||
| 20 | /* Global Status Register */ | ||
| 21 | #define GLOBAL_STATUS 0x04 | ||
| 22 | |||
| 23 | #define CPU_BIG_ENDIAN (1 << 31) | ||
| 24 | #define PLL_OSC_30M (1 << 30) /* else 60MHz */ | ||
| 25 | |||
| 26 | #define OPERATION_MODE_MASK (0xF << 26) | ||
| 27 | #define OPM_IDDQ (0xF << 26) | ||
| 28 | #define OPM_NAND (0xE << 26) | ||
| 29 | #define OPM_RING (0xD << 26) | ||
| 30 | #define OPM_DIRECT_BOOT (0xC << 26) | ||
| 31 | #define OPM_USB1_PHY_TEST (0xB << 26) | ||
| 32 | #define OPM_USB0_PHY_TEST (0xA << 26) | ||
| 33 | #define OPM_SATA1_PHY_TEST (0x9 << 26) | ||
| 34 | #define OPM_SATA0_PHY_TEST (0x8 << 26) | ||
| 35 | #define OPM_ICE_ARM (0x7 << 26) | ||
| 36 | #define OPM_ICE_FARADAY (0x6 << 26) | ||
| 37 | #define OPM_PLL_BYPASS (0x5 << 26) | ||
| 38 | #define OPM_DEBUG (0x4 << 26) | ||
| 39 | #define OPM_BURN_IN (0x3 << 26) | ||
| 40 | #define OPM_MBIST (0x2 << 26) | ||
| 41 | #define OPM_SCAN (0x1 << 26) | ||
| 42 | #define OPM_REAL (0x0 << 26) | ||
| 43 | |||
| 44 | #define FLASH_TYPE_MASK (0x3 << 24) | ||
| 45 | #define FLASH_TYPE_NAND_2K (0x3 << 24) | ||
| 46 | #define FLASH_TYPE_NAND_512 (0x2 << 24) | ||
| 47 | #define FLASH_TYPE_PARALLEL (0x1 << 24) | ||
| 48 | #define FLASH_TYPE_SERIAL (0x0 << 24) | ||
| 49 | /* if parallel */ | ||
| 50 | #define FLASH_WIDTH_16BIT (1 << 23) /* else 8 bit */ | ||
| 51 | /* if serial */ | ||
| 52 | #define FLASH_ATMEL (1 << 23) /* else STM */ | ||
| 53 | |||
| 54 | #define FLASH_SIZE_MASK (0x3 << 21) | ||
| 55 | #define NAND_256M (0x3 << 21) /* and more */ | ||
| 56 | #define NAND_128M (0x2 << 21) | ||
| 57 | #define NAND_64M (0x1 << 21) | ||
| 58 | #define NAND_32M (0x0 << 21) | ||
| 59 | #define ATMEL_16M (0x3 << 21) /* and more */ | ||
| 60 | #define ATMEL_8M (0x2 << 21) | ||
| 61 | #define ATMEL_4M_2M (0x1 << 21) | ||
| 62 | #define ATMEL_1M (0x0 << 21) /* and less */ | ||
| 63 | #define STM_32M (1 << 22) /* and more */ | ||
| 64 | #define STM_16M (0 << 22) /* and less */ | ||
| 65 | |||
| 66 | #define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */ | ||
| 67 | |||
| 68 | #define CPU_AHB_RATIO_MASK (0x3 << 18) | ||
| 69 | #define CPU_AHB_1_1 (0x0 << 18) | ||
| 70 | #define CPU_AHB_3_2 (0x1 << 18) | ||
| 71 | #define CPU_AHB_24_13 (0x2 << 18) | ||
| 72 | #define CPU_AHB_2_1 (0x3 << 18) | ||
| 73 | |||
| 74 | #define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130) | ||
| 75 | #define AHB_SPEED_TO_REG(x) ((((x - 130)) / 10) << 15) | ||
| 76 | |||
| 77 | /* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */ | ||
| 78 | #define OVERRIDE_FLASH_TYPE_SHIFT 16 | ||
| 79 | #define OVERRIDE_FLASH_WIDTH_SHIFT 16 | ||
| 80 | #define OVERRIDE_FLASH_SIZE_SHIFT 16 | ||
| 81 | #define OVERRIDE_CPU_AHB_RATIO_SHIFT 15 | ||
| 82 | #define OVERRIDE_AHB_SPEED_SHIFT 15 | ||
| 83 | |||
| 84 | /* Global PLL Control Register */ | ||
| 85 | #define GLOBAL_PLL_CTRL 0x08 | ||
| 86 | |||
| 87 | #define PLL_BYPASS (1 << 31) | ||
| 88 | #define PLL_POWER_DOWN (1 << 8) | ||
| 89 | #define PLL_CONTROL_Q (0x1F << 0) | ||
| 90 | |||
| 91 | /* Global Soft Reset Control Register */ | ||
| 92 | #define GLOBAL_RESET 0x0C | ||
| 93 | |||
| 94 | #define RESET_GLOBAL (1 << 31) | ||
| 95 | #define RESET_CPU1 (1 << 30) | ||
| 96 | #define RESET_TVE (1 << 28) | ||
| 97 | #define RESET_SATA1 (1 << 27) | ||
| 98 | #define RESET_SATA0 (1 << 26) | ||
| 99 | #define RESET_CIR (1 << 25) | ||
| 100 | #define RESET_EXT_DEV (1 << 24) | ||
| 101 | #define RESET_WD (1 << 23) | ||
| 102 | #define RESET_GPIO2 (1 << 22) | ||
| 103 | #define RESET_GPIO1 (1 << 21) | ||
| 104 | #define RESET_GPIO0 (1 << 20) | ||
| 105 | #define RESET_SSP (1 << 19) | ||
| 106 | #define RESET_UART (1 << 18) | ||
| 107 | #define RESET_TIMER (1 << 17) | ||
| 108 | #define RESET_RTC (1 << 16) | ||
| 109 | #define RESET_INT1 (1 << 15) | ||
| 110 | #define RESET_INT0 (1 << 14) | ||
| 111 | #define RESET_LCD (1 << 13) | ||
| 112 | #define RESET_LPC (1 << 12) | ||
| 113 | #define RESET_APB (1 << 11) | ||
| 114 | #define RESET_DMA (1 << 10) | ||
| 115 | #define RESET_USB1 (1 << 9) | ||
| 116 | #define RESET_USB0 (1 << 8) | ||
| 117 | #define RESET_PCI (1 << 7) | ||
| 118 | #define RESET_GMAC1 (1 << 6) | ||
| 119 | #define RESET_GMAC0 (1 << 5) | ||
| 120 | #define RESET_SECURITY (1 << 4) | ||
| 121 | #define RESET_RAID (1 << 3) | ||
| 122 | #define RESET_IDE (1 << 2) | ||
| 123 | #define RESET_FLASH (1 << 1) | ||
| 124 | #define RESET_DRAM (1 << 0) | ||
| 125 | |||
| 126 | /* Global IO Pad Driving Capability Control Register */ | ||
| 127 | #define GLOBAL_IO_DRIVING_CTRL 0x10 | ||
| 128 | |||
| 129 | #define DRIVING_CURRENT_MASK 0x3 | ||
| 130 | |||
| 131 | /* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */ | ||
| 132 | #define GPIO1_PADS_31_28_SHIFT 28 | ||
| 133 | #define GPIO0_PADS_31_16_SHIFT 26 | ||
| 134 | #define GPIO0_PADS_15_0_SHIFT 24 | ||
| 135 | #define PCI_AND_EXT_RESET_PADS_SHIFT 22 | ||
| 136 | #define IDE_PADS_SHIFT 20 | ||
| 137 | #define GMAC1_PADS_SHIFT 18 | ||
| 138 | #define GMAC0_PADS_SHIFT 16 | ||
| 139 | /* DRAM is not in mA and poorly documented */ | ||
| 140 | #define DRAM_CLOCK_PADS_SHIFT 8 | ||
| 141 | #define DRAM_DATA_PADS_SHIFT 4 | ||
| 142 | #define DRAM_CONTROL_PADS_SHIFT 0 | ||
| 143 | |||
| 144 | /* Global IO Pad Slew Rate Control Register */ | ||
| 145 | #define GLOBAL_IO_SLEW_RATE_CTRL 0x14 | ||
| 146 | |||
| 147 | #define GPIO1_PADS_31_28_SLOW (1 << 10) | ||
| 148 | #define GPIO0_PADS_31_16_SLOW (1 << 9) | ||
| 149 | #define GPIO0_PADS_15_0_SLOW (1 << 8) | ||
| 150 | #define PCI_PADS_SLOW (1 << 7) | ||
| 151 | #define IDE_PADS_SLOW (1 << 6) | ||
| 152 | #define GMAC1_PADS_SLOW (1 << 5) | ||
| 153 | #define GMAC0_PADS_SLOW (1 << 4) | ||
| 154 | #define DRAM_CLOCK_PADS_SLOW (1 << 1) | ||
| 155 | #define DRAM_IO_PADS_SLOW (1 << 0) | ||
| 156 | |||
| 157 | /* | ||
| 158 | * General skew control defines | ||
| 159 | * 16 steps, each step is around 0.2ns | ||
| 160 | */ | ||
| 161 | #define SKEW_MASK 0xF | ||
| 162 | |||
| 163 | /* Global IDE PAD Skew Control Register */ | ||
| 164 | #define GLOBAL_IDE_SKEW_CTRL 0x18 | ||
| 165 | |||
| 166 | #define IDE1_HOST_STROBE_DELAY_SHIFT 28 | ||
| 167 | #define IDE1_DEVICE_STROBE_DELAY_SHIFT 24 | ||
| 168 | #define IDE1_OUTPUT_IO_SKEW_SHIFT 20 | ||
| 169 | #define IDE1_INPUT_IO_SKEW_SHIFT 16 | ||
| 170 | #define IDE0_HOST_STROBE_DELAY_SHIFT 12 | ||
| 171 | #define IDE0_DEVICE_STROBE_DELAY_SHIFT 8 | ||
| 172 | #define IDE0_OUTPUT_IO_SKEW_SHIFT 4 | ||
| 173 | #define IDE0_INPUT_IO_SKEW_SHIFT 0 | ||
| 174 | |||
| 175 | /* Global GMAC Control Pad Skew Control Register */ | ||
| 176 | #define GLOBAL_GMAC_CTRL_SKEW_CTRL 0x1C | ||
| 177 | |||
| 178 | #define GMAC1_TXC_SKEW_SHIFT 28 | ||
| 179 | #define GMAC1_TXEN_SKEW_SHIFT 24 | ||
| 180 | #define GMAC1_RXC_SKEW_SHIFT 20 | ||
| 181 | #define GMAC1_RXDV_SKEW_SHIFT 16 | ||
| 182 | #define GMAC0_TXC_SKEW_SHIFT 12 | ||
| 183 | #define GMAC0_TXEN_SKEW_SHIFT 8 | ||
| 184 | #define GMAC0_RXC_SKEW_SHIFT 4 | ||
| 185 | #define GMAC0_RXDV_SKEW_SHIFT 0 | ||
| 186 | |||
| 187 | /* Global GMAC0 Data PAD Skew Control Register */ | ||
| 188 | #define GLOBAL_GMAC0_DATA_SKEW_CTRL 0x20 | ||
| 189 | /* Global GMAC1 Data PAD Skew Control Register */ | ||
| 190 | #define GLOBAL_GMAC1_DATA_SKEW_CTRL 0x24 | ||
| 191 | |||
| 192 | #define GMAC_TXD_SKEW_SHIFT(x) (((x) * 4) + 16) | ||
| 193 | #define GMAC_RXD_SKEW_SHIFT(x) ((x) * 4) | ||
| 194 | |||
| 195 | /* CPU has two AHB busses. */ | ||
| 196 | |||
| 197 | /* Global Arbitration0 Control Register */ | ||
| 198 | #define GLOBAL_ARBITRATION0_CTRL 0x28 | ||
| 199 | |||
| 200 | #define BOOT_CONTROLLER_HIGH_PRIO (1 << 3) | ||
| 201 | #define DMA_BUS1_HIGH_PRIO (1 << 2) | ||
| 202 | #define CPU0_HIGH_PRIO (1 << 0) | ||
| 203 | |||
| 204 | /* Global Arbitration1 Control Register */ | ||
| 205 | #define GLOBAL_ARBITRATION1_CTRL 0x2C | ||
| 206 | |||
| 207 | #define TVE_HIGH_PRIO (1 << 9) | ||
| 208 | #define PCI_HIGH_PRIO (1 << 8) | ||
| 209 | #define USB1_HIGH_PRIO (1 << 7) | ||
| 210 | #define USB0_HIGH_PRIO (1 << 6) | ||
| 211 | #define GMAC1_HIGH_PRIO (1 << 5) | ||
| 212 | #define GMAC0_HIGH_PRIO (1 << 4) | ||
| 213 | #define SECURITY_HIGH_PRIO (1 << 3) | ||
| 214 | #define RAID_HIGH_PRIO (1 << 2) | ||
| 215 | #define IDE_HIGH_PRIO (1 << 1) | ||
| 216 | #define DMA_BUS2_HIGH_PRIO (1 << 0) | ||
| 217 | |||
| 218 | /* Common bits for both arbitration registers */ | ||
| 219 | #define BURST_LENGTH_SHIFT 16 | ||
| 220 | #define BURST_LENGTH_MASK (0x3F << 16) | ||
| 221 | |||
| 222 | /* Miscellaneous Control Register */ | ||
| 223 | #define GLOBAL_MISC_CTRL 0x30 | ||
| 224 | |||
| 225 | #define MEMORY_SPACE_SWAP (1 << 31) | ||
| 226 | #define USB1_PLUG_MINIB (1 << 30) /* else plug is mini-A */ | ||
| 227 | #define USB0_PLUG_MINIB (1 << 29) | ||
| 228 | #define GMAC_GMII (1 << 28) | ||
| 229 | #define GMAC_1_ENABLE (1 << 27) | ||
| 230 | /* TODO: define ATA/SATA bits */ | ||
| 231 | #define USB1_VBUS_ON (1 << 23) | ||
| 232 | #define USB0_VBUS_ON (1 << 22) | ||
| 233 | #define APB_CLKOUT_ENABLE (1 << 21) | ||
| 234 | #define TVC_CLKOUT_ENABLE (1 << 20) | ||
| 235 | #define EXT_CLKIN_ENABLE (1 << 19) | ||
| 236 | #define PCI_66MHZ (1 << 18) /* else 33 MHz */ | ||
| 237 | #define PCI_CLKOUT_ENABLE (1 << 17) | ||
| 238 | #define LPC_CLKOUT_ENABLE (1 << 16) | ||
| 239 | #define USB1_WAKEUP_ON (1 << 15) | ||
| 240 | #define USB0_WAKEUP_ON (1 << 14) | ||
| 241 | /* TODO: define PCI idle detect bits */ | ||
| 242 | #define TVC_PADS_ENABLE (1 << 9) | ||
| 243 | #define SSP_PADS_ENABLE (1 << 8) | ||
| 244 | #define LCD_PADS_ENABLE (1 << 7) | ||
| 245 | #define LPC_PADS_ENABLE (1 << 6) | ||
| 246 | #define PCI_PADS_ENABLE (1 << 5) | ||
| 247 | #define IDE_PADS_ENABLE (1 << 4) | ||
| 248 | #define DRAM_PADS_POWER_DOWN (1 << 3) | ||
| 249 | #define NAND_PADS_DISABLE (1 << 2) | ||
| 250 | #define PFLASH_PADS_DISABLE (1 << 1) | ||
| 251 | #define SFLASH_PADS_DISABLE (1 << 0) | ||
| 252 | |||
| 253 | /* Global Clock Control Register */ | ||
| 254 | #define GLOBAL_CLOCK_CTRL 0x34 | ||
| 255 | |||
| 256 | #define POWER_STATE_G0 (1 << 31) | ||
| 257 | #define POWER_STATE_S1 (1 << 30) /* else it is S3/S4 state */ | ||
| 258 | #define SECURITY_APB_AHB (1 << 29) | ||
| 259 | /* else Security APB clk will be 0.75xAHB */ | ||
| 260 | /* TODO: TVC clock divider */ | ||
| 261 | #define PCI_CLKRUN_ENABLE (1 << 16) | ||
| 262 | #define BOOT_CLK_DISABLE (1 << 13) | ||
| 263 | #define TVC_CLK_DISABLE (1 << 12) | ||
| 264 | #define FLASH_CLK_DISABLE (1 << 11) | ||
| 265 | #define DDR_CLK_DISABLE (1 << 10) | ||
| 266 | #define PCI_CLK_DISABLE (1 << 9) | ||
| 267 | #define IDE_CLK_DISABLE (1 << 8) | ||
| 268 | #define USB1_CLK_DISABLE (1 << 7) | ||
| 269 | #define USB0_CLK_DISABLE (1 << 6) | ||
| 270 | #define SATA1_CLK_DISABLE (1 << 5) | ||
| 271 | #define SATA0_CLK_DISABLE (1 << 4) | ||
| 272 | #define GMAC1_CLK_DISABLE (1 << 3) | ||
| 273 | #define GMAC0_CLK_DISABLE (1 << 2) | ||
| 274 | #define SECURITY_CLK_DISABLE (1 << 1) | ||
| 275 | |||
| 276 | /* TODO: other registers definitions if needed */ | ||
| 277 | |||
| 278 | #endif /* __MACH_GLOBAL_REG_H */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/gpio.h b/arch/arm/mach-gemini/include/mach/gpio.h new file mode 100644 index 000000000000..3bc2c70f2989 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/gpio.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * Gemini gpiolib specific defines | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __MACH_GPIO_H__ | ||
| 13 | #define __MACH_GPIO_H__ | ||
| 14 | |||
| 15 | #include <mach/irqs.h> | ||
| 16 | #include <asm-generic/gpio.h> | ||
| 17 | |||
| 18 | #define gpio_get_value __gpio_get_value | ||
| 19 | #define gpio_set_value __gpio_set_value | ||
| 20 | #define gpio_cansleep __gpio_cansleep | ||
| 21 | |||
| 22 | #define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE) | ||
| 23 | #define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE) | ||
| 24 | |||
| 25 | #endif /* __MACH_GPIO_H__ */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h new file mode 100644 index 000000000000..de6752674c05 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/hardware.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the hardware definitions for Gemini. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #ifndef __MACH_HARDWARE_H | ||
| 13 | #define __MACH_HARDWARE_H | ||
| 14 | |||
| 15 | /* | ||
| 16 | * Memory Map definitions | ||
| 17 | */ | ||
| 18 | /* FIXME: Does it really swap SRAM like this? */ | ||
| 19 | #ifdef CONFIG_GEMINI_MEM_SWAP | ||
| 20 | # define GEMINI_DRAM_BASE 0x00000000 | ||
| 21 | # define GEMINI_SRAM_BASE 0x20000000 | ||
| 22 | #else | ||
| 23 | # define GEMINI_SRAM_BASE 0x00000000 | ||
| 24 | # define GEMINI_DRAM_BASE 0x10000000 | ||
| 25 | #endif | ||
| 26 | #define GEMINI_FLASH_BASE 0x30000000 | ||
| 27 | #define GEMINI_GLOBAL_BASE 0x40000000 | ||
| 28 | #define GEMINI_WAQTCHDOG_BASE 0x41000000 | ||
| 29 | #define GEMINI_UART_BASE 0x42000000 | ||
| 30 | #define GEMINI_TIMER_BASE 0x43000000 | ||
| 31 | #define GEMINI_LCD_BASE 0x44000000 | ||
| 32 | #define GEMINI_RTC_BASE 0x45000000 | ||
| 33 | #define GEMINI_SATA_BASE 0x46000000 | ||
| 34 | #define GEMINI_LPC_HOST_BASE 0x47000000 | ||
| 35 | #define GEMINI_LPC_IO_BASE 0x47800000 | ||
| 36 | #define GEMINI_INTERRUPT_BASE 0x48000000 | ||
| 37 | /* TODO: Different interrupt controlers when SMP | ||
| 38 | * #define GEMINI_INTERRUPT0_BASE 0x48000000 | ||
| 39 | * #define GEMINI_INTERRUPT1_BASE 0x49000000 | ||
| 40 | */ | ||
| 41 | #define GEMINI_SSP_CTRL_BASE 0x4A000000 | ||
| 42 | #define GEMINI_POWER_CTRL_BASE 0x4B000000 | ||
| 43 | #define GEMINI_CIR_BASE 0x4C000000 | ||
| 44 | #define GEMINI_GPIO_BASE(x) (0x4D000000 + (x) * 0x1000000) | ||
| 45 | #define GEMINI_PCI_IO_BASE 0x50000000 | ||
| 46 | #define GEMINI_PCI_MEM_BASE 0x58000000 | ||
| 47 | #define GEMINI_TOE_BASE 0x60000000 | ||
| 48 | #define GEMINI_GMAC0_BASE 0x6000A000 | ||
| 49 | #define GEMINI_GMAC1_BASE 0x6000E000 | ||
| 50 | #define GEMINI_SECURITY_BASE 0x62000000 | ||
| 51 | #define GEMINI_IDE0_BASE 0x63000000 | ||
| 52 | #define GEMINI_IDE1_BASE 0x63400000 | ||
| 53 | #define GEMINI_RAID_BASE 0x64000000 | ||
| 54 | #define GEMINI_FLASH_CTRL_BASE 0x65000000 | ||
| 55 | #define GEMINI_DRAM_CTRL_BASE 0x66000000 | ||
| 56 | #define GEMINI_GENERAL_DMA_BASE 0x67000000 | ||
| 57 | #define GEMINI_USB0_BASE 0x68000000 | ||
| 58 | #define GEMINI_USB1_BASE 0x69000000 | ||
| 59 | #define GEMINI_BIG_ENDIAN_BASE 0x80000000 | ||
| 60 | |||
| 61 | #define GEMINI_TIMER1_BASE GEMINI_TIMER_BASE | ||
| 62 | #define GEMINI_TIMER2_BASE (GEMINI_TIMER_BASE + 0x10) | ||
| 63 | #define GEMINI_TIMER3_BASE (GEMINI_TIMER_BASE + 0x20) | ||
| 64 | |||
| 65 | /* | ||
| 66 | * UART Clock when System clk is 150MHz | ||
| 67 | */ | ||
| 68 | #define UART_CLK 48000000 | ||
| 69 | |||
| 70 | /* | ||
| 71 | * macro to get at IO space when running virtually | ||
| 72 | */ | ||
| 73 | #define IO_ADDRESS(x) ((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) | ||
| 74 | |||
| 75 | #endif | ||
diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h new file mode 100644 index 000000000000..c548056b98b2 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/io.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 3 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | #ifndef __MACH_IO_H | ||
| 11 | #define __MACH_IO_H | ||
| 12 | |||
| 13 | #define IO_SPACE_LIMIT 0xffffffff | ||
| 14 | |||
| 15 | #define __io(a) __typesafe_io(a) | ||
| 16 | #define __mem_pci(a) (a) | ||
| 17 | |||
| 18 | #endif /* __MACH_IO_H */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/irqs.h b/arch/arm/mach-gemini/include/mach/irqs.h new file mode 100644 index 000000000000..06bc47e77e8b --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/irqs.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 3 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __MACH_IRQS_H__ | ||
| 12 | #define __MACH_IRQS_H__ | ||
| 13 | |||
| 14 | #define IRQ_SERIRQ1 31 | ||
| 15 | #define IRQ_SERIRQ0 30 | ||
| 16 | #define IRQ_PCID 29 | ||
| 17 | #define IRQ_PCIC 28 | ||
| 18 | #define IRQ_PCIB 27 | ||
| 19 | #define IRQ_PWR 26 | ||
| 20 | #define IRQ_CIR 25 | ||
| 21 | #define IRQ_GPIO(x) (22 + (x)) | ||
| 22 | #define IRQ_SSP 21 | ||
| 23 | #define IRQ_LPC 20 | ||
| 24 | #define IRQ_LCD 19 | ||
| 25 | #define IRQ_UART 18 | ||
| 26 | #define IRQ_RTC 17 | ||
| 27 | #define IRQ_TIMER3 16 | ||
| 28 | #define IRQ_TIMER2 15 | ||
| 29 | #define IRQ_TIMER1 14 | ||
| 30 | #define IRQ_FLASH 12 | ||
| 31 | #define IRQ_USB1 11 | ||
| 32 | #define IRQ_USB0 10 | ||
| 33 | #define IRQ_DMA 9 | ||
| 34 | #define IRQ_PCI 8 | ||
| 35 | #define IRQ_IPSEC 7 | ||
| 36 | #define IRQ_RAID 6 | ||
| 37 | #define IRQ_IDE1 5 | ||
| 38 | #define IRQ_IDE0 4 | ||
| 39 | #define IRQ_WATCHDOG 3 | ||
| 40 | #define IRQ_GMAC1 2 | ||
| 41 | #define IRQ_GMAC0 1 | ||
| 42 | #define IRQ_IPI 0 | ||
| 43 | |||
| 44 | #define NORMAL_IRQ_NUM 32 | ||
| 45 | |||
| 46 | #define GPIO_IRQ_BASE NORMAL_IRQ_NUM | ||
| 47 | #define GPIO_IRQ_NUM (3 * 32) | ||
| 48 | |||
| 49 | #define ARCH_TIMER_IRQ IRQ_TIMER2 | ||
| 50 | |||
| 51 | #define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM) | ||
| 52 | |||
| 53 | #endif /* __MACH_IRQS_H__ */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h new file mode 100644 index 000000000000..2d14d5bf1f9f --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/memory.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 3 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | #ifndef __MACH_MEMORY_H | ||
| 11 | #define __MACH_MEMORY_H | ||
| 12 | |||
| 13 | #ifdef CONFIG_GEMINI_MEM_SWAP | ||
| 14 | # define PHYS_OFFSET UL(0x00000000) | ||
| 15 | #else | ||
| 16 | # define PHYS_OFFSET UL(0x10000000) | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #endif /* __MACH_MEMORY_H */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h new file mode 100644 index 000000000000..bbbd72767a02 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/system.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 3 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | #ifndef __MACH_SYSTEM_H | ||
| 11 | #define __MACH_SYSTEM_H | ||
| 12 | |||
| 13 | #include <linux/io.h> | ||
| 14 | #include <mach/hardware.h> | ||
| 15 | #include <mach/global_reg.h> | ||
| 16 | |||
| 17 | static inline void arch_idle(void) | ||
| 18 | { | ||
| 19 | /* | ||
| 20 | * Because of broken hardware we have to enable interrupts or the CPU | ||
| 21 | * will never wakeup... Acctualy it is not very good to enable | ||
| 22 | * interrupts here since scheduler can miss a tick, but there is | ||
| 23 | * no other way around this. Platforms that needs it for power saving | ||
| 24 | * should call enable_hlt() in init code, since by default it is | ||
| 25 | * disabled. | ||
| 26 | */ | ||
| 27 | local_irq_enable(); | ||
| 28 | cpu_do_idle(); | ||
| 29 | } | ||
| 30 | |||
| 31 | static inline void arch_reset(char mode) | ||
| 32 | { | ||
| 33 | __raw_writel(RESET_GLOBAL | RESET_CPU1, | ||
| 34 | IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET); | ||
| 35 | } | ||
| 36 | |||
| 37 | #endif /* __MACH_SYSTEM_H */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h new file mode 100644 index 000000000000..dc5690ba975c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/timex.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* | ||
| 2 | * Gemini timex specifications | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | /* When AHB bus frequency is 150MHz */ | ||
| 13 | #define CLOCK_TICK_RATE 38000000 | ||
diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h new file mode 100644 index 000000000000..59c5df7e716c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/uncompress.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 3 | * | ||
| 4 | * Based on mach-pxa/include/mach/uncompress.h: | ||
| 5 | * Copyright: (C) 2001 MontaVista Software Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __MACH_UNCOMPRESS_H | ||
| 14 | #define __MACH_UNCOMPRESS_H | ||
| 15 | |||
| 16 | #include <linux/serial_reg.h> | ||
| 17 | #include <mach/hardware.h> | ||
| 18 | |||
| 19 | static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * The following code assumes the serial port has already been | ||
| 23 | * initialized by the bootloader. If you didn't setup a port in | ||
| 24 | * your bootloader then nothing will appear (which might be desired). | ||
| 25 | */ | ||
| 26 | static inline void putc(char c) | ||
| 27 | { | ||
| 28 | while (!(UART[UART_LSR] & UART_LSR_THRE)) | ||
| 29 | barrier(); | ||
| 30 | UART[UART_TX] = c; | ||
| 31 | } | ||
| 32 | |||
| 33 | #define flush() do { } while (0) | ||
| 34 | |||
| 35 | /* | ||
| 36 | * nothing to do | ||
| 37 | */ | ||
| 38 | #define arch_decomp_setup() | ||
| 39 | |||
| 40 | #define arch_decomp_wdog() | ||
| 41 | |||
| 42 | #endif /* __MACH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-gemini/include/mach/vmalloc.h b/arch/arm/mach-gemini/include/mach/vmalloc.h new file mode 100644 index 000000000000..83e536d9436c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/vmalloc.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #define VMALLOC_END 0xF0000000 | ||
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c new file mode 100644 index 000000000000..9e613ca8120d --- /dev/null +++ b/arch/arm/mach-gemini/irq.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * Interrupt routines for Gemini | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/ioport.h> | ||
| 15 | #include <linux/stddef.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/sched.h> | ||
| 18 | #include <asm/irq.h> | ||
| 19 | #include <asm/mach/irq.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | |||
| 22 | #define IRQ_SOURCE(base_addr) (base_addr + 0x00) | ||
| 23 | #define IRQ_MASK(base_addr) (base_addr + 0x04) | ||
| 24 | #define IRQ_CLEAR(base_addr) (base_addr + 0x08) | ||
| 25 | #define IRQ_TMODE(base_addr) (base_addr + 0x0C) | ||
| 26 | #define IRQ_TLEVEL(base_addr) (base_addr + 0x10) | ||
| 27 | #define IRQ_STATUS(base_addr) (base_addr + 0x14) | ||
| 28 | #define FIQ_SOURCE(base_addr) (base_addr + 0x20) | ||
| 29 | #define FIQ_MASK(base_addr) (base_addr + 0x24) | ||
| 30 | #define FIQ_CLEAR(base_addr) (base_addr + 0x28) | ||
| 31 | #define FIQ_TMODE(base_addr) (base_addr + 0x2C) | ||
| 32 | #define FIQ_LEVEL(base_addr) (base_addr + 0x30) | ||
| 33 | #define FIQ_STATUS(base_addr) (base_addr + 0x34) | ||
| 34 | |||
| 35 | static void gemini_ack_irq(unsigned int irq) | ||
| 36 | { | ||
| 37 | __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void gemini_mask_irq(unsigned int irq) | ||
| 41 | { | ||
| 42 | unsigned int mask; | ||
| 43 | |||
| 44 | mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 45 | mask &= ~(1 << irq); | ||
| 46 | __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void gemini_unmask_irq(unsigned int irq) | ||
| 50 | { | ||
| 51 | unsigned int mask; | ||
| 52 | |||
| 53 | mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 54 | mask |= (1 << irq); | ||
| 55 | __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 56 | } | ||
| 57 | |||
| 58 | static struct irq_chip gemini_irq_chip = { | ||
| 59 | .name = "INTC", | ||
| 60 | .ack = gemini_ack_irq, | ||
| 61 | .mask = gemini_mask_irq, | ||
| 62 | .unmask = gemini_unmask_irq, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct resource irq_resource = { | ||
| 66 | .name = "irq_handler", | ||
| 67 | .start = IO_ADDRESS(GEMINI_INTERRUPT_BASE), | ||
| 68 | .end = IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4, | ||
| 69 | }; | ||
| 70 | |||
| 71 | void __init gemini_init_irq(void) | ||
| 72 | { | ||
| 73 | unsigned int i, mode = 0, level = 0; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Disable arch_idle() by default since it is buggy | ||
| 77 | * For more info see arch/arm/mach-gemini/include/mach/system.h | ||
| 78 | */ | ||
| 79 | disable_hlt(); | ||
| 80 | |||
| 81 | request_resource(&iomem_resource, &irq_resource); | ||
| 82 | |||
| 83 | for (i = 0; i < NR_IRQS; i++) { | ||
| 84 | set_irq_chip(i, &gemini_irq_chip); | ||
| 85 | if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) { | ||
| 86 | set_irq_handler(i, handle_edge_irq); | ||
| 87 | mode |= 1 << i; | ||
| 88 | level |= 1 << i; | ||
| 89 | } else { | ||
| 90 | set_irq_handler(i, handle_level_irq); | ||
| 91 | } | ||
| 92 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
| 93 | } | ||
| 94 | |||
| 95 | /* Disable all interrupts */ | ||
| 96 | __raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 97 | __raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 98 | |||
| 99 | /* Set interrupt mode */ | ||
| 100 | __raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 101 | __raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); | ||
| 102 | } | ||
diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c new file mode 100644 index 000000000000..51948242ec09 --- /dev/null +++ b/arch/arm/mach-gemini/mm.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* | ||
| 2 | * Static mappings for Gemini | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 5 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #include <linux/mm.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | |||
| 15 | #include <asm/mach/map.h> | ||
| 16 | |||
| 17 | #include <mach/hardware.h> | ||
| 18 | |||
| 19 | /* Page table mapping for I/O region */ | ||
| 20 | static struct map_desc gemini_io_desc[] __initdata = { | ||
| 21 | { | ||
| 22 | .virtual = IO_ADDRESS(GEMINI_GLOBAL_BASE), | ||
| 23 | .pfn =__phys_to_pfn(GEMINI_GLOBAL_BASE), | ||
| 24 | .length = SZ_512K, | ||
| 25 | .type = MT_DEVICE, | ||
| 26 | }, { | ||
| 27 | .virtual = IO_ADDRESS(GEMINI_UART_BASE), | ||
| 28 | .pfn = __phys_to_pfn(GEMINI_UART_BASE), | ||
| 29 | .length = SZ_512K, | ||
| 30 | .type = MT_DEVICE, | ||
| 31 | }, { | ||
| 32 | .virtual = IO_ADDRESS(GEMINI_TIMER_BASE), | ||
| 33 | .pfn = __phys_to_pfn(GEMINI_TIMER_BASE), | ||
| 34 | .length = SZ_512K, | ||
| 35 | .type = MT_DEVICE, | ||
| 36 | }, { | ||
| 37 | .virtual = IO_ADDRESS(GEMINI_INTERRUPT_BASE), | ||
| 38 | .pfn = __phys_to_pfn(GEMINI_INTERRUPT_BASE), | ||
| 39 | .length = SZ_512K, | ||
| 40 | .type = MT_DEVICE, | ||
| 41 | }, { | ||
| 42 | .virtual = IO_ADDRESS(GEMINI_POWER_CTRL_BASE), | ||
| 43 | .pfn = __phys_to_pfn(GEMINI_POWER_CTRL_BASE), | ||
| 44 | .length = SZ_512K, | ||
| 45 | .type = MT_DEVICE, | ||
| 46 | }, { | ||
| 47 | .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(0)), | ||
| 48 | .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(0)), | ||
| 49 | .length = SZ_512K, | ||
| 50 | .type = MT_DEVICE, | ||
| 51 | }, { | ||
| 52 | .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(1)), | ||
| 53 | .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(1)), | ||
| 54 | .length = SZ_512K, | ||
| 55 | .type = MT_DEVICE, | ||
| 56 | }, { | ||
| 57 | .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(2)), | ||
| 58 | .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(2)), | ||
| 59 | .length = SZ_512K, | ||
| 60 | .type = MT_DEVICE, | ||
| 61 | }, { | ||
| 62 | .virtual = IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), | ||
| 63 | .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE), | ||
| 64 | .length = SZ_512K, | ||
| 65 | .type = MT_DEVICE, | ||
| 66 | }, { | ||
| 67 | .virtual = IO_ADDRESS(GEMINI_DRAM_CTRL_BASE), | ||
| 68 | .pfn = __phys_to_pfn(GEMINI_DRAM_CTRL_BASE), | ||
| 69 | .length = SZ_512K, | ||
| 70 | .type = MT_DEVICE, | ||
| 71 | }, { | ||
| 72 | .virtual = IO_ADDRESS(GEMINI_GENERAL_DMA_BASE), | ||
| 73 | .pfn = __phys_to_pfn(GEMINI_GENERAL_DMA_BASE), | ||
| 74 | .length = SZ_512K, | ||
| 75 | .type = MT_DEVICE, | ||
| 76 | }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | void __init gemini_map_io(void) | ||
| 80 | { | ||
| 81 | iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc)); | ||
| 82 | } | ||
diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c new file mode 100644 index 000000000000..21dc5a89d1c4 --- /dev/null +++ b/arch/arm/mach-gemini/time.c | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
| 3 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | #include <linux/interrupt.h> | ||
| 11 | #include <linux/irq.h> | ||
| 12 | #include <linux/io.h> | ||
| 13 | #include <mach/hardware.h> | ||
| 14 | #include <mach/global_reg.h> | ||
| 15 | #include <asm/mach/time.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * Register definitions for the timers | ||
| 19 | */ | ||
| 20 | #define TIMER_COUNT(BASE_ADDR) (BASE_ADDR + 0x00) | ||
| 21 | #define TIMER_LOAD(BASE_ADDR) (BASE_ADDR + 0x04) | ||
| 22 | #define TIMER_MATCH1(BASE_ADDR) (BASE_ADDR + 0x08) | ||
| 23 | #define TIMER_MATCH2(BASE_ADDR) (BASE_ADDR + 0x0C) | ||
| 24 | #define TIMER_CR(BASE_ADDR) (BASE_ADDR + 0x30) | ||
| 25 | |||
| 26 | #define TIMER_1_CR_ENABLE (1 << 0) | ||
| 27 | #define TIMER_1_CR_CLOCK (1 << 1) | ||
| 28 | #define TIMER_1_CR_INT (1 << 2) | ||
| 29 | #define TIMER_2_CR_ENABLE (1 << 3) | ||
| 30 | #define TIMER_2_CR_CLOCK (1 << 4) | ||
| 31 | #define TIMER_2_CR_INT (1 << 5) | ||
| 32 | #define TIMER_3_CR_ENABLE (1 << 6) | ||
| 33 | #define TIMER_3_CR_CLOCK (1 << 7) | ||
| 34 | #define TIMER_3_CR_INT (1 << 8) | ||
| 35 | |||
| 36 | /* | ||
| 37 | * IRQ handler for the timer | ||
| 38 | */ | ||
| 39 | static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) | ||
| 40 | { | ||
| 41 | timer_tick(); | ||
| 42 | |||
| 43 | return IRQ_HANDLED; | ||
| 44 | } | ||
| 45 | |||
| 46 | static struct irqaction gemini_timer_irq = { | ||
| 47 | .name = "Gemini Timer Tick", | ||
| 48 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
| 49 | .handler = gemini_timer_interrupt, | ||
| 50 | }; | ||
| 51 | |||
| 52 | /* | ||
| 53 | * Set up timer interrupt, and return the current time in seconds. | ||
| 54 | */ | ||
| 55 | void __init gemini_timer_init(void) | ||
| 56 | { | ||
| 57 | unsigned int tick_rate, reg_v; | ||
| 58 | |||
| 59 | reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); | ||
| 60 | tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000; | ||
| 61 | |||
| 62 | printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); | ||
| 63 | |||
| 64 | tick_rate /= 6; /* APB bus run AHB*(1/6) */ | ||
| 65 | |||
| 66 | switch(reg_v & CPU_AHB_RATIO_MASK) { | ||
| 67 | case CPU_AHB_1_1: | ||
| 68 | printk(KERN_CONT "(1/1)\n"); | ||
| 69 | break; | ||
| 70 | case CPU_AHB_3_2: | ||
| 71 | printk(KERN_CONT "(3/2)\n"); | ||
| 72 | break; | ||
| 73 | case CPU_AHB_24_13: | ||
| 74 | printk(KERN_CONT "(24/13)\n"); | ||
| 75 | break; | ||
| 76 | case CPU_AHB_2_1: | ||
| 77 | printk(KERN_CONT "(2/1)\n"); | ||
| 78 | break; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Make irqs happen for the system timer | ||
| 83 | */ | ||
| 84 | setup_irq(IRQ_TIMER2, &gemini_timer_irq); | ||
| 85 | /* Start the timer */ | ||
| 86 | __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); | ||
| 87 | __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); | ||
| 88 | __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); | ||
| 89 | } | ||
