1 /* 2 * linux/arch/arm/mach-sa1100/collie.c 3 * 4 * May be copied or modified under the terms of the GNU General Public 5 * License. See linux/COPYING for more information. 6 * 7 * This file contains all Collie-specific tweaks. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * ChangeLog: 14 * 2006 Pavel Machek <pavel@suse.cz> 15 * 03-06-2004 John Lenz <lenz@cs.wisc.edu> 16 * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net> 17 * 04-16-2001 Lineo Japan,Inc. ... 18 */ 19 20 #include <linux/init.h> 21 #include <linux/kernel.h> 22 #include <linux/tty.h> 23 #include <linux/delay.h> 24 #include <linux/platform_device.h> 25 #include <linux/mtd/mtd.h> 26 #include <linux/mtd/partitions.h> 27 #include <linux/timer.h> 28 #include <linux/gpio.h> 29 30 #include <mach/hardware.h> 31 #include <asm/mach-types.h> 32 #include <asm/irq.h> 33 #include <asm/setup.h> 34 #include <mach/collie.h> 35 36 #include <asm/mach/arch.h> 37 #include <asm/mach/flash.h> 38 #include <asm/mach/map.h> 39 #include <asm/mach/serial_sa1100.h> 40 41 #include <asm/hardware/scoop.h> 42 #include <asm/mach/sharpsl_param.h> 43 #include <asm/hardware/locomo.h> 44 #include <mach/mcp.h> 45 46 #include "generic.h" 47 48 static struct resource collie_scoop_resources[] = { 49 [0] = { 50 .start = 0x40800000, 51 .end = 0x40800fff, 52 .flags = IORESOURCE_MEM, 53 }, 54 }; 55 56 static struct scoop_config collie_scoop_setup = { 57 .io_dir = COLLIE_SCOOP_IO_DIR, 58 .io_out = COLLIE_SCOOP_IO_OUT, 59 }; 60 61 struct platform_device colliescoop_device = { 62 .name = "sharp-scoop", 63 .id = -1, 64 .dev = { 65 .platform_data = &collie_scoop_setup, 66 }, 67 .num_resources = ARRAY_SIZE(collie_scoop_resources), 68 .resource = collie_scoop_resources, 69 }; 70 71 static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = { 72 { 73 .dev = &colliescoop_device.dev, 74 .irq = COLLIE_IRQ_GPIO_CF_IRQ, 75 .cd_irq = COLLIE_IRQ_GPIO_CF_CD, 76 .cd_irq_str = "PCMCIA0 CD", 77 }, 78 }; 79 80 static struct scoop_pcmcia_config collie_pcmcia_config = { 81 .devs = &collie_pcmcia_scoop[0], 82 .num_devs = 1, 83 }; 84 85 static struct mcp_plat_data collie_mcp_data = { 86 .mccr0 = MCCR0_ADM | MCCR0_ExtClk, 87 .sclk_rate = 9216000, 88 }; 89 90 #ifdef CONFIG_SHARP_LOCOMO 91 /* 92 * low-level UART features. 93 */ 94 struct platform_device collie_locomo_device; 95 96 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) 97 { 98 if (mctrl & TIOCM_RTS) 99 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); 100 else 101 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); 102 103 if (mctrl & TIOCM_DTR) 104 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); 105 else 106 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1); 107 } 108 109 static u_int collie_uart_get_mctrl(struct uart_port *port) 110 { 111 int ret = TIOCM_CD; 112 unsigned int r; 113 114 r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); 115 if (r == -ENODEV) 116 return ret; 117 if (r & LOCOMO_GPIO_CTS) 118 ret |= TIOCM_CTS; 119 if (r & LOCOMO_GPIO_DSR) 120 ret |= TIOCM_DSR; 121 122 return ret; 123 } 124 125 static struct sa1100_port_fns collie_port_fns __initdata = { 126 .set_mctrl = collie_uart_set_mctrl, 127 .get_mctrl = collie_uart_get_mctrl, 128 }; 129 130 static int collie_uart_probe(struct locomo_dev *dev) 131 { 132 return 0; 133 } 134 135 static int collie_uart_remove(struct locomo_dev *dev) 136 { 137 return 0; 138 } 139 140 static struct locomo_driver collie_uart_driver = { 141 .drv = { 142 .name = "collie_uart", 143 }, 144 .devid = LOCOMO_DEVID_UART, 145 .probe = collie_uart_probe, 146 .remove = collie_uart_remove, 147 }; 148 149 static int __init collie_uart_init(void) 150 { 151 return locomo_driver_register(&collie_uart_driver); 152 } 153 device_initcall(collie_uart_init); 154 155 #endif 156 157 158 static struct resource locomo_resources[] = { 159 [0] = { 160 .start = 0x40000000, 161 .end = 0x40001fff, 162 .flags = IORESOURCE_MEM, 163 }, 164 [1] = { 165 .start = IRQ_GPIO25, 166 .end = IRQ_GPIO25, 167 .flags = IORESOURCE_IRQ, 168 }, 169 }; 170 171 struct platform_device collie_locomo_device = { 172 .name = "locomo", 173 .id = 0, 174 .num_resources = ARRAY_SIZE(locomo_resources), 175 .resource = locomo_resources, 176 }; 177 178 static struct platform_device *devices[] __initdata = { 179 &collie_locomo_device, 180 &colliescoop_device, 181 }; 182 183 static struct mtd_partition collie_partitions[] = { 184 { 185 .name = "bootloader", 186 .offset = 0, 187 .size = 0x000C0000, 188 .mask_flags = MTD_WRITEABLE 189 }, { 190 .name = "kernel", 191 .offset = MTDPART_OFS_APPEND, 192 .size = 0x00100000, 193 }, { 194 .name = "rootfs", 195 .offset = MTDPART_OFS_APPEND, 196 .size = 0x00e20000, 197 } 198 }; 199 200 static int collie_flash_init(void) 201 { 202 int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable"); 203 if (rc) 204 return rc; 205 206 rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1); 207 if (rc) 208 gpio_free(COLLIE_GPIO_VPEN); 209 210 return rc; 211 } 212 213 static void collie_set_vpp(int vpp) 214 { 215 gpio_set_value(COLLIE_GPIO_VPEN, vpp); 216 } 217 218 static void collie_flash_exit(void) 219 { 220 gpio_free(COLLIE_GPIO_VPEN); 221 } 222 223 static struct flash_platform_data collie_flash_data = { 224 .map_name = "cfi_probe", 225 .init = collie_flash_init, 226 .set_vpp = collie_set_vpp, 227 .exit = collie_flash_exit, 228 .parts = collie_partitions, 229 .nr_parts = ARRAY_SIZE(collie_partitions), 230 }; 231 232 static struct resource collie_flash_resources[] = { 233 { 234 .start = SA1100_CS0_PHYS, 235 .end = SA1100_CS0_PHYS + SZ_32M - 1, 236 .flags = IORESOURCE_MEM, 237 } 238 }; 239 240 static void __init collie_init(void) 241 { 242 int ret = 0; 243 244 /* cpu initialize */ 245 GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | 246 GPIO_MCP_CLK | GPIO_32_768kHz; 247 248 GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | 249 GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | 250 GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | 251 COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON | 252 COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz; 253 254 PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | 255 PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | 256 PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; 257 258 PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY | 259 COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC; 260 261 PGSR = COLLIE_GPIO_nREMOCON_ON; 262 263 PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4; 264 265 PCFR = PCFR_OPDE; 266 267 268 platform_scoop_config = &collie_pcmcia_config; 269 270 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 271 if (ret) { 272 printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); 273 } 274 275 sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources, 276 ARRAY_SIZE(collie_flash_resources)); 277 sa11x0_set_mcp_data(&collie_mcp_data); 278 279 sharpsl_save_param(); 280 } 281 282 static struct map_desc collie_io_desc[] __initdata = { 283 { /* 32M main flash (cs0) */ 284 .virtual = 0xe8000000, 285 .pfn = __phys_to_pfn(0x00000000), 286 .length = 0x02000000, 287 .type = MT_DEVICE 288 }, { /* 32M boot flash (cs1) */ 289 .virtual = 0xea000000, 290 .pfn = __phys_to_pfn(0x08000000), 291 .length = 0x02000000, 292 .type = MT_DEVICE 293 } 294 }; 295 296 static void __init collie_map_io(void) 297 { 298 sa1100_map_io(); 299 iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); 300 301 #ifdef CONFIG_SHARP_LOCOMO 302 sa1100_register_uart_fns(&collie_port_fns); 303 #endif 304 sa1100_register_uart(0, 3); 305 sa1100_register_uart(1, 1); 306 } 307 308 MACHINE_START(COLLIE, "Sharp-Collie") 309 .phys_io = 0x80000000, 310 .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, 311 .map_io = collie_map_io, 312 .init_irq = sa1100_init_irq, 313 .timer = &sa1100_timer, 314 .init_machine = collie_init, 315 MACHINE_END 316