1/* 2 * iop13xx platform Initialization 3 * Copyright (c) 2005-2006, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 * Place - Suite 330, Boston, MA 02111-1307 USA. 17 * 18 */ 19 20#include <linux/serial_8250.h> 21#ifdef CONFIG_MTD_PHYSMAP 22#include <linux/mtd/physmap.h> 23#endif 24#include <asm/mach/map.h> 25#include <asm/hardware.h> 26#include <asm/irq.h> 27#include <asm/io.h> 28 29#define IOP13XX_UART_XTAL 33334000 30#define IOP13XX_SETUP_DEBUG 0 31#define PRINTK(x...) ((void)(IOP13XX_SETUP_DEBUG && printk(x))) 32 33/* Standard IO mapping for all IOP13XX based systems 34 */ 35static struct map_desc iop13xx_std_desc[] __initdata = { 36 { /* mem mapped registers */ 37 .virtual = IOP13XX_PMMR_VIRT_MEM_BASE, 38 .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE), 39 .length = IOP13XX_PMMR_SIZE, 40 .type = MT_DEVICE, 41 }, { /* PCIE IO space */ 42 .virtual = IOP13XX_PCIE_LOWER_IO_VA, 43 .pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA), 44 .length = IOP13XX_PCIX_IO_WINDOW_SIZE, 45 .type = MT_DEVICE, 46 }, { /* PCIX IO space */ 47 .virtual = IOP13XX_PCIX_LOWER_IO_VA, 48 .pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA), 49 .length = IOP13XX_PCIX_IO_WINDOW_SIZE, 50 .type = MT_DEVICE, 51 }, 52}; 53 54static struct resource iop13xx_uart0_resources[] = { 55 [0] = { 56 .start = IOP13XX_UART0_PHYS, 57 .end = IOP13XX_UART0_PHYS + 0x3f, 58 .flags = IORESOURCE_MEM, 59 }, 60 [1] = { 61 .start = IRQ_IOP13XX_UART0, 62 .end = IRQ_IOP13XX_UART0, 63 .flags = IORESOURCE_IRQ 64 } 65}; 66 67static struct resource iop13xx_uart1_resources[] = { 68 [0] = { 69 .start = IOP13XX_UART1_PHYS, 70 .end = IOP13XX_UART1_PHYS + 0x3f, 71 .flags = IORESOURCE_MEM, 72 }, 73 [1] = { 74 .start = IRQ_IOP13XX_UART1, 75 .end = IRQ_IOP13XX_UART1, 76 .flags = IORESOURCE_IRQ 77 } 78}; 79 80static struct plat_serial8250_port iop13xx_uart0_data[] = { 81 { 82 .membase = (char*)(IOP13XX_UART0_VIRT), 83 .mapbase = (IOP13XX_UART0_PHYS), 84 .irq = IRQ_IOP13XX_UART0, 85 .uartclk = IOP13XX_UART_XTAL, 86 .regshift = 2, 87 .iotype = UPIO_MEM, 88 .flags = UPF_SKIP_TEST, 89 }, 90 { }, 91}; 92 93static struct plat_serial8250_port iop13xx_uart1_data[] = { 94 { 95 .membase = (char*)(IOP13XX_UART1_VIRT), 96 .mapbase = (IOP13XX_UART1_PHYS), 97 .irq = IRQ_IOP13XX_UART1, 98 .uartclk = IOP13XX_UART_XTAL, 99 .regshift = 2, 100 .iotype = UPIO_MEM, 101 .flags = UPF_SKIP_TEST, 102 }, 103 { }, 104}; 105 106/* The ids are fixed up later in iop13xx_platform_init */ 107static struct platform_device iop13xx_uart0 = { 108 .name = "serial8250", 109 .id = 0, 110 .dev.platform_data = iop13xx_uart0_data, 111 .num_resources = 2, 112 .resource = iop13xx_uart0_resources, 113}; 114 115static struct platform_device iop13xx_uart1 = { 116 .name = "serial8250", 117 .id = 0, 118 .dev.platform_data = iop13xx_uart1_data, 119 .num_resources = 2, 120 .resource = iop13xx_uart1_resources 121}; 122 123static struct resource iop13xx_i2c_0_resources[] = { 124 [0] = { 125 .start = IOP13XX_I2C0_PHYS, 126 .end = IOP13XX_I2C0_PHYS + 0x18, 127 .flags = IORESOURCE_MEM, 128 }, 129 [1] = { 130 .start = IRQ_IOP13XX_I2C_0, 131 .end = IRQ_IOP13XX_I2C_0, 132 .flags = IORESOURCE_IRQ 133 } 134}; 135 136static struct resource iop13xx_i2c_1_resources[] = { 137 [0] = { 138 .start = IOP13XX_I2C1_PHYS, 139 .end = IOP13XX_I2C1_PHYS + 0x18, 140 .flags = IORESOURCE_MEM, 141 }, 142 [1] = { 143 .start = IRQ_IOP13XX_I2C_1, 144 .end = IRQ_IOP13XX_I2C_1, 145 .flags = IORESOURCE_IRQ 146 } 147}; 148 149static struct resource iop13xx_i2c_2_resources[] = { 150 [0] = { 151 .start = IOP13XX_I2C2_PHYS, 152 .end = IOP13XX_I2C2_PHYS + 0x18, 153 .flags = IORESOURCE_MEM, 154 }, 155 [1] = { 156 .start = IRQ_IOP13XX_I2C_2, 157 .end = IRQ_IOP13XX_I2C_2, 158 .flags = IORESOURCE_IRQ 159 } 160}; 161 162/* I2C controllers. The IOP13XX uses the same block as the IOP3xx, so 163 * we just use the same device name. 164 */ 165 166/* The ids are fixed up later in iop13xx_platform_init */ 167static struct platform_device iop13xx_i2c_0_controller = { 168 .name = "IOP3xx-I2C", 169 .id = 0, 170 .num_resources = 2, 171 .resource = iop13xx_i2c_0_resources 172}; 173 174static struct platform_device iop13xx_i2c_1_controller = { 175 .name = "IOP3xx-I2C", 176 .id = 0, 177 .num_resources = 2, 178 .resource = iop13xx_i2c_1_resources 179}; 180 181static struct platform_device iop13xx_i2c_2_controller = { 182 .name = "IOP3xx-I2C", 183 .id = 0, 184 .num_resources = 2, 185 .resource = iop13xx_i2c_2_resources 186}; 187 188#ifdef CONFIG_MTD_PHYSMAP 189/* PBI Flash Device 190 */ 191static struct physmap_flash_data iq8134x_flash_data = { 192 .width = 2, 193}; 194 195static struct resource iq8134x_flash_resource = { 196 .start = IQ81340_FLASHBASE, 197 .end = 0, 198 .flags = IORESOURCE_MEM, 199}; 200 201static struct platform_device iq8134x_flash = { 202 .name = "physmap-flash", 203 .id = 0, 204 .dev = { .platform_data = &iq8134x_flash_data, }, 205 .num_resources = 1, 206 .resource = &iq8134x_flash_resource, 207}; 208 209static unsigned long iq8134x_probe_flash_size(void) 210{ 211 uint8_t __iomem *flash_addr = ioremap(IQ81340_FLASHBASE, PAGE_SIZE); 212 int i; 213 char query[3]; 214 unsigned long size = 0; 215 int width = iq8134x_flash_data.width; 216 217 if (flash_addr) { 218 /* send CFI 'query' command */ 219 writew(0x98, flash_addr); 220 221 /* check for CFI compliance */ 222 for (i = 0; i < 3 * width; i += width) 223 query[i / width] = readb(flash_addr + (0x10 * width) + i); 224 225 /* read the size */ 226 if (memcmp(query, "QRY", 3) == 0) 227 size = 1 << readb(flash_addr + (0x27 * width)); 228 229 /* send CFI 'read array' command */ 230 writew(0xff, flash_addr); 231 232 iounmap(flash_addr); 233 } 234 235 return size; 236} 237#endif 238 239void __init iop13xx_map_io(void) 240{ 241 /* Initialize the Static Page Table maps */ 242 iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc)); 243} 244 245static int init_uart = 0; 246static int init_i2c = 0; 247 248void __init iop13xx_platform_init(void) 249{ 250 int i; 251 u32 uart_idx, i2c_idx, plat_idx; 252 struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES]; 253 254 /* set the bases so we can read the device id */ 255 iop13xx_set_atu_mmr_bases(); 256 257 memset(iop13xx_devices, 0, sizeof(iop13xx_devices)); 258 259 if (init_uart == IOP13XX_INIT_UART_DEFAULT) { 260 switch (iop13xx_dev_id()) { 261 /* enable both uarts on iop341 */ 262 case 0x3380: 263 case 0x3384: 264 case 0x3388: 265 case 0x338c: 266 init_uart |= IOP13XX_INIT_UART_0; 267 init_uart |= IOP13XX_INIT_UART_1; 268 break; 269 /* only enable uart 1 */ 270 default: 271 init_uart |= IOP13XX_INIT_UART_1; 272 } 273 } 274 275 if (init_i2c == IOP13XX_INIT_I2C_DEFAULT) { 276 switch (iop13xx_dev_id()) { 277 /* enable all i2c units on iop341 and iop342 */ 278 case 0x3380: 279 case 0x3384: 280 case 0x3388: 281 case 0x338c: 282 case 0x3382: 283 case 0x3386: 284 case 0x338a: 285 case 0x338e: 286 init_i2c |= IOP13XX_INIT_I2C_0; 287 init_i2c |= IOP13XX_INIT_I2C_1; 288 init_i2c |= IOP13XX_INIT_I2C_2; 289 break; 290 /* only enable i2c 1 and 2 */ 291 default: 292 init_i2c |= IOP13XX_INIT_I2C_1; 293 init_i2c |= IOP13XX_INIT_I2C_2; 294 } 295 } 296 297 plat_idx = 0; 298 uart_idx = 0; 299 i2c_idx = 0; 300 301 /* uart 1 (if enabled) is ttyS0 */ 302 if (init_uart & IOP13XX_INIT_UART_1) { 303 PRINTK("Adding uart1 to platform device list\n"); 304 iop13xx_uart1.id = uart_idx++; 305 iop13xx_devices[plat_idx++] = &iop13xx_uart1; 306 } 307 if (init_uart & IOP13XX_INIT_UART_0) { 308 PRINTK("Adding uart0 to platform device list\n"); 309 iop13xx_uart0.id = uart_idx++; 310 iop13xx_devices[plat_idx++] = &iop13xx_uart0; 311 } 312 313 for(i = 0; i < IQ81340_NUM_I2C; i++) { 314 if ((init_i2c & (1 << i)) && IOP13XX_SETUP_DEBUG) 315 printk("Adding i2c%d to platform device list\n", i); 316 switch(init_i2c & (1 << i)) { 317 case IOP13XX_INIT_I2C_0: 318 iop13xx_i2c_0_controller.id = i2c_idx++; 319 iop13xx_devices[plat_idx++] = 320 &iop13xx_i2c_0_controller; 321 break; 322 case IOP13XX_INIT_I2C_1: 323 iop13xx_i2c_1_controller.id = i2c_idx++; 324 iop13xx_devices[plat_idx++] = 325 &iop13xx_i2c_1_controller; 326 break; 327 case IOP13XX_INIT_I2C_2: 328 iop13xx_i2c_2_controller.id = i2c_idx++; 329 iop13xx_devices[plat_idx++] = 330 &iop13xx_i2c_2_controller; 331 break; 332 } 333 } 334 335#ifdef CONFIG_MTD_PHYSMAP 336 iq8134x_flash_resource.end = iq8134x_flash_resource.start + 337 iq8134x_probe_flash_size() - 1; 338 if (iq8134x_flash_resource.end > iq8134x_flash_resource.start) 339 iop13xx_devices[plat_idx++] = &iq8134x_flash; 340 else 341 printk(KERN_ERR "%s: Failed to probe flash size\n", __FUNCTION__); 342#endif 343 344 platform_add_devices(iop13xx_devices, plat_idx); 345} 346 347static int __init iop13xx_init_uart_setup(char *str) 348{ 349 if (str) { 350 while (*str != '\0') { 351 switch(*str) { 352 case '0': 353 init_uart |= IOP13XX_INIT_UART_0; 354 break; 355 case '1': 356 init_uart |= IOP13XX_INIT_UART_1; 357 break; 358 case ',': 359 case '=': 360 break; 361 default: 362 PRINTK("\"iop13xx_init_uart\" malformed" 363 " at character: \'%c\'", *str); 364 *(str + 1) = '\0'; 365 init_uart = IOP13XX_INIT_UART_DEFAULT; 366 } 367 str++; 368 } 369 } 370 return 1; 371} 372 373static int __init iop13xx_init_i2c_setup(char *str) 374{ 375 if (str) { 376 while (*str != '\0') { 377 switch(*str) { 378 case '0': 379 init_i2c |= IOP13XX_INIT_I2C_0; 380 break; 381 case '1': 382 init_i2c |= IOP13XX_INIT_I2C_1; 383 break; 384 case '2': 385 init_i2c |= IOP13XX_INIT_I2C_2; 386 break; 387 case ',': 388 case '=': 389 break; 390 default: 391 PRINTK("\"iop13xx_init_i2c\" malformed" 392 " at character: \'%c\'", *str); 393 *(str + 1) = '\0'; 394 init_i2c = IOP13XX_INIT_I2C_DEFAULT; 395 } 396 str++; 397 } 398 } 399 return 1; 400} 401 402__setup("iop13xx_init_uart", iop13xx_init_uart_setup); 403__setup("iop13xx_init_i2c", iop13xx_init_i2c_setup); 404