1/* 2 * Board setup routines for the Marvell EV-64360-BP Evaluation Board. 3 * 4 * Author: Lee Nicks <allinux@gmail.com> 5 * 6 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il 7 * Based on code done by - Mark A. Greer <mgreer@mvista.com> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14#include <linux/kernel.h> 15#include <linux/pci.h> 16#include <linux/kdev_t.h> 17#include <linux/console.h> 18#include <linux/initrd.h> 19#include <linux/root_dev.h> 20#include <linux/delay.h> 21#include <linux/seq_file.h> 22#include <linux/bootmem.h> 23#include <linux/mtd/physmap.h> 24#include <linux/mv643xx.h> 25#include <linux/platform_device.h> 26#ifdef CONFIG_BOOTIMG 27#include <linux/bootimg.h> 28#endif 29#include <asm/page.h> 30#include <asm/time.h> 31#include <asm/smp.h> 32#include <asm/todc.h> 33#include <asm/bootinfo.h> 34#include <asm/ppcboot.h> 35#include <asm/mv64x60.h> 36#include <asm/machdep.h> 37#include <platforms/ev64360.h> 38 39#define BOARD_VENDOR "Marvell" 40#define BOARD_MACHINE "EV-64360-BP" 41 42static struct mv64x60_handle bh; 43static void __iomem *sram_base; 44 45static u32 ev64360_flash_size_0; 46static u32 ev64360_flash_size_1; 47 48static u32 ev64360_bus_frequency; 49 50unsigned char __res[sizeof(bd_t)]; 51 52TODC_ALLOC(); 53 54static int __init 55ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) 56{ 57 return 0; 58} 59 60static void __init 61ev64360_setup_bridge(void) 62{ 63 struct mv64x60_setup_info si; 64 int i; 65 66 memset(&si, 0, sizeof(si)); 67 68 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE; 69 70 #ifdef CONFIG_PCI 71 si.pci_1.enable_bus = 1; 72 si.pci_1.pci_io.cpu_base = EV64360_PCI1_IO_START_PROC_ADDR; 73 si.pci_1.pci_io.pci_base_hi = 0; 74 si.pci_1.pci_io.pci_base_lo = EV64360_PCI1_IO_START_PCI_ADDR; 75 si.pci_1.pci_io.size = EV64360_PCI1_IO_SIZE; 76 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; 77 si.pci_1.pci_mem[0].cpu_base = EV64360_PCI1_MEM_START_PROC_ADDR; 78 si.pci_1.pci_mem[0].pci_base_hi = EV64360_PCI1_MEM_START_PCI_HI_ADDR; 79 si.pci_1.pci_mem[0].pci_base_lo = EV64360_PCI1_MEM_START_PCI_LO_ADDR; 80 si.pci_1.pci_mem[0].size = EV64360_PCI1_MEM_SIZE; 81 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; 82 si.pci_1.pci_cmd_bits = 0; 83 si.pci_1.latency_timer = 0x80; 84 #else 85 si.pci_0.enable_bus = 0; 86 si.pci_1.enable_bus = 0; 87 #endif 88 89 for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) { 90#if defined(CONFIG_NOT_COHERENT_CACHE) 91 si.cpu_prot_options[i] = 0; 92 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; 93 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; 94 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; 95 96 si.pci_1.acc_cntl_options[i] = 97 MV64360_PCI_ACC_CNTL_SNOOP_NONE | 98 MV64360_PCI_ACC_CNTL_SWAP_NONE | 99 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES | 100 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES; 101#else 102 si.cpu_prot_options[i] = 0; 103 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */ 104 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */ 105 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */ 106 107 si.pci_1.acc_cntl_options[i] = 108 MV64360_PCI_ACC_CNTL_SNOOP_WB | 109 MV64360_PCI_ACC_CNTL_SWAP_NONE | 110 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES | 111 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES; 112#endif 113 } 114 115 if (mv64x60_init(&bh, &si)) 116 printk(KERN_WARNING "Bridge initialization failed.\n"); 117 118 #ifdef CONFIG_PCI 119 pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */ 120 ppc_md.pci_swizzle = common_swizzle; 121 ppc_md.pci_map_irq = ev64360_map_irq; 122 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device; 123 124 mv64x60_set_bus(&bh, 1, 0); 125 bh.hose_b->first_busno = 0; 126 bh.hose_b->last_busno = 0xff; 127 #endif 128} 129 130/* Bridge & platform setup routines */ 131void __init 132ev64360_intr_setup(void) 133{ 134 /* MPP 8, 9, and 10 */ 135 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0xfff); 136 137 /* 138 * Define GPP 8,9,and 10 interrupt polarity as active low 139 * input signal and level triggered 140 */ 141 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, 0x700); 142 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, 0x700); 143 144 /* Config GPP intr ctlr to respond to level trigger */ 145 mv64x60_set_bits(&bh, MV64x60_COMM_ARBITER_CNTL, (1<<10)); 146 147 /* Erranum FEr PCI-#8 */ 148 mv64x60_clr_bits(&bh, MV64x60_PCI0_CMD, (1<<5) | (1<<9)); 149 mv64x60_clr_bits(&bh, MV64x60_PCI1_CMD, (1<<5) | (1<<9)); 150 151 /* 152 * Dismiss and then enable interrupt on GPP interrupt cause 153 * for CPU #0 154 */ 155 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~0x700); 156 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, 0x700); 157 158 /* 159 * Dismiss and then enable interrupt on CPU #0 high cause reg 160 * BIT25 summarizes GPP interrupts 8-15 161 */ 162 mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, (1<<25)); 163} 164 165void __init 166ev64360_setup_peripherals(void) 167{ 168 u32 base; 169 170 /* Set up window for boot CS */ 171 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, 172 EV64360_BOOT_WINDOW_BASE, EV64360_BOOT_WINDOW_SIZE, 0); 173 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN); 174 175 /* We only use the 32-bit flash */ 176 mv64x60_get_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, &base, 177 &ev64360_flash_size_0); 178 ev64360_flash_size_1 = 0; 179 180 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, 181 EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0); 182 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN); 183 184 TODC_INIT(TODC_TYPE_DS1501, 0, 0, 185 ioremap(EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE), 8); 186 187 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN, 188 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0); 189 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN); 190 sram_base = ioremap(EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE); 191 192 /* Set up Enet->SRAM window */ 193 mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN, 194 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0x2); 195 bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN); 196 197 /* Give enet r/w access to memory region */ 198 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_0, (0x3 << (4 << 1))); 199 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_1, (0x3 << (4 << 1))); 200 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_2, (0x3 << (4 << 1))); 201 202 mv64x60_clr_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, (1 << 3)); 203 mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, 204 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24))); 205 206#if defined(CONFIG_NOT_COHERENT_CACHE) 207 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x00160000); 208#else 209 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2); 210#endif 211 212 /* 213 * Setting the SRAM to 0. Note that this generates parity errors on 214 * internal data path in SRAM since it's first time accessing it 215 * while after reset it's not configured. 216 */ 217 memset(sram_base, 0, MV64360_SRAM_SIZE); 218 219 /* set up PCI interrupt controller */ 220 ev64360_intr_setup(); 221} 222 223static void __init 224ev64360_setup_arch(void) 225{ 226 if (ppc_md.progress) 227 ppc_md.progress("ev64360_setup_arch: enter", 0); 228 229 set_tb(0, 0); 230 231#ifdef CONFIG_BLK_DEV_INITRD 232 if (initrd_start) 233 ROOT_DEV = Root_RAM0; 234 else 235#endif 236#ifdef CONFIG_ROOT_NFS 237 ROOT_DEV = Root_NFS; 238#else 239 ROOT_DEV = Root_SDA2; 240#endif 241 242 /* 243 * Set up the L2CR register. 244 */ 245 _set_L2CR(L2CR_L2E | L2CR_L2PE); 246 247 if (ppc_md.progress) 248 ppc_md.progress("ev64360_setup_arch: calling setup_bridge", 0); 249 250 ev64360_setup_bridge(); 251 ev64360_setup_peripherals(); 252 ev64360_bus_frequency = ev64360_bus_freq(); 253 254 printk(KERN_INFO "%s %s port (C) 2005 Lee Nicks " 255 "(allinux@gmail.com)\n", BOARD_VENDOR, BOARD_MACHINE); 256 if (ppc_md.progress) 257 ppc_md.progress("ev64360_setup_arch: exit", 0); 258} 259 260/* Platform device data fixup routines. */ 261#if defined(CONFIG_SERIAL_MPSC) 262static void __init 263ev64360_fixup_mpsc_pdata(struct platform_device *pdev) 264{ 265 struct mpsc_pdata *pdata; 266 267 pdata = (struct mpsc_pdata *)pdev->dev.platform_data; 268 269 pdata->max_idle = 40; 270 pdata->default_baud = EV64360_DEFAULT_BAUD; 271 pdata->brg_clk_src = EV64360_MPSC_CLK_SRC; 272 /* 273 * TCLK (not SysCLk) is routed to BRG, then to the MPSC. On most parts, 274 * TCLK == SysCLK but on 64460, they are separate pins. 275 * SysCLK can go up to 200 MHz but TCLK can only go up to 133 MHz. 276 */ 277 pdata->brg_clk_freq = min(ev64360_bus_frequency, MV64x60_TCLK_FREQ_MAX); 278} 279#endif 280 281#if defined(CONFIG_MV643XX_ETH) 282static void __init 283ev64360_fixup_eth_pdata(struct platform_device *pdev) 284{ 285 struct mv643xx_eth_platform_data *eth_pd; 286 static u16 phy_addr[] = { 287 EV64360_ETH0_PHY_ADDR, 288 EV64360_ETH1_PHY_ADDR, 289 EV64360_ETH2_PHY_ADDR, 290 }; 291 292 eth_pd = pdev->dev.platform_data; 293 eth_pd->force_phy_addr = 1; 294 eth_pd->phy_addr = phy_addr[pdev->id]; 295 eth_pd->tx_queue_size = EV64360_ETH_TX_QUEUE_SIZE; 296 eth_pd->rx_queue_size = EV64360_ETH_RX_QUEUE_SIZE; 297} 298#endif 299 300static int 301ev64360_platform_notify(struct device *dev) 302{ 303 static struct { 304 char *bus_id; 305 void ((*rtn)(struct platform_device *pdev)); 306 } dev_map[] = { 307#if defined(CONFIG_SERIAL_MPSC) 308 { MPSC_CTLR_NAME ".0", ev64360_fixup_mpsc_pdata }, 309 { MPSC_CTLR_NAME ".1", ev64360_fixup_mpsc_pdata }, 310#endif 311#if defined(CONFIG_MV643XX_ETH) 312 { MV643XX_ETH_NAME ".0", ev64360_fixup_eth_pdata }, 313 { MV643XX_ETH_NAME ".1", ev64360_fixup_eth_pdata }, 314 { MV643XX_ETH_NAME ".2", ev64360_fixup_eth_pdata }, 315#endif 316 }; 317 struct platform_device *pdev; 318 int i; 319 320 if (dev && dev->bus_id) 321 for (i=0; i<ARRAY_SIZE(dev_map); i++) 322 if (!strncmp(dev->bus_id, dev_map[i].bus_id, 323 BUS_ID_SIZE)) { 324 325 pdev = container_of(dev, 326 struct platform_device, dev); 327 dev_map[i].rtn(pdev); 328 } 329 330 return 0; 331} 332 333#ifdef CONFIG_MTD_PHYSMAP 334 335#ifndef MB 336#define MB (1 << 20) 337#endif 338 339/* 340 * MTD Layout. 341 * 342 * FLASH Amount: 0xff000000 - 0xffffffff 343 * ------------- ----------------------- 344 * Reserved: 0xff000000 - 0xff03ffff 345 * JFFS2 file system: 0xff040000 - 0xffefffff 346 * U-boot: 0xfff00000 - 0xffffffff 347 */ 348static int __init 349ev64360_setup_mtd(void) 350{ 351 u32 size; 352 int ptbl_entries; 353 static struct mtd_partition *ptbl; 354 355 size = ev64360_flash_size_0 + ev64360_flash_size_1; 356 if (!size) 357 return -ENOMEM; 358 359 ptbl_entries = 3; 360 361 if ((ptbl = kzalloc(ptbl_entries * sizeof(struct mtd_partition), 362 GFP_KERNEL)) == NULL) { 363 364 printk(KERN_WARNING "Can't alloc MTD partition table\n"); 365 return -ENOMEM; 366 } 367 368 ptbl[0].name = "reserved"; 369 ptbl[0].offset = 0; 370 ptbl[0].size = EV64360_MTD_RESERVED_SIZE; 371 ptbl[1].name = "jffs2"; 372 ptbl[1].offset = EV64360_MTD_RESERVED_SIZE; 373 ptbl[1].size = EV64360_MTD_JFFS2_SIZE; 374 ptbl[2].name = "U-BOOT"; 375 ptbl[2].offset = EV64360_MTD_RESERVED_SIZE + EV64360_MTD_JFFS2_SIZE; 376 ptbl[2].size = EV64360_MTD_UBOOT_SIZE; 377 378 physmap_map.size = size; 379 physmap_set_partitions(ptbl, ptbl_entries); 380 return 0; 381} 382 383arch_initcall(ev64360_setup_mtd); 384#endif 385 386static void 387ev64360_restart(char *cmd) 388{ 389 ulong i = 0xffffffff; 390 volatile unsigned char * rtc_base = ioremap(EV64360_RTC_WINDOW_BASE,0x4000); 391 392 /* issue hard reset */ 393 rtc_base[0xf] = 0x80; 394 rtc_base[0xc] = 0x00; 395 rtc_base[0xd] = 0x01; 396 rtc_base[0xf] = 0x83; 397 398 while (i-- > 0) ; 399 panic("restart failed\n"); 400} 401 402static void 403ev64360_halt(void) 404{ 405 while (1) ; 406 /* NOTREACHED */ 407} 408 409static void 410ev64360_power_off(void) 411{ 412 ev64360_halt(); 413 /* NOTREACHED */ 414} 415 416static int 417ev64360_show_cpuinfo(struct seq_file *m) 418{ 419 seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n"); 420 seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n"); 421 seq_printf(m, "bus speed\t: %dMHz\n", ev64360_bus_frequency/1000/1000); 422 423 return 0; 424} 425 426static void __init 427ev64360_calibrate_decr(void) 428{ 429 u32 freq; 430 431 freq = ev64360_bus_frequency / 4; 432 433 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", 434 (long)freq / 1000000, (long)freq % 1000000); 435 436 tb_ticks_per_jiffy = freq / HZ; 437 tb_to_us = mulhwu_scale_factor(freq, 1000000); 438} 439 440unsigned long __init 441ev64360_find_end_of_memory(void) 442{ 443 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE, 444 MV64x60_TYPE_MV64360); 445} 446 447static inline void 448ev64360_set_bat(void) 449{ 450 mb(); 451 mtspr(SPRN_DBAT2U, 0xf0001ffe); 452 mtspr(SPRN_DBAT2L, 0xf000002a); 453 mb(); 454} 455 456#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) 457static void __init 458ev64360_map_io(void) 459{ 460 io_block_mapping(CONFIG_MV64X60_NEW_BASE, \ 461 CONFIG_MV64X60_NEW_BASE, \ 462 0x00020000, _PAGE_IO); 463} 464#endif 465 466void __init 467platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 468 unsigned long r6, unsigned long r7) 469{ 470 parse_bootinfo(find_bootinfo()); 471 472 /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) 473 * are non-zero, then we should use the board info from the bd_t 474 * structure and the cmdline pointed to by r6 instead of the 475 * information from birecs, if any. Otherwise, use the information 476 * from birecs as discovered by the preceding call to 477 * parse_bootinfo(). This rule should work with both PPCBoot, which 478 * uses a bd_t board info structure, and the kernel boot wrapper, 479 * which uses birecs. 480 */ 481 if (r3 && r6) { 482 /* copy board info structure */ 483 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); 484 /* copy command line */ 485 *(char *)(r7+KERNELBASE) = 0; 486 strcpy(cmd_line, (char *)(r6+KERNELBASE)); 487 } 488 #ifdef CONFIG_ISA 489 isa_mem_base = 0; 490 #endif 491 492 ppc_md.setup_arch = ev64360_setup_arch; 493 ppc_md.show_cpuinfo = ev64360_show_cpuinfo; 494 ppc_md.init_IRQ = mv64360_init_irq; 495 ppc_md.get_irq = mv64360_get_irq; 496 ppc_md.restart = ev64360_restart; 497 ppc_md.power_off = ev64360_power_off; 498 ppc_md.halt = ev64360_halt; 499 ppc_md.find_end_of_memory = ev64360_find_end_of_memory; 500 ppc_md.init = NULL; 501 502 ppc_md.time_init = todc_time_init; 503 ppc_md.set_rtc_time = todc_set_rtc_time; 504 ppc_md.get_rtc_time = todc_get_rtc_time; 505 ppc_md.nvram_read_val = todc_direct_read_val; 506 ppc_md.nvram_write_val = todc_direct_write_val; 507 ppc_md.calibrate_decr = ev64360_calibrate_decr; 508 509#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) 510 ppc_md.setup_io_mappings = ev64360_map_io; 511 ppc_md.progress = mv64x60_mpsc_progress; 512 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE); 513#endif 514 515#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) 516 platform_notify = ev64360_platform_notify; 517#endif 518 519 ev64360_set_bat(); /* Need for ev64360_find_end_of_memory and progress */ 520} 521