1/* 2 * HND MIPS boards setup routines 3 * 4 * Copyright 2006, Broadcom Corporation 5 * All Rights Reserved. 6 * 7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 11 * 12 * $Id: setup.c,v 1.1.1.1 2008/10/15 03:26:06 james26_jang Exp $ 13 */ 14 15#include <linux/config.h> 16#include <linux/init.h> 17#include <linux/kernel.h> 18#include <linux/serialP.h> 19#include <linux/ide.h> 20#include <asm/bootinfo.h> 21#include <asm/cpu.h> 22#include <asm/time.h> 23#include <asm/reboot.h> 24 25#ifdef CONFIG_MTD_PARTITIONS 26#include <linux/mtd/mtd.h> 27#include <linux/mtd/partitions.h> 28#include <linux/minix_fs.h> 29#include <linux/ext2_fs.h> 30#include <linux/romfs_fs.h> 31#include <linux/cramfs_fs.h> 32#endif 33 34#include <typedefs.h> 35#include <osl.h> 36#include <bcmutils.h> 37#include <bcmnvram.h> 38#include <sbutils.h> 39#include <hndcpu.h> 40#include <sbhndmips.h> 41#include <hndmips.h> 42#include <sbchipc.h> 43#include <hndchipc.h> 44#include <trxhdr.h> 45#include "bcm947xx.h" 46 47extern void bcm947xx_time_init(void); 48extern void bcm947xx_timer_setup(struct irqaction *irq); 49 50#ifdef CONFIG_REMOTE_DEBUG 51extern void set_debug_traps(void); 52extern void rs_kgdb_hook(struct serial_state *); 53extern void breakpoint(void); 54#endif 55 56#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) 57extern struct ide_ops std_ide_ops; 58#endif 59 60/* Global SB handle */ 61sb_t *bcm947xx_sbh = NULL; 62spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; 63EXPORT_SYMBOL(bcm947xx_sbh); 64EXPORT_SYMBOL(bcm947xx_sbh_lock); 65 66/* Convenience */ 67#define sbh bcm947xx_sbh 68#define sbh_lock bcm947xx_sbh_lock 69 70/* Kernel command line */ 71char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; 72 73void 74bcm947xx_machine_restart(char *command) 75{ 76 printk("Please stand by while rebooting the system...\n"); 77 78 /* Set the watchdog timer to reset immediately */ 79 __cli(); 80 hnd_cpu_reset(sbh); 81} 82 83void 84bcm947xx_machine_halt(void) 85{ 86 printk("System halted\n"); 87 88 /* Disable interrupts and watchdog and spin forever */ 89 __cli(); 90 sb_watchdog(sbh, 0); 91 while (1); 92} 93 94#ifdef CONFIG_SERIAL 95 96static struct serial_struct rs = { 97 line: 0, 98 flags: ASYNC_BOOT_AUTOCONF, 99 io_type: SERIAL_IO_MEM, 100}; 101 102static void __init 103serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) 104{ 105 rs.iomem_base = regs; 106 rs.irq = irq + 2; 107 rs.baud_base = baud_base / 16; 108 rs.iomem_reg_shift = reg_shift; 109 110 early_serial_setup(&rs); 111 112 rs.line++; 113} 114 115static void __init 116serial_setup(sb_t *sbh) 117{ 118 sb_serial_init(sbh, serial_add); 119 120#ifdef CONFIG_REMOTE_DEBUG 121 /* Use the last port for kernel debugging */ 122 if (rs.iomem_base) 123 rs_kgdb_hook(&rs); 124#endif 125} 126 127#endif /* CONFIG_SERIAL */ 128 129void __init 130brcm_setup(void) 131{ 132 char *value; 133 134 /* Get global SB handle */ 135 sbh = sb_kattach(SB_OSH); 136 137 /* Initialize clocks and interrupts */ 138 sb_mips_init(sbh, SBMIPS_VIRTIRQ_BASE); 139 140 if (BCM330X(mips_cpu.processor_id) && 141 (read_c0_diag() & BRCM_PFC_AVAIL)) { 142 /* 143 * Now that the sbh is inited set the proper PFC value 144 */ 145 printk("Setting the PFC to its default value\n"); 146 enable_pfc(PFC_AUTO); 147 } 148 149 150#ifdef CONFIG_SERIAL 151 /* Initialize UARTs */ 152 serial_setup(sbh); 153#endif 154 155#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) 156 ide_ops = &std_ide_ops; 157#endif 158 159 /* Override default command line arguments */ 160 value = nvram_get("kernel_args"); 161 if (value && strlen(value) && strncmp(value, "empty", 5)) 162 strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); 163 164 165 /* Generic setup */ 166 _machine_restart = bcm947xx_machine_restart; 167 _machine_halt = bcm947xx_machine_halt; 168 _machine_power_off = bcm947xx_machine_halt; 169 170 board_time_init = bcm947xx_time_init; 171 board_timer_setup = bcm947xx_timer_setup; 172} 173 174const char * 175get_system_type(void) 176{ 177 static char s[32]; 178 179 if (bcm947xx_sbh) { 180 sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh), 181 sb_chiprev(bcm947xx_sbh)); 182 return s; 183 } 184 else 185 return "Broadcom BCM947XX"; 186} 187 188void __init 189bus_error_init(void) 190{ 191} 192 193#ifdef CONFIG_MTD_PARTITIONS 194// Modify by Chen-I 195static struct mtd_partition bcm947xx_parts[] = { 196 { name: "boot", offset: 0, size: 0, }, 197 { name: "linux", offset: 0, size: 0, }, 198 { name: "rootfs", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, 199 { name: "nvram", offset: 0, size: 0, }, 200 { name: NULL, }, 201}; 202 203struct mtd_partition * __init 204init_mtd_partitions(struct mtd_info *mtd, size_t size) 205{ 206 struct minix_super_block *minixsb; 207 struct ext2_super_block *ext2sb; 208 struct romfs_super_block *romfsb; 209 struct squashfs_super_block *squashfsb; 210 struct cramfs_super *cramfsb; 211 struct trx_header *trx; 212 unsigned char buf[512]; 213 int off; 214 size_t len; 215 216 minixsb = (struct minix_super_block *) buf; 217 ext2sb = (struct ext2_super_block *) buf; 218 romfsb = (struct romfs_super_block *) buf; 219 squashfsb = (struct squashfs_super_block *) buf; 220 cramfsb = (struct cramfs_super *) buf; 221 trx = (struct trx_header *) buf; 222 223 /* Look at every 64 KB boundary */ 224 for (off = 0; off < size; off += (64 * 1024)) { 225 memset(buf, 0xe5, sizeof(buf)); 226 227 /* 228 * Read block 0 to test for romfs and cramfs superblock 229 */ 230 if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || 231 len != sizeof(buf)) 232 continue; 233 234 /* Try looking at TRX header for rootfs offset */ 235 if (le32_to_cpu(trx->magic) == TRX_MAGIC) { 236 bcm947xx_parts[1].offset = off; 237// if (le32_to_cpu(trx->offsets[1]) > off) 238 if (le32_to_cpu(trx->offsets[2]) > off) 239 off = le32_to_cpu(trx->offsets[2]); 240 else if (le32_to_cpu(trx->offsets[1]) > off) 241 off = le32_to_cpu(trx->offsets[1]); 242 243 continue; 244 } 245 246 /* romfs is at block zero too */ 247 if (romfsb->word0 == ROMSB_WORD0 && 248 romfsb->word1 == ROMSB_WORD1) { 249 printk(KERN_NOTICE 250 "%s: romfs filesystem found at block %d\n", 251 mtd->name, off / BLOCK_SIZE); 252 goto done; 253 } 254 255 /* squashfs is at block zero too */ 256 if (squashfsb->s_magic == SQUASHFS_MAGIC) { 257 printk(KERN_NOTICE 258 "%s: squashfs filesystem found at block %d\n", 259 mtd->name, off / BLOCK_SIZE); 260 goto done; 261 } 262 263 264 /* so is cramfs */ 265 if (cramfsb->magic == CRAMFS_MAGIC) { 266 printk(KERN_NOTICE 267 "%s: cramfs filesystem found at block %d\n", 268 mtd->name, off / BLOCK_SIZE); 269 goto done; 270 } 271 272 /* 273 * Read block 1 to test for minix and ext2 superblock 274 */ 275 if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) || 276 len != sizeof(buf)) 277 continue; 278 279 /* Try minix */ 280 if (minixsb->s_magic == MINIX_SUPER_MAGIC || 281 minixsb->s_magic == MINIX_SUPER_MAGIC2) { 282 printk(KERN_NOTICE 283 "%s: Minix filesystem found at block %d\n", 284 mtd->name, off / BLOCK_SIZE); 285 goto done; 286 } 287 288 /* Try ext2 */ 289 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { 290 printk(KERN_NOTICE 291 "%s: ext2 filesystem found at block %d\n", 292 mtd->name, off / BLOCK_SIZE); 293 goto done; 294 } 295 } 296 297 printk(KERN_NOTICE 298 "%s: Couldn't find valid ROM disk image\n", 299 mtd->name); 300 301 done: 302 /* Find and size nvram */ 303 bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); 304 bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset; 305 306 /* Find and size rootfs */ 307 if (off < size) { 308 bcm947xx_parts[2].offset = off; 309 bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; 310 } 311 312 /* Size linux (kernel and rootfs) */ 313 bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset; 314 315 /* Size pmon */ 316 bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset; 317 318 return bcm947xx_parts; 319} 320 321EXPORT_SYMBOL(init_mtd_partitions); 322 323#endif 324