diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2016-02-09 15:55:50 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-05-13 08:01:55 -0400 |
commit | 738a3f79027bef44b0bd3bfcc325f53b518749d4 (patch) | |
tree | c7b38c69ebafaa28866df7cd2d2cb007215e88d1 | |
parent | 036aff91c30a6f15d5bf25f22827abc26b6d06c1 (diff) |
MIPS: BMIPS: Add early CPU initialization code
Port the stblinux-3.3 code to perform a bunch of CPU-specific initialization,
make it compatible with run-time detection of the CPU, and unroll the
brcmstb-specific macros: BDEV_RB(), BDEV_UNSET.
The "pref 30" disabling is done as a quirk. This is a preliminary change to
allow the use of the "rotr" instruction gated by cpu_has_rixi.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Cc: john@phrozen.org
Cc: cernekee@gmail.com
Cc: jon.fraser@broadcom.com
Cc: pgynther@google.com
Cc: paul.burton@imgtec.com
Cc: ddaney.cavm@gmail.com
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12504/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/bmips/setup.c | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/bmips.h | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smp-bmips.c | 87 |
3 files changed, 89 insertions, 0 deletions
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 35535284b39e..b764995343c1 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c | |||
@@ -111,6 +111,7 @@ static const struct bmips_quirk bmips_quirk_list[] = { | |||
111 | 111 | ||
112 | void __init prom_init(void) | 112 | void __init prom_init(void) |
113 | { | 113 | { |
114 | bmips_cpu_setup(); | ||
114 | register_bmips_smp_ops(); | 115 | register_bmips_smp_ops(); |
115 | } | 116 | } |
116 | 117 | ||
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index 6d25ad33ec78..a92aee7b977a 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h | |||
@@ -88,6 +88,7 @@ extern unsigned long bmips_tp1_irqs; | |||
88 | 88 | ||
89 | extern void bmips_ebase_setup(void); | 89 | extern void bmips_ebase_setup(void); |
90 | extern asmlinkage void plat_wired_tlb_setup(void); | 90 | extern asmlinkage void plat_wired_tlb_setup(void); |
91 | extern void bmips_cpu_setup(void); | ||
91 | 92 | ||
92 | static inline unsigned long bmips_read_zscm_reg(unsigned int offset) | 93 | static inline unsigned long bmips_read_zscm_reg(unsigned int offset) |
93 | { | 94 | { |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 6d11788b4502..e02addc0307f 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -566,3 +566,90 @@ asmlinkage void __weak plat_wired_tlb_setup(void) | |||
566 | * once the wired entries are present. | 566 | * once the wired entries are present. |
567 | */ | 567 | */ |
568 | } | 568 | } |
569 | |||
570 | void __init bmips_cpu_setup(void) | ||
571 | { | ||
572 | void __iomem __maybe_unused *cbr = BMIPS_GET_CBR(); | ||
573 | u32 __maybe_unused cfg; | ||
574 | |||
575 | switch (current_cpu_type()) { | ||
576 | case CPU_BMIPS3300: | ||
577 | /* Set BIU to async mode */ | ||
578 | set_c0_brcm_bus_pll(BIT(22)); | ||
579 | __sync(); | ||
580 | |||
581 | /* put the BIU back in sync mode */ | ||
582 | clear_c0_brcm_bus_pll(BIT(22)); | ||
583 | |||
584 | /* clear BHTD to enable branch history table */ | ||
585 | clear_c0_brcm_reset(BIT(16)); | ||
586 | |||
587 | /* Flush and enable RAC */ | ||
588 | cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
589 | __raw_writel(cfg | 0x100, BMIPS_RAC_CONFIG); | ||
590 | __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
591 | |||
592 | cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
593 | __raw_writel(cfg | 0xf, BMIPS_RAC_CONFIG); | ||
594 | __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
595 | |||
596 | cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
597 | __raw_writel(cfg | 0x0fff0000, cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
598 | __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
599 | break; | ||
600 | |||
601 | case CPU_BMIPS4380: | ||
602 | /* CBG workaround for early BMIPS4380 CPUs */ | ||
603 | switch (read_c0_prid()) { | ||
604 | case 0x2a040: | ||
605 | case 0x2a042: | ||
606 | case 0x2a044: | ||
607 | case 0x2a060: | ||
608 | cfg = __raw_readl(cbr + BMIPS_L2_CONFIG); | ||
609 | __raw_writel(cfg & ~0x07000000, cbr + BMIPS_L2_CONFIG); | ||
610 | __raw_readl(cbr + BMIPS_L2_CONFIG); | ||
611 | } | ||
612 | |||
613 | /* clear BHTD to enable branch history table */ | ||
614 | clear_c0_brcm_config_0(BIT(21)); | ||
615 | |||
616 | /* XI/ROTR enable */ | ||
617 | set_c0_brcm_config_0(BIT(23)); | ||
618 | set_c0_brcm_cmt_ctrl(BIT(15)); | ||
619 | break; | ||
620 | |||
621 | case CPU_BMIPS5000: | ||
622 | /* enable RDHWR, BRDHWR */ | ||
623 | set_c0_brcm_config(BIT(17) | BIT(21)); | ||
624 | |||
625 | /* Disable JTB */ | ||
626 | __asm__ __volatile__( | ||
627 | " .set noreorder\n" | ||
628 | " li $8, 0x5a455048\n" | ||
629 | " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ | ||
630 | " .word 0x4008b008\n" /* mfc0 t0, $22, 8 */ | ||
631 | " li $9, 0x00008000\n" | ||
632 | " or $8, $8, $9\n" | ||
633 | " .word 0x4088b008\n" /* mtc0 t0, $22, 8 */ | ||
634 | " sync\n" | ||
635 | " li $8, 0x0\n" | ||
636 | " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ | ||
637 | " .set reorder\n" | ||
638 | : : : "$8", "$9"); | ||
639 | |||
640 | /* XI enable */ | ||
641 | set_c0_brcm_config(BIT(27)); | ||
642 | |||
643 | /* enable MIPS32R2 ROR instruction for XI TLB handlers */ | ||
644 | __asm__ __volatile__( | ||
645 | " li $8, 0x5a455048\n" | ||
646 | " .word 0x4088b00f\n" /* mtc0 $8, $22, 15 */ | ||
647 | " nop; nop; nop\n" | ||
648 | " .word 0x4008b008\n" /* mfc0 $8, $22, 8 */ | ||
649 | " lui $9, 0x0100\n" | ||
650 | " or $8, $9\n" | ||
651 | " .word 0x4088b008\n" /* mtc0 $8, $22, 8 */ | ||
652 | : : : "$8", "$9"); | ||
653 | break; | ||
654 | } | ||
655 | } | ||