diff options
author | Mike Frysinger <michael.frysinger@analog.com> | 2007-10-10 12:22:35 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-10-10 12:22:35 -0400 |
commit | 168f1212c098727f2509fe0f66bd30d7209a8159 (patch) | |
tree | e749898e8ab56131a12d8fc489081321abb3ff2f /arch | |
parent | 27d875f2c134c4b26860ccdd03b4c52cce4efc2c (diff) |
Blackfin arch: rewrite our reboot code in C
rewrite our reboot code in C rather than assembly to be like
other architectures and to allow board maintainers to define
custom behavior
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 18 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 25 | ||||
-rw-r--r-- | arch/blackfin/mach-bf533/head.S | 60 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/head.S | 79 | ||||
-rw-r--r-- | arch/blackfin/mach-bf548/head.S | 125 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/head.S | 60 |
7 files changed, 19 insertions, 350 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index f429ebc3a96..ae0a2203c3d 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := init_task.o vmlinux.lds | |||
7 | obj-y := \ | 7 | obj-y := \ |
8 | entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ | 8 | entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ |
9 | sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \ | 9 | sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \ |
10 | fixed_code.o cplbinit.o cacheinit.o | 10 | fixed_code.o cplbinit.o cacheinit.o reboot.o |
11 | 11 | ||
12 | obj-$(CONFIG_BF53x) += bfin_gpio.o | 12 | obj-$(CONFIG_BF53x) += bfin_gpio.o |
13 | obj-$(CONFIG_BF561) += bfin_gpio.o | 13 | obj-$(CONFIG_BF561) += bfin_gpio.o |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 0182ce1fc4f..d9284d7dc9f 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -80,6 +80,7 @@ | |||
80 | * GPIO_47 PH15 PF47 | 80 | * GPIO_47 PH15 PF47 |
81 | */ | 81 | */ |
82 | 82 | ||
83 | #include <linux/delay.h> | ||
83 | #include <linux/module.h> | 84 | #include <linux/module.h> |
84 | #include <linux/err.h> | 85 | #include <linux/err.h> |
85 | #include <asm/blackfin.h> | 86 | #include <asm/blackfin.h> |
@@ -888,3 +889,20 @@ void gpio_direction_output(unsigned short gpio) | |||
888 | local_irq_restore(flags); | 889 | local_irq_restore(flags); |
889 | } | 890 | } |
890 | EXPORT_SYMBOL(gpio_direction_output); | 891 | EXPORT_SYMBOL(gpio_direction_output); |
892 | |||
893 | /* If we are booting from SPI and our board lacks a strong enough pull up, | ||
894 | * the core can reset and execute the bootrom faster than the resistor can | ||
895 | * pull the signal logically high. To work around this (common) error in | ||
896 | * board design, we explicitly set the pin back to GPIO mode, force /CS | ||
897 | * high, and wait for the electrons to do their thing. | ||
898 | * | ||
899 | * This function only makes sense to be called from reset code, but it | ||
900 | * lives here as we need to force all the GPIO states w/out going through | ||
901 | * BUG() checks and such. | ||
902 | */ | ||
903 | void bfin_gpio_reset_spi0_ssel1(void) | ||
904 | { | ||
905 | port_setup(P_SPI0_SSEL1, GPIO_USAGE); | ||
906 | gpio_bankb[gpio_bank(P_SPI0_SSEL1)]->data_set = gpio_bit(P_SPI0_SSEL1); | ||
907 | udelay(1); | ||
908 | } | ||
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 22e79041986..de7d048bd4e 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -134,31 +134,6 @@ void cpu_idle(void) | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | void machine_restart(char *__unused) | ||
138 | { | ||
139 | #if defined(CONFIG_BFIN_ICACHE) | ||
140 | bfin_write_IMEM_CONTROL(0x01); | ||
141 | SSYNC(); | ||
142 | #endif | ||
143 | bfin_reset(); | ||
144 | /* Dont do anything till the reset occurs */ | ||
145 | while (1) { | ||
146 | SSYNC(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | void machine_halt(void) | ||
151 | { | ||
152 | for (;;) | ||
153 | asm volatile ("idle"); | ||
154 | } | ||
155 | |||
156 | void machine_power_off(void) | ||
157 | { | ||
158 | for (;;) | ||
159 | asm volatile ("idle"); | ||
160 | } | ||
161 | |||
162 | void show_regs(struct pt_regs *regs) | 137 | void show_regs(struct pt_regs *regs) |
163 | { | 138 | { |
164 | printk(KERN_NOTICE "\n"); | 139 | printk(KERN_NOTICE "\n"); |
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S index 3be6feefa8a..6e1b5f6da5c 100644 --- a/arch/blackfin/mach-bf533/head.S +++ b/arch/blackfin/mach-bf533/head.S | |||
@@ -459,66 +459,6 @@ ENTRY(_start_dma_code) | |||
459 | ENDPROC(_start_dma_code) | 459 | ENDPROC(_start_dma_code) |
460 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 460 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
461 | 461 | ||
462 | ENTRY(_bfin_reset) | ||
463 | /* No more interrupts to be handled*/ | ||
464 | CLI R6; | ||
465 | SSYNC; | ||
466 | |||
467 | #if defined(CONFIG_BFIN_SHARED_FLASH_ENET) | ||
468 | p0.h = hi(FIO_INEN); | ||
469 | p0.l = lo(FIO_INEN); | ||
470 | r0.l = ~(1 << CONFIG_ENET_FLASH_PIN); | ||
471 | w[p0] = r0.l; | ||
472 | |||
473 | p0.h = hi(FIO_DIR); | ||
474 | p0.l = lo(FIO_DIR); | ||
475 | r0.l = (1 << CONFIG_ENET_FLASH_PIN); | ||
476 | w[p0] = r0.l; | ||
477 | |||
478 | p0.h = hi(FIO_FLAG_C); | ||
479 | p0.l = lo(FIO_FLAG_C); | ||
480 | r0.l = (1 << CONFIG_ENET_FLASH_PIN); | ||
481 | w[p0] = r0.l; | ||
482 | #endif | ||
483 | |||
484 | /* Clear the IMASK register */ | ||
485 | p0.h = hi(IMASK); | ||
486 | p0.l = lo(IMASK); | ||
487 | r0 = 0x0; | ||
488 | [p0] = r0; | ||
489 | |||
490 | /* Clear the ILAT register */ | ||
491 | p0.h = hi(ILAT); | ||
492 | p0.l = lo(ILAT); | ||
493 | r0 = [p0]; | ||
494 | [p0] = r0; | ||
495 | SSYNC; | ||
496 | |||
497 | /* make sure SYSCR is set to use BMODE */ | ||
498 | P0.h = hi(SYSCR); | ||
499 | P0.l = lo(SYSCR); | ||
500 | R0.l = 0x0; | ||
501 | W[P0] = R0.l; | ||
502 | SSYNC; | ||
503 | |||
504 | /* issue a system soft reset */ | ||
505 | P1.h = hi(SWRST); | ||
506 | P1.l = lo(SWRST); | ||
507 | R1.l = 0x0007; | ||
508 | W[P1] = R1; | ||
509 | SSYNC; | ||
510 | |||
511 | /* clear system soft reset */ | ||
512 | R0.l = 0x0000; | ||
513 | W[P0] = R0; | ||
514 | SSYNC; | ||
515 | |||
516 | /* issue core reset */ | ||
517 | raise 1; | ||
518 | |||
519 | RTS; | ||
520 | ENDPROC(_bfin_reset) | ||
521 | |||
522 | #if CONFIG_DEBUG_KERNEL_START | 462 | #if CONFIG_DEBUG_KERNEL_START |
523 | debug_kernel_start_trap: | 463 | debug_kernel_start_trap: |
524 | /* Set up a temp stack in L1 - SDRAM might not be working */ | 464 | /* Set up a temp stack in L1 - SDRAM might not be working */ |
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S index 0836bfdcc6c..2c4ae466d4e 100644 --- a/arch/blackfin/mach-bf537/head.S +++ b/arch/blackfin/mach-bf537/head.S | |||
@@ -478,85 +478,6 @@ ENTRY(_start_dma_code) | |||
478 | ENDPROC(_start_dma_code) | 478 | ENDPROC(_start_dma_code) |
479 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 479 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
480 | 480 | ||
481 | ENTRY(_bfin_reset) | ||
482 | /* No more interrupts to be handled*/ | ||
483 | CLI R6; | ||
484 | SSYNC; | ||
485 | |||
486 | #if defined(CONFIG_MTD_M25P80) | ||
487 | /* | ||
488 | * The following code fix the SPI flash reboot issue, | ||
489 | * /CS signal of the chip which is using PF10 return to GPIO mode | ||
490 | */ | ||
491 | p0.h = hi(PORTF_FER); | ||
492 | p0.l = lo(PORTF_FER); | ||
493 | r0.l = 0x0000; | ||
494 | w[p0] = r0.l; | ||
495 | SSYNC; | ||
496 | |||
497 | /* /CS return to high */ | ||
498 | p0.h = hi(PORTFIO); | ||
499 | p0.l = lo(PORTFIO); | ||
500 | r0.l = 0xFFFF; | ||
501 | w[p0] = r0.l; | ||
502 | SSYNC; | ||
503 | |||
504 | /* Delay some time, This is necessary */ | ||
505 | r1.h = 0; | ||
506 | r1.l = 0x400; | ||
507 | p1 = r1; | ||
508 | lsetup (.L_delay_lab1, .L_delay_lab1_end) lc1 = p1; | ||
509 | .L_delay_lab1: | ||
510 | r0.h = 0; | ||
511 | r0.l = 0x8000; | ||
512 | p0 = r0; | ||
513 | lsetup (.L_delay_lab0, .L_delay_lab0_end) lc0 = p0; | ||
514 | .L_delay_lab0: | ||
515 | nop; | ||
516 | .L_delay_lab0_end: | ||
517 | nop; | ||
518 | .L_delay_lab1_end: | ||
519 | nop; | ||
520 | #endif | ||
521 | |||
522 | /* Clear the IMASK register */ | ||
523 | p0.h = hi(IMASK); | ||
524 | p0.l = lo(IMASK); | ||
525 | r0 = 0x0; | ||
526 | [p0] = r0; | ||
527 | |||
528 | /* Clear the ILAT register */ | ||
529 | p0.h = hi(ILAT); | ||
530 | p0.l = lo(ILAT); | ||
531 | r0 = [p0]; | ||
532 | [p0] = r0; | ||
533 | SSYNC; | ||
534 | |||
535 | /* make sure SYSCR is set to use BMODE */ | ||
536 | P0.h = hi(SYSCR); | ||
537 | P0.l = lo(SYSCR); | ||
538 | R0.l = 0x0; | ||
539 | W[P0] = R0.l; | ||
540 | SSYNC; | ||
541 | |||
542 | /* issue a system soft reset */ | ||
543 | P1.h = hi(SWRST); | ||
544 | P1.l = lo(SWRST); | ||
545 | R1.l = 0x0007; | ||
546 | W[P1] = R1; | ||
547 | SSYNC; | ||
548 | |||
549 | /* clear system soft reset */ | ||
550 | R0.l = 0x0000; | ||
551 | W[P0] = R0; | ||
552 | SSYNC; | ||
553 | |||
554 | /* issue core reset */ | ||
555 | raise 1; | ||
556 | |||
557 | RTS; | ||
558 | ENDPROC(_bfin_reset) | ||
559 | |||
560 | .data | 481 | .data |
561 | 482 | ||
562 | /* | 483 | /* |
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 937fbef26a5..532ed0930b5 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S | |||
@@ -378,131 +378,6 @@ ENTRY(_start_dma_code) | |||
378 | RTS; | 378 | RTS; |
379 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 379 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
380 | 380 | ||
381 | ENTRY(_bfin_reset) | ||
382 | /* No more interrupts to be handled*/ | ||
383 | CLI R6; | ||
384 | SSYNC; | ||
385 | |||
386 | #if 0 /* Need to determine later if this is here necessary for BF54x */ | ||
387 | #if defined(CONFIG_MTD_M25P80) | ||
388 | /* | ||
389 | * The following code fix the SPI flash reboot issue, | ||
390 | * /CS signal of the chip which is using PF10 return to GPIO mode | ||
391 | */ | ||
392 | p0.h = hi(PORTF_FER); | ||
393 | p0.l = lo(PORTF_FER); | ||
394 | r0.l = 0x0000; | ||
395 | w[p0] = r0.l; | ||
396 | SSYNC; | ||
397 | |||
398 | /* /CS return to high */ | ||
399 | p0.h = hi(PORTFIO); | ||
400 | p0.l = lo(PORTFIO); | ||
401 | r0.l = 0xFFFF; | ||
402 | w[p0] = r0.l; | ||
403 | SSYNC; | ||
404 | |||
405 | /* Delay some time, This is necessary */ | ||
406 | r1.h = 0; | ||
407 | r1.l = 0x400; | ||
408 | p1 = r1; | ||
409 | lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1; | ||
410 | _delay_lab1: | ||
411 | r0.h = 0; | ||
412 | r0.l = 0x8000; | ||
413 | p0 = r0; | ||
414 | lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0; | ||
415 | _delay_lab0: | ||
416 | nop; | ||
417 | _delay_lab0_end: | ||
418 | nop; | ||
419 | _delay_lab1_end: | ||
420 | nop; | ||
421 | #endif | ||
422 | #endif | ||
423 | |||
424 | /* Clear the bits 13-15 in SWRST if they werent cleared */ | ||
425 | p0.h = hi(SWRST); | ||
426 | p0.l = lo(SWRST); | ||
427 | csync; | ||
428 | r0.l = w[p0]; | ||
429 | |||
430 | /* Clear the IMASK register */ | ||
431 | p0.h = hi(IMASK); | ||
432 | p0.l = lo(IMASK); | ||
433 | r0 = 0x0; | ||
434 | [p0] = r0; | ||
435 | |||
436 | /* Clear the ILAT register */ | ||
437 | p0.h = hi(ILAT); | ||
438 | p0.l = lo(ILAT); | ||
439 | r0 = [p0]; | ||
440 | [p0] = r0; | ||
441 | SSYNC; | ||
442 | |||
443 | /* Disable the WDOG TIMER */ | ||
444 | p0.h = hi(WDOG_CTL); | ||
445 | p0.l = lo(WDOG_CTL); | ||
446 | r0.l = 0xAD6; | ||
447 | w[p0] = r0.l; | ||
448 | SSYNC; | ||
449 | |||
450 | /* Clear the sticky bit incase it is already set */ | ||
451 | p0.h = hi(WDOG_CTL); | ||
452 | p0.l = lo(WDOG_CTL); | ||
453 | r0.l = 0x8AD6; | ||
454 | w[p0] = r0.l; | ||
455 | SSYNC; | ||
456 | |||
457 | /* Program the count value */ | ||
458 | R0.l = 0x100; | ||
459 | R0.h = 0x0; | ||
460 | P0.h = hi(WDOG_CNT); | ||
461 | P0.l = lo(WDOG_CNT); | ||
462 | [P0] = R0; | ||
463 | SSYNC; | ||
464 | |||
465 | /* Program WDOG_STAT if necessary */ | ||
466 | P0.h = hi(WDOG_CTL); | ||
467 | P0.l = lo(WDOG_CTL); | ||
468 | R0 = W[P0](Z); | ||
469 | CC = BITTST(R0,1); | ||
470 | if !CC JUMP .LWRITESTAT; | ||
471 | CC = BITTST(R0,2); | ||
472 | if !CC JUMP .LWRITESTAT; | ||
473 | JUMP .LSKIP_WRITE; | ||
474 | |||
475 | .LWRITESTAT: | ||
476 | /* When watch dog timer is enabled, | ||
477 | * a write to STAT will load the contents of CNT to STAT | ||
478 | */ | ||
479 | R0 = 0x0000(z); | ||
480 | P0.h = hi(WDOG_STAT); | ||
481 | P0.l = lo(WDOG_STAT) | ||
482 | [P0] = R0; | ||
483 | SSYNC; | ||
484 | |||
485 | .LSKIP_WRITE: | ||
486 | /* Enable the reset event */ | ||
487 | P0.h = hi(WDOG_CTL); | ||
488 | P0.l = lo(WDOG_CTL); | ||
489 | R0 = W[P0](Z); | ||
490 | BITCLR(R0,1); | ||
491 | BITCLR(R0,2); | ||
492 | W[P0] = R0.L; | ||
493 | SSYNC; | ||
494 | NOP; | ||
495 | |||
496 | /* Enable the wdog counter */ | ||
497 | R0 = W[P0](Z); | ||
498 | BITCLR(R0,4); | ||
499 | W[P0] = R0.L; | ||
500 | SSYNC; | ||
501 | |||
502 | IDLE; | ||
503 | |||
504 | RTS; | ||
505 | |||
506 | .data | 381 | .data |
507 | 382 | ||
508 | /* | 383 | /* |
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S index 139f4cff801..fd39891ae0f 100644 --- a/arch/blackfin/mach-bf561/head.S +++ b/arch/blackfin/mach-bf561/head.S | |||
@@ -406,66 +406,6 @@ ENTRY(_start_dma_code) | |||
406 | ENDPROC(_start_dma_code) | 406 | ENDPROC(_start_dma_code) |
407 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 407 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
408 | 408 | ||
409 | ENTRY(_bfin_reset) | ||
410 | /* No more interrupts to be handled*/ | ||
411 | CLI R6; | ||
412 | SSYNC; | ||
413 | |||
414 | #if defined(CONFIG_BFIN_SHARED_FLASH_ENET) | ||
415 | p0.h = hi(FIO_INEN); | ||
416 | p0.l = lo(FIO_INEN); | ||
417 | r0.l = ~(PF1 | PF0); | ||
418 | w[p0] = r0.l; | ||
419 | |||
420 | p0.h = hi(FIO_DIR); | ||
421 | p0.l = lo(FIO_DIR); | ||
422 | r0.l = (PF1 | PF0); | ||
423 | w[p0] = r0.l; | ||
424 | |||
425 | p0.h = hi(FIO_FLAG_C); | ||
426 | p0.l = lo(FIO_FLAG_C); | ||
427 | r0.l = (PF1 | PF0); | ||
428 | w[p0] = r0.l; | ||
429 | #endif | ||
430 | |||
431 | /* Clear the IMASK register */ | ||
432 | p0.h = hi(IMASK); | ||
433 | p0.l = lo(IMASK); | ||
434 | r0 = 0x0; | ||
435 | [p0] = r0; | ||
436 | |||
437 | /* Clear the ILAT register */ | ||
438 | p0.h = hi(ILAT); | ||
439 | p0.l = lo(ILAT); | ||
440 | r0 = [p0]; | ||
441 | [p0] = r0; | ||
442 | SSYNC; | ||
443 | |||
444 | /* make sure SYSCR is set to use BMODE */ | ||
445 | P0.h = hi(SYSCR); | ||
446 | P0.l = lo(SYSCR); | ||
447 | R0.l = 0x20; /* on BF561, disable core b */ | ||
448 | W[P0] = R0.l; | ||
449 | SSYNC; | ||
450 | |||
451 | /* issue a system soft reset */ | ||
452 | P1.h = hi(SWRST); | ||
453 | P1.l = lo(SWRST); | ||
454 | R1.l = 0x0007; | ||
455 | W[P1] = R1; | ||
456 | SSYNC; | ||
457 | |||
458 | /* clear system soft reset */ | ||
459 | R0.l = 0x0000; | ||
460 | W[P0] = R0; | ||
461 | SSYNC; | ||
462 | |||
463 | /* issue core reset */ | ||
464 | raise 1; | ||
465 | |||
466 | RTS; | ||
467 | ENDPROC(_bfin_reset) | ||
468 | |||
469 | .data | 409 | .data |
470 | 410 | ||
471 | /* | 411 | /* |