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 <asm/hardware.h> 30 #include <asm/mach-types.h> 31 #include <asm/irq.h> 32 #include <asm/setup.h> 33 #include <asm/arch/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 <asm/arch/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 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 return locomo_driver_register(&collie_uart_driver); 151 } 152 device_initcall(collie_uart_init); 153 154 #endif 155 156 157 static struct resource locomo_resources[] = { 158 [0] = { 159 .start = 0x40000000, 160 .end = 0x40001fff, 161 .flags = IORESOURCE_MEM, 162 }, 163 [1] = { 164 .start = IRQ_GPIO25, 165 .end = IRQ_GPIO25, 166 .flags = IORESOURCE_IRQ, 167 }, 168 }; 169 170 struct platform_device collie_locomo_device = { 171 .name = "locomo", 172 .id = 0, 173 .num_resources = ARRAY_SIZE(locomo_resources), 174 .resource = locomo_resources, 175 }; 176 177 static struct platform_device *devices[] __initdata = { 178 &collie_locomo_device, 179 &colliescoop_device, 180 }; 181 182 static struct mtd_partition collie_partitions[] = { 183 { 184 .name = "bootloader", 185 .offset = 0, 186 .size = 0x000C0000, 187 .mask_flags = MTD_WRITEABLE 188 }, { 189 .name = "kernel", 190 .offset = MTDPART_OFS_APPEND, 191 .size = 0x00100000, 192 }, { 193 .name = "rootfs", 194 .offset = MTDPART_OFS_APPEND, 195 .size = 0x00e20000, 196 } 197 }; 198 199 static void collie_set_vpp(int vpp) 200 { 201 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR) | COLLIE_SCP_VPEN); 202 if (vpp) 203 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) | COLLIE_SCP_VPEN); 204 else 205 write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) & ~COLLIE_SCP_VPEN); 206 } 207 208 static struct flash_platform_data collie_flash_data = { 209 .map_name = "cfi_probe", 210 .set_vpp = collie_set_vpp, 211 .parts = collie_partitions, 212 .nr_parts = ARRAY_SIZE(collie_partitions), 213 }; 214 215 static struct resource collie_flash_resources[] = { 216 { 217 .start = SA1100_CS0_PHYS, 218 .end = SA1100_CS0_PHYS + SZ_32M - 1, 219 .flags = IORESOURCE_MEM, 220 } 221 }; 222 223 static void __init collie_init(void) 224 { 225 int ret = 0; 226 227 /* cpu initialize */ 228 GAFR = ( GPIO_SSP_TXD | \ 229 GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | GPIO_TIC_ACK | \ 230 GPIO_32_768kHz ); 231 232 GPDR = ( GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | \ 233 GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | \ 234 GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | \ 235 GPIO_SDLC_AAF | GPIO_UART_SCLK1 | GPIO_32_768kHz ); 236 GPLR = GPIO_GPIO18; 237 238 // PPC pin setting 239 PPDR = ( PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | \ 240 PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | \ 241 PPC_TXD1 | PPC_TXD2 | PPC_RXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM ); 242 243 PSDR = ( PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4 ); 244 245 GAFR |= GPIO_32_768kHz; 246 GPDR |= GPIO_32_768kHz; 247 TUCR = TUCR_32_768kHz; 248 249 platform_scoop_config = &collie_pcmcia_config; 250 251 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 252 if (ret) { 253 printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); 254 } 255 256 sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources, 257 ARRAY_SIZE(collie_flash_resources)); 258 sa11x0_set_mcp_data(&collie_mcp_data); 259 260 sharpsl_save_param(); 261 } 262 263 static struct map_desc collie_io_desc[] __initdata = { 264 { /* 32M main flash (cs0) */ 265 .virtual = 0xe8000000, 266 .pfn = __phys_to_pfn(0x00000000), 267 .length = 0x02000000, 268 .type = MT_DEVICE 269 }, { /* 32M boot flash (cs1) */ 270 .virtual = 0xea000000, 271 .pfn = __phys_to_pfn(0x08000000), 272 .length = 0x02000000, 273 .type = MT_DEVICE 274 } 275 }; 276 277 static void __init collie_map_io(void) 278 { 279 sa1100_map_io(); 280 iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); 281 282 #ifdef CONFIG_SHARP_LOCOMO 283 sa1100_register_uart_fns(&collie_port_fns); 284 #endif 285 sa1100_register_uart(0, 3); 286 sa1100_register_uart(1, 1); 287 } 288 289 MACHINE_START(COLLIE, "Sharp-Collie") 290 .phys_io = 0x80000000, 291 .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, 292 .map_io = collie_map_io, 293 .init_irq = sa1100_init_irq, 294 .timer = &sa1100_timer, 295 .init_machine = collie_init, 296 MACHINE_END 297