2 #include <linux/types.h>
3 #include <linux/version.h>
4 #include <linux/init.h>
5 #include <linux/platform_device.h>
8 #include <asm/mach-types.h>
9 #include <asm/mach/arch.h>
10 #include <asm/mach/time.h>
11 #include <asm/clkdev.h>
13 #include <mach/clkdev.h>
14 #include <mach/hardware.h>
15 #include <mach/memory.h>
16 #include <mach/io_map.h>
19 #include <plat/mpcore.h>
20 #include <plat/plat-bcm5301x.h>
22 #ifdef CONFIG_MTD_PARTITIONS
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/nand.h>
25 #include <linux/mtd/partitions.h>
26 #include <linux/romfs_fs.h>
27 #include <linux/cramfs_fs.h>
28 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
29 #include <linux/squashfs_fs.h>
31 /* #include <magic.h> */
39 #include <bcmendian.h>
48 #include <ctf/hndctf.h>
50 #include <hndsflash.h>
51 #ifdef CONFIG_MTD_NFLASH
55 extern char __initdata saved_root_name
[];
57 /* Global SB handle */
58 si_t
*bcm947xx_sih
= NULL
;
59 spinlock_t bcm947xx_sih_lock
= SPIN_LOCK_UNLOCKED
;
60 EXPORT_SYMBOL(bcm947xx_sih
);
61 EXPORT_SYMBOL(bcm947xx_sih_lock
);
64 #define sih bcm947xx_sih
65 #define sih_lock bcm947xx_sih_lock
67 #define WATCHDOG_MIN 3000 /* milliseconds */
68 extern int panic_timeout
;
69 extern int panic_on_oops
;
70 static int watchdog
= 0;
75 ctf_attach_t ctf_attach_fn
= NULL
;
76 EXPORT_SYMBOL(ctf_attach_fn
);
80 struct dummy_super_block
{
84 /* This is the main reference clock 25MHz from external crystal */
85 static struct clk clk_ref
= {
87 .rate
= 25 * 1000000, /* run-time override */
93 static struct clk_lookup board_clk_lookups
[] = {
102 void __init
board_map_io(void)
104 early_printk("board_map_io\n");
105 /* Install clock sources into the lookup table */
106 clkdev_add_table(board_clk_lookups
,
107 ARRAY_SIZE(board_clk_lookups
));
109 /* Map SoC specific I/O */
110 soc_map_io( &clk_ref
);
114 void __init
board_init_irq(void)
116 early_printk("board_init_irq\n");
119 /* serial_setup(sih); */
122 void board_init_timer(void)
124 early_printk("board_init_timer\n");
128 static int __init
rootfs_mtdblock(void)
133 #ifdef CONFIG_FAILSAFE_UPGRADE
134 char *img_boot
= nvram_get(BOOTPARTITION
);
137 bootdev
= soc_boot_dev((void *)sih
);
138 knldev
= soc_knl_dev((void *)sih
);
141 if (bootdev
== SOC_BOOTDEV_NANDFLASH
&&
142 knldev
== SOC_KNLDEV_NANDFLASH
) {
143 #ifdef CONFIG_FAILSAFE_UPGRADE
144 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
153 /* SFLASH/PFLASH only */
154 if (bootdev
!= SOC_BOOTDEV_NANDFLASH
&&
155 knldev
!= SOC_KNLDEV_NANDFLASH
) {
156 #ifdef CONFIG_FAILSAFE_UPGRADE
157 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
169 #ifdef CONFIG_FAILSAFE_UPGRADE
170 if (img_boot
&& simple_strtol(img_boot
, NULL
, 10))
173 /* Boot from norflash and kernel in nandflash */
177 static void __init
brcm_setup(void)
179 /* Get global SB handle */
180 sih
= si_kattach(SI_OSH
);
182 if (strncmp(boot_command_line
, "root=/dev/mtdblock", strlen("root=/dev/mtdblock")) == 0)
183 sprintf(saved_root_name
, "/dev/mtdblock%d", rootfs_mtdblock());
185 /* Set watchdog interval in ms */
186 watchdog
= simple_strtoul(nvram_safe_get("watchdog"), NULL
, 0);
188 /* Ensure at least WATCHDOG_MIN */
189 if ((watchdog
> 0) && (watchdog
< WATCHDOG_MIN
))
190 watchdog
= WATCHDOG_MIN
;
192 /* Set panic timeout in seconds */
193 panic_timeout
= watchdog
/ 1000;
194 panic_on_oops
= watchdog
/ 1000;
197 void soc_watchdog(void)
200 si_watchdog_ms(sih
, watchdog
);
203 #define CFE_UPDATE 1 // added by Chen-I for mac/regulation update
206 void bcm947xx_watchdog_disable(void)
209 si_watchdog_ms(sih
, 0);
213 void __init
board_init(void)
215 early_printk("board_init\n");
218 * Add common platform devices that do not have board dependent HW
226 static void __init
board_fixup(
227 struct machine_desc
*desc
,
233 u32 mem_size
, lo_size
;
234 early_printk("board_fixup\n" );
236 /* Fuxup reference clock rate */
237 if (desc
->nr
== MACH_TYPE_BRCM_NS_QT
)
238 clk_ref
.rate
= 17594; /* Emulator ref clock rate */
243 early_printk("board_fixup: mem=%uMiB\n", mem_size
>> 20);
245 lo_size
= min(mem_size
, DRAM_MEMORY_REGION_SIZE
);
247 mi
->bank
[0].start
= PHYS_OFFSET
;
248 mi
->bank
[0].size
= lo_size
;
251 if (lo_size
== mem_size
)
254 mi
->bank
[1].start
= PHYS_OFFSET2
;
255 mi
->bank
[1].size
= mem_size
- lo_size
;
259 #ifdef CONFIG_ZONE_DMA
261 * Adjust the zones if there are restrictions for DMA access.
263 void __init
bcm47xx_adjust_zones(unsigned long *size
, unsigned long *hole
)
265 unsigned long dma_size
= SZ_128M
>> PAGE_SHIFT
;
267 if (size
[0] <= dma_size
)
270 size
[ZONE_NORMAL
] = size
[0] - dma_size
;
271 size
[ZONE_DMA
] = dma_size
;
272 hole
[ZONE_NORMAL
] = hole
[0];
275 #endif /* CONFIG_ZONE_DMA */
277 static struct sys_timer board_timer
= {
278 .init
= board_init_timer
,
281 #if (( (IO_BASE_VA >>18) & 0xfffc) != 0x3c40)
285 MACHINE_START(BRCM_NS
, "Northstar Prototype")
286 .phys_io
= /* UART I/O mapping */
288 .io_pg_offst
= /* for early debug */
289 (IO_BASE_VA
>>18) & 0xfffc,
290 .fixup
= board_fixup
, /* Opt. early setup_arch() */
291 .map_io
= board_map_io
, /* Opt. from setup_arch() */
292 .init_irq
= board_init_irq
, /* main.c after setup_arch() */
293 .timer
= &board_timer
, /* main.c after IRQs */
294 .init_machine
= board_init
, /* Late archinitcall */
295 .boot_params
= CONFIG_BOARD_PARAMS_PHYS
,
298 #ifdef CONFIG_MACH_BRCM_NS_QT
299 MACHINE_START(BRCM_NS_QT
, "Northstar Emulation Model")
300 .phys_io
= /* UART I/O mapping */
302 .io_pg_offst
= /* for early debug */
303 (IO_BASE_VA
>>18) & 0xfffc,
304 .fixup
= board_fixup
, /* Opt. early setup_arch() */
305 .map_io
= board_map_io
, /* Opt. from setup_arch() */
306 .init_irq
= board_init_irq
, /* main.c after setup_arch() */
307 .timer
= &board_timer
, /* main.c after IRQs */
308 .init_machine
= board_init
, /* Late archinitcall */
309 .boot_params
= CONFIG_BOARD_PARAMS_PHYS
,
313 void arch_reset(char mode
, const char *cmd
)
315 #ifdef CONFIG_OUTER_CACHE_SYNC
316 outer_cache
.sync
= NULL
;
321 #ifdef CONFIG_MTD_PARTITIONS
323 static spinlock_t
*mtd_lock
= NULL
;
325 spinlock_t
*partitions_lock_init(void)
328 mtd_lock
= (spinlock_t
*)kzalloc(sizeof(spinlock_t
), GFP_KERNEL
);
332 spin_lock_init( mtd_lock
);
336 EXPORT_SYMBOL(partitions_lock_init
);
338 static struct nand_hw_control
*nand_hwcontrol
= NULL
;
339 struct nand_hw_control
*nand_hwcontrol_lock_init(void)
341 if (!nand_hwcontrol
) {
342 nand_hwcontrol
= (struct nand_hw_control
*)kzalloc(sizeof(struct nand_hw_control
), GFP_KERNEL
);
346 spin_lock_init(&nand_hwcontrol
->lock
);
347 init_waitqueue_head(&nand_hwcontrol
->wq
);
349 return nand_hwcontrol
;
351 EXPORT_SYMBOL(nand_hwcontrol_lock_init
);
353 /* Find out prom size */
354 static uint32
boot_partition_size(uint32 flash_phys
) {
355 uint32 bootsz
, *bisz
;
357 /* Default is 256K boot partition */
360 /* Do we have a self-describing binary image? */
361 bisz
= (uint32
*)(flash_phys
+ BISZ_OFFSET
);
362 if (bisz
[BISZ_MAGIC_IDX
] == BISZ_MAGIC
) {
363 int isz
= bisz
[BISZ_DATAEND_IDX
] - bisz
[BISZ_TXTST_IDX
];
365 if (isz
> (1024 * 1024))
366 bootsz
= 2048 * 1024;
367 else if (isz
> (512 * 1024))
368 bootsz
= 1024 * 1024;
369 else if (isz
> (256 * 1024))
371 else if (isz
<= (128 * 1024))
377 #if defined(BCMCONFMTD)
387 #if defined(CONFIG_FAILSAFE_UPGRADE)
388 #define FAILSAFE_PARTS 2
390 #define FAILSAFE_PARTS 0
392 #if defined(CONFIG_CRASHLOG)
393 #define CRASHLOG_PARTS 1
395 #define CRASHLOG_PARTS 0
397 /* boot;nvram;kernel;rootfs;empty */
398 #define FLASH_PARTS_NUM (5+MTD_PARTS+PLC_PARTS+FAILSAFE_PARTS+CRASHLOG_PARTS)
400 static struct mtd_partition bcm947xx_flash_parts
[FLASH_PARTS_NUM
] = {{0}};
402 static uint
lookup_flash_rootfs_offset(struct mtd_info
*mtd
, int *trx_off
, size_t size
,
405 struct romfs_super_block
*romfsb
;
406 struct cramfs_super
*cramfsb
;
407 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
408 struct squashfs_super_block
*squashfsb
;
410 struct dummy_super_block
*squashfsb
;
412 struct trx_header
*trx
;
413 unsigned char buf
[512];
417 romfsb
= (struct romfs_super_block
*) buf
;
418 cramfsb
= (struct cramfs_super
*) buf
;
419 squashfsb
= (void *) buf
;
420 trx
= (struct trx_header
*) buf
;
422 /* Look at every 64 KB boundary */
423 for (off
= *trx_off
; off
< size
; off
+= (64 * 1024)) {
424 memset(buf
, 0xe5, sizeof(buf
));
427 * Read block 0 to test for romfs and cramfs superblock
429 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) ||
433 /* Try looking at TRX header for rootfs offset */
434 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
436 *trx_size
= le32_to_cpu(trx
->len
);
437 if (trx
->offsets
[1] == 0)
440 * Read to test for romfs and cramfs superblock
442 off
+= le32_to_cpu(trx
->offsets
[1]);
443 memset(buf
, 0xe5, sizeof(buf
));
444 if (mtd
->read(mtd
, off
, sizeof(buf
), &len
, buf
) || len
!= sizeof(buf
))
448 /* romfs is at block zero too */
449 if (romfsb
->word0
== ROMSB_WORD0
&&
450 romfsb
->word1
== ROMSB_WORD1
) {
452 "%s: romfs filesystem found at block %d\n",
453 mtd
->name
, off
/ mtd
->erasesize
);
458 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
460 "%s: cramfs filesystem found at block %d\n",
461 mtd
->name
, off
/ mtd
->erasesize
);
465 if (squashfsb
->s_magic
== SQUASHFS_MAGIC
) {
467 "%s: squash filesystem found at block %d\n",
468 mtd
->name
, off
/ mtd
->erasesize
);
476 struct mtd_partition
*
477 init_mtd_partitions(hndsflash_t
*sfl_info
, struct mtd_info
*mtd
, size_t size
)
485 uint vmlz_off
, knl_size
;
489 #ifdef CONFIG_CRASHLOG
490 char create_crash_partition
= 0;
492 #ifdef CONFIG_FAILSAFE_UPGRADE
493 char *img_boot
= nvram_get(BOOTPARTITION
);
494 char *imag_1st_offset
= nvram_get(IMAGE_FIRST_OFFSET
);
495 char *imag_2nd_offset
= nvram_get(IMAGE_SECOND_OFFSET
);
496 unsigned int image_first_offset
= 0;
497 unsigned int image_second_offset
= 0;
498 char dual_image_on
= 0;
500 /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
503 dual_image_on
= (img_boot
!= NULL
&& imag_1st_offset
!= NULL
&& imag_2nd_offset
!= NULL
);
506 image_first_offset
= simple_strtol(imag_1st_offset
, NULL
, 10);
507 image_second_offset
= simple_strtol(imag_2nd_offset
, NULL
, 10);
508 printk("The first offset=%x, 2nd offset=%x\n", image_first_offset
,
509 image_second_offset
);
512 #endif /* CONFIG_FAILSAFE_UPGRADE */
514 /* limit size for R6300V2/R6250 */
515 if (nvram_match("boardnum", "679") && nvram_match("boardtype", "0x0646")
516 && nvram_match("boardrev", "0x1110")) {
521 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665")
522 && nvram_match("boardrev", "0x1301")) {
527 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0646")
528 && nvram_match("boardrev", "0x1601")) {
533 bootdev
= soc_boot_dev((void *)sih
);
534 knldev
= soc_knl_dev((void *)sih
);
536 if (bootdev
== SOC_BOOTDEV_NANDFLASH
) {
537 /* Do not init MTD partitions on NOR flash when NAND boot */
541 if (knldev
!= SOC_KNLDEV_NANDFLASH
) {
543 rfs_off
= lookup_flash_rootfs_offset(mtd
, &vmlz_off
, size
, &trx_size
);
546 bcm947xx_flash_parts
[nparts
].name
= "boot";
547 bcm947xx_flash_parts
[nparts
].size
= vmlz_off
;
548 bcm947xx_flash_parts
[nparts
].offset
= top
;
549 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
552 /* Setup kernel MTD partition */
553 bcm947xx_flash_parts
[nparts
].name
= "linux";
554 #ifdef CONFIG_FAILSAFE_UPGRADE
555 if (trx_size
> (image_second_offset
-image_first_offset
)) {
556 printk("sflash size is too small to afford two images.\n");
558 image_first_offset
= 0;
559 image_second_offset
= 0;
562 bcm947xx_flash_parts
[nparts
].size
= image_second_offset
-image_first_offset
;
564 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- vmlz_off
;
566 /* Reserve for NVRAM */
567 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(nvram_space
, mtd
->erasesize
);
569 /* Reserve for PLC */
570 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
573 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
578 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- vmlz_off
;
581 /* Reserve for PLC */
582 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
584 /* Reserve for NVRAM */
585 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(nvram_space
, mtd
->erasesize
);
588 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
590 #endif /* CONFIG_FAILSAFE_UPGRADE */
592 /* Reserve for board_data */
593 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665")
594 && nvram_match("boardrev", "0x1301") && nvram_match("model", "R1D")) {
595 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x10000, mtd
->erasesize
);
599 #ifdef CONFIG_CRASHLOG
600 if ((bcm947xx_flash_parts
[nparts
].size
- trx_size
) >=
601 ROUNDUP(0x4000, mtd
->erasesize
)) {
602 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x4000, mtd
->erasesize
);
603 create_crash_partition
= 1;
605 create_crash_partition
= 0;
609 bcm947xx_flash_parts
[nparts
].offset
= vmlz_off
;
610 knl_size
= bcm947xx_flash_parts
[nparts
].size
;
611 offset
= bcm947xx_flash_parts
[nparts
].offset
+ knl_size
;
614 /* Setup rootfs MTD partition */
615 bcm947xx_flash_parts
[nparts
].name
= "rootfs";
616 bcm947xx_flash_parts
[nparts
].size
= knl_size
- (rfs_off
- vmlz_off
);
617 bcm947xx_flash_parts
[nparts
].offset
= rfs_off
;
618 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
; /* forces on read only */
619 offset
= bcm947xx_flash_parts
[nparts
].offset
+ bcm947xx_flash_parts
[nparts
].size
;
622 #if defined(CONFIG_CRASHLOG) && defined(BCMDBG)
623 if (create_crash_partition
) {
624 /* Setup crash MTD partition */
625 bcm947xx_flash_parts
[nparts
].name
= "crash";
626 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(0x4000, mtd
->erasesize
);
627 bcm947xx_flash_parts
[nparts
].offset
= offset
;
628 bcm947xx_flash_parts
[nparts
].mask_flags
= 0;
632 #ifdef CONFIG_FAILSAFE_UPGRADE
634 offset
= image_second_offset
;
635 rfs_off
= lookup_flash_rootfs_offset(mtd
, &offset
, size
, &trx_size
);
636 /* When the second image doesn't exist,
637 * set the rootfs use the same offset with the kernel
643 /* Setup kernel2 MTD partition */
644 bcm947xx_flash_parts
[nparts
].name
= "linux2";
645 bcm947xx_flash_parts
[nparts
].size
= mtd
->size
- image_second_offset
;
646 /* Reserve for NVRAM */
647 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(nvram_space
, mtd
->erasesize
);
650 bcm947xx_flash_parts
[nparts
].size
-= (mtd
->erasesize
*4);
653 /* Reserve for PLC */
654 bcm947xx_flash_parts
[nparts
].size
-= ROUNDUP(0x1000, mtd
->erasesize
);
656 bcm947xx_flash_parts
[nparts
].offset
= image_second_offset
;
657 knl_size
= bcm947xx_flash_parts
[nparts
].size
;
658 offset
= bcm947xx_flash_parts
[nparts
].offset
+ knl_size
;
661 /* Setup rootfs MTD partition */
662 bcm947xx_flash_parts
[nparts
].name
= "rootfs2";
663 bcm947xx_flash_parts
[nparts
].size
=
664 knl_size
- (rfs_off
- image_second_offset
);
665 bcm947xx_flash_parts
[nparts
].offset
= rfs_off
;
666 /* forces on read only */
667 bcm947xx_flash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
670 #endif /* CONFIG_FAILSAFE_UPGRADE */
673 bootsz
= boot_partition_size(sfl_info
->base
);
674 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
678 bcm947xx_flash_parts
[nparts
].name
= "boot";
679 bcm947xx_flash_parts
[nparts
].size
= bootsz
;
680 bcm947xx_flash_parts
[nparts
].offset
= top
;
681 //bcm947xx_flash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
682 offset
= bcm947xx_flash_parts
[nparts
].size
;
687 /* Setup CONF MTD partition */
688 bcm947xx_flash_parts
[nparts
].name
= "confmtd";
689 bcm947xx_flash_parts
[nparts
].size
= mtd
->erasesize
* 4;
690 bcm947xx_flash_parts
[nparts
].offset
= offset
;
691 offset
= bcm947xx_flash_parts
[nparts
].offset
+ bcm947xx_flash_parts
[nparts
].size
;
693 #endif /* BCMCONFMTD */
696 /* Setup plc MTD partition */
697 bcm947xx_flash_parts
[nparts
].name
= "plc";
698 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(0x1000, mtd
->erasesize
);
699 bcm947xx_flash_parts
[nparts
].offset
=
700 size
- (ROUNDUP(nvram_space
, mtd
->erasesize
) + ROUNDUP(0x1000, mtd
->erasesize
));
704 /* Setup board_data partition */
705 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665")
706 && nvram_match("boardrev", "0x1301") && nvram_match("model", "R1D")) {
707 bcm947xx_flash_parts
[nparts
].name
= "board_data";
708 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(0x10000, mtd
->erasesize
);
709 bcm947xx_flash_parts
[nparts
].offset
= 0xFE0000;
713 /* Setup nvram MTD partition */
714 bcm947xx_flash_parts
[nparts
].name
= "nvram";
715 bcm947xx_flash_parts
[nparts
].size
= ROUNDUP(nvram_space
, mtd
->erasesize
);
718 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665")
719 && nvram_match("boardrev", "0x1301") && nvram_match("model", "R1D")) {
720 bcm947xx_flash_parts
[nparts
].offset
= 0xFF0000;
723 bcm947xx_flash_parts
[nparts
].offset
= (size
- 0x10000) - bcm947xx_flash_parts
[nparts
].size
;
725 bcm947xx_flash_parts
[nparts
].offset
= size
- bcm947xx_flash_parts
[nparts
].size
;
730 return bcm947xx_flash_parts
;
733 EXPORT_SYMBOL(init_mtd_partitions
);
735 #endif /* CONFIG_MTD_PARTITIONS */
738 #ifdef CONFIG_MTD_NFLASH
740 #define NFLASH_PARTS_NUM 7
741 static struct mtd_partition bcm947xx_nflash_parts
[NFLASH_PARTS_NUM
] = {{0}};
744 lookup_nflash_rootfs_offset(hndnand_t
*nfl
, struct mtd_info
*mtd
, int offset
, size_t size
)
746 struct romfs_super_block
*romfsb
;
747 struct cramfs_super
*cramfsb
;
748 struct dummy_super_block
*squashfsb
;
749 struct trx_header
*trx
;
751 uint blocksize
, pagesize
, mask
, blk_offset
, off
, shift
= 0;
754 pagesize
= nfl
->pagesize
;
755 buf
= (unsigned char *)kmalloc(pagesize
, GFP_KERNEL
);
757 printk("lookup_nflash_rootfs_offset: kmalloc fail\n");
761 romfsb
= (struct romfs_super_block
*) buf
;
762 cramfsb
= (struct cramfs_super
*) buf
;
763 squashfsb
= (void *) buf
;
764 trx
= (struct trx_header
*) buf
;
766 /* Look at every block boundary till 16MB; higher space is reserved for application data. */
767 blocksize
= mtd
->erasesize
;
768 printk("lookup_nflash_rootfs_offset: offset = 0x%x\n", offset
);
769 for (off
= offset
; off
< offset
+ size
; off
+= blocksize
) {
770 mask
= blocksize
- 1;
771 blk_offset
= off
& ~mask
;
772 if (hndnand_checkbadb(nfl
, blk_offset
) != 0)
774 memset(buf
, 0xe5, pagesize
);
775 if ((ret
= hndnand_read(nfl
, off
, pagesize
, buf
)) != pagesize
) {
777 "%s: nflash_read return %d\n", mtd
->name
, ret
);
781 /* Try looking at TRX header for rootfs offset */
782 if (le32_to_cpu(trx
->magic
) == TRX_MAGIC
) {
784 off
= offset
+ (le32_to_cpu(trx
->offsets
[1]) & ~mask
) - blocksize
;
785 shift
= (le32_to_cpu(trx
->offsets
[1]) & mask
);
786 romfsb
= (struct romfs_super_block
*)((unsigned char *)romfsb
+ shift
);
787 cramfsb
= (struct cramfs_super
*)((unsigned char *)cramfsb
+ shift
);
788 squashfsb
= (struct squashfs_super_block
*)
789 ((unsigned char *)squashfsb
+ shift
);
793 /* romfs is at block zero too */
794 if (romfsb
->word0
== ROMSB_WORD0
&&
795 romfsb
->word1
== ROMSB_WORD1
) {
797 "%s: romfs filesystem found at block %d\n",
798 mtd
->name
, off
/ blocksize
);
803 if (cramfsb
->magic
== CRAMFS_MAGIC
) {
805 "%s: cramfs filesystem found at block %d\n",
806 mtd
->name
, off
/ blocksize
);
810 if (squashfsb
->s_magic
== SQUASHFS_MAGIC
) {
812 "%s: squash filesystem with lzma found at block %d\n",
813 mtd
->name
, off
/ blocksize
);
825 struct mtd_partition
*
826 init_nflash_mtd_partitions(hndnand_t
*nfl
, struct mtd_info
*mtd
, size_t size
)
836 uint32 bootossz
= nfl_boot_os_size(nfl
);
837 uint boardnum
= bcm_strtoul(nvram_safe_get("boardnum"), NULL
, 0);
839 if (((boardnum
== 1) || (nvram_get("boardnum") == NULL
)) && nvram_match("boardtype", "0xF646") && nvram_match("boardrev", "0x1100")) {
840 bootossz
= 0x4000000;
843 else if (((boardnum
== 1) || (nvram_get("boardnum") == NULL
)) && nvram_match("boardtype","0xD646") && nvram_match("boardrev","0x1100")) {
844 bootossz
= 0x4000000;
847 #ifdef CONFIG_FAILSAFE_UPGRADE
848 char *img_boot
= nvram_get(BOOTPARTITION
);
849 char *imag_1st_offset
= nvram_get(IMAGE_FIRST_OFFSET
);
850 char *imag_2nd_offset
= nvram_get(IMAGE_SECOND_OFFSET
);
851 unsigned int image_first_offset
= 0;
852 unsigned int image_second_offset
= 0;
853 char dual_image_on
= 0;
855 /* The image_1st_size and image_2nd_size are necessary if the Flash does not have any
858 dual_image_on
= (img_boot
!= NULL
&& imag_1st_offset
!= NULL
&& imag_2nd_offset
!= NULL
);
861 image_first_offset
= simple_strtol(imag_1st_offset
, NULL
, 10);
862 image_second_offset
= simple_strtol(imag_2nd_offset
, NULL
, 10);
863 printk("The first offset=%x, 2nd offset=%x\n", image_first_offset
,
864 image_second_offset
);
867 #endif /* CONFIG_FAILSAFE_UPGRADE */
869 bootdev
= soc_boot_dev((void *)sih
);
870 knldev
= soc_knl_dev((void *)sih
);
872 if (bootdev
== SOC_BOOTDEV_NANDFLASH
) {
873 bootsz
= boot_partition_size(nfl
->base
);
874 if (bootsz
> mtd
->erasesize
) {
875 /* Prepare double space in case of bad blocks */
876 bootsz
= (bootsz
<< 1);
878 /* CFE occupies at least one block */
879 bootsz
= mtd
->erasesize
;
881 printk("Boot partition size = %d(0x%x)\n", bootsz
, bootsz
);
884 bcm947xx_nflash_parts
[nparts
].name
= "boot";
885 bcm947xx_nflash_parts
[nparts
].size
= bootsz
;
886 bcm947xx_nflash_parts
[nparts
].offset
= top
;
887 //bcm947xx_nflash_parts[nparts].mask_flags = MTD_WRITEABLE; /* forces on read only */
888 offset
= bcm947xx_nflash_parts
[nparts
].size
;
891 /* Setup NVRAM MTD partition */
892 bcm947xx_nflash_parts
[nparts
].name
= "nvram";
894 bcm947xx_nflash_parts
[nparts
].size
= nvsz
;
896 bcm947xx_nflash_parts
[nparts
].size
= nfl_boot_size(nfl
) - offset
;
897 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
899 offset
= nfl_boot_size(nfl
);
903 if (knldev
== SOC_KNLDEV_NANDFLASH
) {
904 /* Setup kernel MTD partition */
905 bcm947xx_nflash_parts
[nparts
].name
= "linux";
906 #ifdef CONFIG_FAILSAFE_UPGRADE
908 bcm947xx_nflash_parts
[nparts
].size
=
909 image_second_offset
- image_first_offset
;
913 bcm947xx_nflash_parts
[nparts
].size
= nparts
?
914 (bootossz
- nfl_boot_size(nfl
)) :
915 nfl_boot_os_size(nfl
);
917 /* fix linux offset for the R6300V2/R6250 units */
918 if (nvram_match("boardnum","679") && nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1110")) {
920 bcm947xx_nflash_parts
[nparts
].size
-= 0x180000;
923 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665") && nvram_match("boardrev", "0x1301")) {
924 bcm947xx_nflash_parts
[nparts
].size
+= 0x200000;
927 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1601")) {
928 bcm947xx_nflash_parts
[nparts
].size
+= 0x200000;
931 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
933 shift
= lookup_nflash_rootfs_offset(nfl
, mtd
, offset
,
934 bcm947xx_nflash_parts
[nparts
].size
);
936 #ifdef CONFIG_FAILSAFE_UPGRADE
938 offset
= image_second_offset
;
944 /* Setup rootfs MTD partition */
945 bcm947xx_nflash_parts
[nparts
].name
= "rootfs";
946 #ifdef CONFIG_FAILSAFE_UPGRADE
948 bcm947xx_nflash_parts
[nparts
].size
= image_second_offset
- shift
;
951 bcm947xx_nflash_parts
[nparts
].size
= bootossz
- shift
;
952 bcm947xx_nflash_parts
[nparts
].offset
= shift
;
953 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
954 offset
= nfl_boot_os_size(nfl
);
958 #ifdef CONFIG_DUAL_TRX /* ASUS Setup 2nd kernel MTD partition */
959 bcm947xx_nflash_parts
[nparts
].name
= "linux2";
960 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
;
961 bcm947xx_nflash_parts
[nparts
].offset
= NFL_BOOT_OS_SIZE
;
963 /* Setup rootfs MTD partition */
964 bcm947xx_nflash_parts
[nparts
].name
= "rootfs2";
965 bcm947xx_nflash_parts
[nparts
].size
= NFL_BOOT_OS_SIZE
- shift
;
966 bcm947xx_nflash_parts
[nparts
].offset
= NFL_BOOT_OS_SIZE
+ shift
;
967 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
969 #endif /* End of ASUS 2nd FW partition*/
971 /* again, to fix R6300V2, 6400 and R7000 */
972 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0665") && nvram_match("boardrev", "0x1301")) {
974 bcm947xx_nflash_parts
[nparts
].name
= "board_data";
975 bcm947xx_nflash_parts
[nparts
].size
= 0x40000;
976 bcm947xx_nflash_parts
[nparts
].offset
= 0x2200000;
980 if (nvram_match("boardnum", "32") && nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1601")) {
982 bcm947xx_nflash_parts
[nparts
].name
= "board_data";
983 bcm947xx_nflash_parts
[nparts
].size
= 0x40000;
984 bcm947xx_nflash_parts
[nparts
].offset
= 0x2200000;
988 if ( nvram_match("boardnum","679") && nvram_match("boardtype", "0x0646") && (nvram_match("boardrev", "0x1110")) ) {
989 bcm947xx_nflash_parts
[nparts
].name
= "board_data";
990 bcm947xx_nflash_parts
[nparts
].size
= 0x20000;
991 bcm947xx_nflash_parts
[nparts
].offset
= 0x200000;
994 #ifdef CONFIG_FAILSAFE_UPGRADE
995 /* Setup 2nd kernel MTD partition */
997 bcm947xx_nflash_parts
[nparts
].name
= "linux2";
998 bcm947xx_nflash_parts
[nparts
].size
= bootossz
- image_second_offset
;
999 bcm947xx_nflash_parts
[nparts
].offset
= image_second_offset
;
1000 shift
= lookup_nflash_rootfs_offset(nfl
, mtd
, image_second_offset
,
1001 bcm947xx_nflash_parts
[nparts
].size
);
1003 /* Setup rootfs MTD partition */
1004 bcm947xx_nflash_parts
[nparts
].name
= "rootfs2";
1005 bcm947xx_nflash_parts
[nparts
].size
= bootossz
- shift
;
1006 bcm947xx_nflash_parts
[nparts
].offset
= shift
;
1007 bcm947xx_nflash_parts
[nparts
].mask_flags
= MTD_WRITEABLE
;
1010 #endif /* CONFIG_FAILSAFE_UPGRADE */
1014 #ifdef PLAT_NAND_JFFS2
1015 /* Setup the remainder of NAND Flash as FFS partition */
1016 if( size
> offset
) {
1017 bcm947xx_nflash_parts
[nparts
].name
= "ffs";
1018 bcm947xx_nflash_parts
[nparts
].size
= size
- offset
;
1019 bcm947xx_nflash_parts
[nparts
].offset
= offset
;
1020 bcm947xx_nflash_parts
[nparts
].mask_flags
= 0;
1021 bcm947xx_nflash_parts
[nparts
].ecclayout
= mtd
->ecclayout
;
1026 return bcm947xx_nflash_parts
;
1029 /* LR: Calling this function directly violates Linux API conventions */
1030 EXPORT_SYMBOL(init_nflash_mtd_partitions
);
1031 #endif /* CONFIG_MTD_NFLASH */
1033 #ifdef CONFIG_CRASHLOG
1034 extern char *get_logbuf(void);
1035 extern char *get_logsize(void);
1037 void nvram_store_crash(void)
1039 struct mtd_info
*mtd
= NULL
;
1042 unsigned char buf
[16];
1046 printk("Trying to store crash\n");
1048 mtd
= get_mtd_device_nm("crash");
1052 buf_len
= get_logsize();
1053 buffer
= get_logbuf();
1054 if (buf_len
> mtd
->size
)
1055 buf_len
= mtd
->size
;
1057 memset(buf
,0,sizeof(buf
));
1058 mtd
->read(mtd
, 0, sizeof(buf
), &len
, buf
);
1059 for (len
=0;len
<sizeof(buf
);len
++)
1060 if (buf
[len
]!=0xff) {
1061 printk("Could not save crash, partition not clean\n");
1064 if (len
== sizeof(buf
)) {
1065 mtd
->write(mtd
, 0, buf_len
, &len
, buffer
);
1067 printk("Crash Saved\n");
1070 printk("Could not find NVRAM partition\n");
1073 #endif /* CONFIG_CRASHLOG */