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 29 #include <mach/hardware.h> 30 #include <asm/mach-types.h> 31 #include <asm/irq.h> 32 #include <asm/setup.h> 33 #include <mach/collie.h> 34 35 #include <asm/mach/arch.h> 36 #include <asm/mach/flash.h> 37 #include <asm/mach/map.h> 38 #include <asm/mach/serial_sa1100.h> 39 40 #include <asm/hardware/scoop.h> 41 #include <asm/mach/sharpsl_param.h> 42 #include <asm/hardware/locomo.h> 43 #include <mach/mcp.h> 44 45 #include "generic.h" 46 47 static struct resource collie_scoop_resources[] = { 48 [0] = { 49 .start = 0x40800000, 50 .end = 0x40800fff, 51 .flags = IORESOURCE_MEM, 52 }, 53 }; 54 55 static struct scoop_config collie_scoop_setup = { 56 .io_dir = COLLIE_SCOOP_IO_DIR, 57 .io_out = COLLIE_SCOOP_IO_OUT, 58 }; 59 60 struct platform_device colliescoop_device = { 61 .name = "sharp-scoop", 62 .id = -1, 63 .dev = { 64 .platform_data = &collie_scoop_setup, 65 }, 66 .num_resources = ARRAY_SIZE(collie_scoop_resources), 67 .resource = collie_scoop_resources, 68 }; 69 70 static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = { 71 { 72 .dev = &colliescoop_device.dev, 73 .irq = COLLIE_IRQ_GPIO_CF_IRQ, 74 .cd_irq = COLLIE_IRQ_GPIO_CF_CD, 75 .cd_irq_str = "PCMCIA0 CD", 76 }, 77 }; 78 79 static struct scoop_pcmcia_config collie_pcmcia_config = { 80 .devs = &collie_pcmcia_scoop[0], 81 .num_devs = 1, 82 }; 83 84 static struct mcp_plat_data collie_mcp_data = { 85 .mccr0 = MCCR0_ADM | MCCR0_ExtClk, 86 .sclk_rate = 9216000, 87 }; 88 89 #ifdef CONFIG_SHARP_LOCOMO 90 /* 91 * low-level UART features. 92 */ 93 struct platform_device collie_locomo_device; 94 95 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) 96 { 97 if (mctrl & TIOCM_RTS) 98 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); 99 else 100 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); 101 102 if (mctrl & TIOCM_DTR) 103 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); 104 else 105 locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1); 106 } 107 108 static u_int collie_uart_get_mctrl(struct uart_port *port) 109 { 110 int ret = TIOCM_CD; 111 unsigned int r; 112 113 r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); 114 if (r == -ENODEV) 115 return ret; 116 if (r & LOCOMO_GPIO_CTS) 117 ret |= TIOCM_CTS; 118 if (r & LOCOMO_GPIO_DSR) 119 ret |= TIOCM_DSR; 120 121 return ret; 122 } 123 124 static struct sa1100_port_fns collie_port_fns __initdata = { 125 .set_mctrl = collie_uart_set_mctrl, 126 .get_mctrl = collie_uart_get_mctrl, 127 }; 128 129 static int collie_uart_probe(struct locomo_dev *dev) 130 { 131 return 0; 132 } 133 134 static int collie_uart_remove(struct locomo_dev *dev) 135 { 136 return 0; 137 } 138 139 static struct locomo_driver collie_uart_driver = { 140 .drv = { 141 .name = "collie_uart", 142 }, 143 .devid = LOCOMO_DEVID_UART, 144 .probe = collie_uart_probe, 145 .remove = collie_uart_remove, 146 }; 147 148 static int __init collie_uart_init(void) { 149 return locomo_driver_register(&collie_uart_driver); 150 } 151 device_initcall(collie_uart_init); 152 153 #endif 154 155 156 static struct resource locomo_resources[] = { 157 [0] = { 158 .start = 0x40000000, 159 .end = 0x40001fff, 160 .flags = IORESOURCE_MEM, 161 }, 162 [1] = { 163 .start = IRQ_GPIO25, 164 .end = IRQ_GPIO25, 165 .flags = IORESOURCE_IRQ, 166 }, 167 }; 168 169 struct platform_device collie_locomo_device = { 170 .name = "locomo", 171 .id = 0, 172 .num_resources = ARRAY_SIZE(locomo_resources), 173 .resource = locomo_resources, 174 }; 175 176 static struct platform_device *devices[] __initdata = { 177 &collie_locomo_device, 178 &colliescoop_device, 179 }; 180 181 static struct mtd_partition collie_partitions[] = { 182 { 183 .name = "bootloader", 184 .offset = 0, 185 .size = 0x000C0000, 186 .mask_flags = MTD_WRITEABLE 187 }, { 188 .name = "kernel", 189 .offset = MTDPART_OFS_APPEND, 190 .size = 0x00100000, 191 }, { 192 .name = "rootfs", 193 .offset = MTDPART_OFS_APPEND, 194 .size = 0x00e20000, 195 } 196 }; 197 198 static void collie_set_vpp(int vpp) 199 { 200 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR) | COLLIE_SCP_VPEN); 201 if (vpp) 202 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) | COLLIE_SCP_VPEN); 203 else 204 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) & ~COLLIE_SCP_VPEN); 205 } 206 207 static struct flash_platform_data collie_flash_data = { 208 .map_name = "cfi_probe", 209 .set_vpp = collie_set_vpp, 210 .parts = collie_partitions, 211 .nr_parts = ARRAY_SIZE(collie_partitions), 212 }; 213 214 static struct resource collie_flash_resources[] = { 215 { 216 .start = SA1100_CS0_PHYS, 217 .end = SA1100_CS0_PHYS + SZ_32M - 1, 218 .flags = IORESOURCE_MEM, 219 } 220 }; 221 222 static void __init collie_init(void) 223 { 224 int ret = 0; 225 226 /* cpu initialize */ 227 GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | 228 GPIO_MCP_CLK | GPIO_32_768kHz; 229 230 GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | 231 GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | 232 GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | 233 COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON | 234 COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz; 235 236 PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | 237 PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | 238 PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; 239 240 PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY | 241 COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC; 242 243 PGSR = COLLIE_GPIO_nREMOCON_ON; 244 245 PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4; 246 247 PCFR = PCFR_OPDE; 248 249 250 platform_scoop_config = &collie_pcmcia_config; 251 252 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 253 if (ret) { 254 printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); 255 } 256 257 sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources, 258 ARRAY_SIZE(collie_flash_resources)); 259 sa11x0_set_mcp_data(&collie_mcp_data); 260 261 sharpsl_save_param(); 262 } 263 264 static struct map_desc collie_io_desc[] __initdata = { 265 { /* 32M main flash (cs0) */ 266 .virtual = 0xe8000000, 267 .pfn = __phys_to_pfn(0x00000000), 268 .length = 0x02000000, 269 .type = MT_DEVICE 270 }, { /* 32M boot flash (cs1) */ 271 .virtual = 0xea000000, 272 .pfn = __phys_to_pfn(0x08000000), 273 .length = 0x02000000, 274 .type = MT_DEVICE 275 } 276 }; 277 278 static void __init collie_map_io(void) 279 { 280 sa1100_map_io(); 281 iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); 282 283 #ifdef CONFIG_SHARP_LOCOMO 284 sa1100_register_uart_fns(&collie_port_fns); 285 #endif 286 sa1100_register_uart(0, 3); 287 sa1100_register_uart(1, 1); 288 } 289 290 MACHINE_START(COLLIE, "Sharp-Collie") 291 .phys_io = 0x80000000, 292 .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, 293 .map_io = collie_map_io, 294 .init_irq = sa1100_init_irq, 295 .timer = &sa1100_timer, 296 .init_machine = collie_init, 297 MACHINE_END 298