1/* linux/arch/arm/mach-s3c2410/mach-bast.c 2 * 3 * Copyright (c) 2003-2005 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * http://www.simtec.co.uk/products/EB2410ITX/ 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 13#include <linux/kernel.h> 14#include <linux/types.h> 15#include <linux/interrupt.h> 16#include <linux/list.h> 17#include <linux/timer.h> 18#include <linux/init.h> 19#include <linux/serial_core.h> 20#include <linux/platform_device.h> 21#include <linux/dm9000.h> 22 23#include <asm/mach/arch.h> 24#include <asm/mach/map.h> 25#include <asm/mach/irq.h> 26 27#include <asm/arch/bast-map.h> 28#include <asm/arch/bast-irq.h> 29#include <asm/arch/bast-cpld.h> 30 31#include <asm/hardware.h> 32#include <asm/io.h> 33#include <asm/irq.h> 34#include <asm/mach-types.h> 35 36//#include <asm/debug-ll.h> 37#include <asm/arch/regs-serial.h> 38#include <asm/arch/regs-gpio.h> 39#include <asm/arch/regs-mem.h> 40#include <asm/arch/regs-lcd.h> 41 42#include <asm/arch/nand.h> 43#include <asm/arch/iic.h> 44#include <asm/arch/fb.h> 45 46#include <linux/mtd/mtd.h> 47#include <linux/mtd/nand.h> 48#include <linux/mtd/nand_ecc.h> 49#include <linux/mtd/partitions.h> 50 51#include <linux/serial_8250.h> 52 53#include <asm/plat-s3c24xx/clock.h> 54#include <asm/plat-s3c24xx/devs.h> 55#include <asm/plat-s3c24xx/cpu.h> 56#include "usb-simtec.h" 57 58#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" 59 60/* macros for virtual address mods for the io space entries */ 61#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5) 62#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4) 63#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3) 64#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2) 65 66/* macros to modify the physical addresses for io space */ 67 68#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) 69#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) 70#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) 71#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) 72 73static struct map_desc bast_iodesc[] __initdata = { 74 /* ISA IO areas */ 75 { 76 .virtual = (u32)S3C24XX_VA_ISA_BYTE, 77 .pfn = PA_CS2(BAST_PA_ISAIO), 78 .length = SZ_16M, 79 .type = MT_DEVICE, 80 }, { 81 .virtual = (u32)S3C24XX_VA_ISA_WORD, 82 .pfn = PA_CS3(BAST_PA_ISAIO), 83 .length = SZ_16M, 84 .type = MT_DEVICE, 85 }, 86 /* bast CPLD control registers, and external interrupt controls */ 87 { 88 .virtual = (u32)BAST_VA_CTRL1, 89 .pfn = __phys_to_pfn(BAST_PA_CTRL1), 90 .length = SZ_1M, 91 .type = MT_DEVICE, 92 }, { 93 .virtual = (u32)BAST_VA_CTRL2, 94 .pfn = __phys_to_pfn(BAST_PA_CTRL2), 95 .length = SZ_1M, 96 .type = MT_DEVICE, 97 }, { 98 .virtual = (u32)BAST_VA_CTRL3, 99 .pfn = __phys_to_pfn(BAST_PA_CTRL3), 100 .length = SZ_1M, 101 .type = MT_DEVICE, 102 }, { 103 .virtual = (u32)BAST_VA_CTRL4, 104 .pfn = __phys_to_pfn(BAST_PA_CTRL4), 105 .length = SZ_1M, 106 .type = MT_DEVICE, 107 }, 108 /* PC104 IRQ mux */ 109 { 110 .virtual = (u32)BAST_VA_PC104_IRQREQ, 111 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ), 112 .length = SZ_1M, 113 .type = MT_DEVICE, 114 }, { 115 .virtual = (u32)BAST_VA_PC104_IRQRAW, 116 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW), 117 .length = SZ_1M, 118 .type = MT_DEVICE, 119 }, { 120 .virtual = (u32)BAST_VA_PC104_IRQMASK, 121 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK), 122 .length = SZ_1M, 123 .type = MT_DEVICE, 124 }, 125 126 /* peripheral space... one for each of fast/slow/byte/16bit */ 127 /* note, ide is only decoded in word space, even though some registers 128 * are only 8bit */ 129 130 /* slow, byte */ 131 { VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 132 { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 133 { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 134 { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 135 { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 136 { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 137 { VA_C2(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 138 139 /* slow, word */ 140 { VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 141 { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 142 { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 143 { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 144 { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 145 { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 146 { VA_C3(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 147 148 /* fast, byte */ 149 { VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 150 { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 151 { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 152 { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 153 { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 154 { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 155 { VA_C4(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 156 157 /* fast, word */ 158 { VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 159 { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 160 { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 161 { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 162 { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 163 { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 164 { VA_C5(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 165}; 166 167#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 168#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 169#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 170 171static struct s3c24xx_uart_clksrc bast_serial_clocks[] = { 172 [0] = { 173 .name = "uclk", 174 .divisor = 1, 175 .min_baud = 0, 176 .max_baud = 0, 177 }, 178 [1] = { 179 .name = "pclk", 180 .divisor = 1, 181 .min_baud = 0, 182 .max_baud = 0, 183 } 184}; 185 186 187static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { 188 [0] = { 189 .hwport = 0, 190 .flags = 0, 191 .ucon = UCON, 192 .ulcon = ULCON, 193 .ufcon = UFCON, 194 .clocks = bast_serial_clocks, 195 .clocks_size = ARRAY_SIZE(bast_serial_clocks), 196 }, 197 [1] = { 198 .hwport = 1, 199 .flags = 0, 200 .ucon = UCON, 201 .ulcon = ULCON, 202 .ufcon = UFCON, 203 .clocks = bast_serial_clocks, 204 .clocks_size = ARRAY_SIZE(bast_serial_clocks), 205 }, 206 /* port 2 is not actually used */ 207 [2] = { 208 .hwport = 2, 209 .flags = 0, 210 .ucon = UCON, 211 .ulcon = ULCON, 212 .ufcon = UFCON, 213 .clocks = bast_serial_clocks, 214 .clocks_size = ARRAY_SIZE(bast_serial_clocks), 215 } 216}; 217 218/* NOR Flash on BAST board */ 219 220static struct resource bast_nor_resource[] = { 221 [0] = { 222 .start = S3C2410_CS1 + 0x4000000, 223 .end = S3C2410_CS1 + 0x4000000 + (32*1024*1024) - 1, 224 .flags = IORESOURCE_MEM, 225 } 226}; 227 228static struct platform_device bast_device_nor = { 229 .name = "bast-nor", 230 .id = -1, 231 .num_resources = ARRAY_SIZE(bast_nor_resource), 232 .resource = bast_nor_resource, 233}; 234 235/* NAND Flash on BAST board */ 236 237 238static int smartmedia_map[] = { 0 }; 239static int chip0_map[] = { 1 }; 240static int chip1_map[] = { 2 }; 241static int chip2_map[] = { 3 }; 242 243static struct mtd_partition bast_default_nand_part[] = { 244 [0] = { 245 .name = "Boot Agent", 246 .size = SZ_16K, 247 .offset = 0, 248 }, 249 [1] = { 250 .name = "/boot", 251 .size = SZ_4M - SZ_16K, 252 .offset = SZ_16K, 253 }, 254 [2] = { 255 .name = "user", 256 .offset = SZ_4M, 257 .size = MTDPART_SIZ_FULL, 258 } 259}; 260 261/* the bast has 4 selectable slots for nand-flash, the three 262 * on-board chip areas, as well as the external SmartMedia 263 * slot. 264 * 265 * Note, there is no current hot-plug support for the SmartMedia 266 * socket. 267*/ 268 269static struct s3c2410_nand_set bast_nand_sets[] = { 270 [0] = { 271 .name = "SmartMedia", 272 .nr_chips = 1, 273 .nr_map = smartmedia_map, 274 .nr_partitions = ARRAY_SIZE(bast_default_nand_part), 275 .partitions = bast_default_nand_part, 276 }, 277 [1] = { 278 .name = "chip0", 279 .nr_chips = 1, 280 .nr_map = chip0_map, 281 .nr_partitions = ARRAY_SIZE(bast_default_nand_part), 282 .partitions = bast_default_nand_part, 283 }, 284 [2] = { 285 .name = "chip1", 286 .nr_chips = 1, 287 .nr_map = chip1_map, 288 .nr_partitions = ARRAY_SIZE(bast_default_nand_part), 289 .partitions = bast_default_nand_part, 290 }, 291 [3] = { 292 .name = "chip2", 293 .nr_chips = 1, 294 .nr_map = chip2_map, 295 .nr_partitions = ARRAY_SIZE(bast_default_nand_part), 296 .partitions = bast_default_nand_part, 297 } 298}; 299 300static void bast_nand_select(struct s3c2410_nand_set *set, int slot) 301{ 302 unsigned int tmp; 303 304 slot = set->nr_map[slot] & 3; 305 306 pr_debug("bast_nand: selecting slot %d (set %p,%p)\n", 307 slot, set, set->nr_map); 308 309 tmp = __raw_readb(BAST_VA_CTRL2); 310 tmp &= BAST_CPLD_CTLR2_IDERST; 311 tmp |= slot; 312 tmp |= BAST_CPLD_CTRL2_WNAND; 313 314 pr_debug("bast_nand: ctrl2 now %02x\n", tmp); 315 316 __raw_writeb(tmp, BAST_VA_CTRL2); 317} 318 319static struct s3c2410_platform_nand bast_nand_info = { 320 .tacls = 30, 321 .twrph0 = 60, 322 .twrph1 = 60, 323 .nr_sets = ARRAY_SIZE(bast_nand_sets), 324 .sets = bast_nand_sets, 325 .select_chip = bast_nand_select, 326}; 327 328/* DM9000 */ 329 330static struct resource bast_dm9k_resource[] = { 331 [0] = { 332 .start = S3C2410_CS5 + BAST_PA_DM9000, 333 .end = S3C2410_CS5 + BAST_PA_DM9000 + 3, 334 .flags = IORESOURCE_MEM, 335 }, 336 [1] = { 337 .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40, 338 .end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f, 339 .flags = IORESOURCE_MEM, 340 }, 341 [2] = { 342 .start = IRQ_DM9000, 343 .end = IRQ_DM9000, 344 .flags = IORESOURCE_IRQ, 345 } 346 347}; 348 349/* for the moment we limit ourselves to 16bit IO until some 350 * better IO routines can be written and tested 351*/ 352 353static struct dm9000_plat_data bast_dm9k_platdata = { 354 .flags = DM9000_PLATF_16BITONLY, 355}; 356 357static struct platform_device bast_device_dm9k = { 358 .name = "dm9000", 359 .id = 0, 360 .num_resources = ARRAY_SIZE(bast_dm9k_resource), 361 .resource = bast_dm9k_resource, 362 .dev = { 363 .platform_data = &bast_dm9k_platdata, 364 } 365}; 366 367/* serial devices */ 368 369#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO) 370#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ) 371#define SERIAL_CLK (1843200) 372 373static struct plat_serial8250_port bast_sio_data[] = { 374 [0] = { 375 .mapbase = SERIAL_BASE + 0x2f8, 376 .irq = IRQ_PCSERIAL1, 377 .flags = SERIAL_FLAGS, 378 .iotype = UPIO_MEM, 379 .regshift = 0, 380 .uartclk = SERIAL_CLK, 381 }, 382 [1] = { 383 .mapbase = SERIAL_BASE + 0x3f8, 384 .irq = IRQ_PCSERIAL2, 385 .flags = SERIAL_FLAGS, 386 .iotype = UPIO_MEM, 387 .regshift = 0, 388 .uartclk = SERIAL_CLK, 389 }, 390 { } 391}; 392 393static struct platform_device bast_sio = { 394 .name = "serial8250", 395 .id = PLAT8250_DEV_PLATFORM, 396 .dev = { 397 .platform_data = &bast_sio_data, 398 }, 399}; 400 401/* we have devices on the bus which cannot work much over the 402 * standard 100KHz i2c bus frequency 403*/ 404 405static struct s3c2410_platform_i2c bast_i2c_info = { 406 .flags = 0, 407 .slave_addr = 0x10, 408 .bus_freq = 100*1000, 409 .max_freq = 130*1000, 410}; 411 412 413static struct s3c2410fb_mach_info __initdata bast_lcd_info = { 414 .width = 640, 415 .height = 480, 416 417 .xres = { 418 .min = 320, 419 .max = 1024, 420 .defval = 640, 421 }, 422 423 .yres = { 424 .min = 240, 425 .max = 600, 426 .defval = 480, 427 }, 428 429 .bpp = { 430 .min = 4, 431 .max = 16, 432 .defval = 8, 433 }, 434 435 .regs = { 436 .lcdcon1 = 0x00000176, 437 .lcdcon2 = 0x1d77c7c2, 438 .lcdcon3 = 0x013a7f13, 439 .lcdcon4 = 0x00000057, 440 .lcdcon5 = 0x00014b02, 441 } 442}; 443 444/* Standard BAST devices */ 445 446static struct platform_device *bast_devices[] __initdata = { 447 &s3c_device_usb, 448 &s3c_device_lcd, 449 &s3c_device_wdt, 450 &s3c_device_i2c, 451 &s3c_device_iis, 452 &s3c_device_rtc, 453 &s3c_device_nand, 454 &bast_device_nor, 455 &bast_device_dm9k, 456 &bast_sio, 457}; 458 459static struct clk *bast_clocks[] = { 460 &s3c24xx_dclk0, 461 &s3c24xx_dclk1, 462 &s3c24xx_clkout0, 463 &s3c24xx_clkout1, 464 &s3c24xx_uclk, 465}; 466 467static void __init bast_map_io(void) 468{ 469 /* initialise the clocks */ 470 471 s3c24xx_dclk0.parent = NULL; 472 s3c24xx_dclk0.rate = 12*1000*1000; 473 474 s3c24xx_dclk1.parent = NULL; 475 s3c24xx_dclk1.rate = 24*1000*1000; 476 477 s3c24xx_clkout0.parent = &s3c24xx_dclk0; 478 s3c24xx_clkout1.parent = &s3c24xx_dclk1; 479 480 s3c24xx_uclk.parent = &s3c24xx_clkout1; 481 482 s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); 483 484 s3c_device_nand.dev.platform_data = &bast_nand_info; 485 s3c_device_i2c.dev.platform_data = &bast_i2c_info; 486 487 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); 488 s3c24xx_init_clocks(0); 489 s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); 490 491 usb_simtec_init(); 492} 493 494static void __init bast_init(void) 495{ 496 s3c24xx_fb_set_platdata(&bast_lcd_info); 497 platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); 498} 499 500MACHINE_START(BAST, "Simtec-BAST") 501 /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ 502 .phys_io = S3C2410_PA_UART, 503 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 504 .boot_params = S3C2410_SDRAM_PA + 0x100, 505 .map_io = bast_map_io, 506 .init_irq = s3c24xx_init_irq, 507 .init_machine = bast_init, 508 .timer = &s3c24xx_timer, 509MACHINE_END 510