diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2016-02-09 12:55:50 -0800 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-05-13 14:01:55 +0200 |
commit | 738a3f79027bef44b0bd3bfcc325f53b518749d4 (patch) | |
tree | c7b38c69ebafaa28866df7cd2d2cb007215e88d1 /arch | |
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>
Diffstat (limited to 'arch')
-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[] = { void __init prom_init(void) { + bmips_cpu_setup(); register_bmips_smp_ops(); } 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; extern void bmips_ebase_setup(void); extern asmlinkage void plat_wired_tlb_setup(void); +extern void bmips_cpu_setup(void); static inline unsigned long bmips_read_zscm_reg(unsigned int offset) { 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) * once the wired entries are present. */ } + +void __init bmips_cpu_setup(void) +{ + void __iomem __maybe_unused *cbr = BMIPS_GET_CBR(); + u32 __maybe_unused cfg; + + switch (current_cpu_type()) { + case CPU_BMIPS3300: + /* Set BIU to async mode */ + set_c0_brcm_bus_pll(BIT(22)); + __sync(); + + /* put the BIU back in sync mode */ + clear_c0_brcm_bus_pll(BIT(22)); + + /* clear BHTD to enable branch history table */ + clear_c0_brcm_reset(BIT(16)); + + /* Flush and enable RAC */ + cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0x100, BMIPS_RAC_CONFIG); + __raw_readl(cbr + BMIPS_RAC_CONFIG); + + cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0xf, BMIPS_RAC_CONFIG); + __raw_readl(cbr + BMIPS_RAC_CONFIG); + + cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); + __raw_writel(cfg | 0x0fff0000, cbr + BMIPS_RAC_ADDRESS_RANGE); + __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); + break; + + case CPU_BMIPS4380: + /* CBG workaround for early BMIPS4380 CPUs */ + switch (read_c0_prid()) { + case 0x2a040: + case 0x2a042: + case 0x2a044: + case 0x2a060: + cfg = __raw_readl(cbr + BMIPS_L2_CONFIG); + __raw_writel(cfg & ~0x07000000, cbr + BMIPS_L2_CONFIG); + __raw_readl(cbr + BMIPS_L2_CONFIG); + } + + /* clear BHTD to enable branch history table */ + clear_c0_brcm_config_0(BIT(21)); + + /* XI/ROTR enable */ + set_c0_brcm_config_0(BIT(23)); + set_c0_brcm_cmt_ctrl(BIT(15)); + break; + + case CPU_BMIPS5000: + /* enable RDHWR, BRDHWR */ + set_c0_brcm_config(BIT(17) | BIT(21)); + + /* Disable JTB */ + __asm__ __volatile__( + " .set noreorder\n" + " li $8, 0x5a455048\n" + " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ + " .word 0x4008b008\n" /* mfc0 t0, $22, 8 */ + " li $9, 0x00008000\n" + " or $8, $8, $9\n" + " .word 0x4088b008\n" /* mtc0 t0, $22, 8 */ + " sync\n" + " li $8, 0x0\n" + " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ + " .set reorder\n" + : : : "$8", "$9"); + + /* XI enable */ + set_c0_brcm_config(BIT(27)); + + /* enable MIPS32R2 ROR instruction for XI TLB handlers */ + __asm__ __volatile__( + " li $8, 0x5a455048\n" + " .word 0x4088b00f\n" /* mtc0 $8, $22, 15 */ + " nop; nop; nop\n" + " .word 0x4008b008\n" /* mfc0 $8, $22, 8 */ + " lui $9, 0x0100\n" + " or $8, $9\n" + " .word 0x4088b008\n" /* mtc0 $8, $22, 8 */ + : : : "$8", "$9"); + break; + } +} |