^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/bootinfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/bmips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/smp-ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <bcm63xx_board.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <bcm63xx_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <bcm63xx_io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <bcm63xx_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void __init prom_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u32 reg, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) bcm63xx_cpu_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* stop any running watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* disable all hardware blocks clock for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (BCMCPU_IS_3368())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) mask = CKCTL_3368_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) else if (BCMCPU_IS_6328())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) mask = CKCTL_6328_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) else if (BCMCPU_IS_6338())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) mask = CKCTL_6338_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) else if (BCMCPU_IS_6345())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mask = CKCTL_6345_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) else if (BCMCPU_IS_6348())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mask = CKCTL_6348_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) else if (BCMCPU_IS_6358())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) mask = CKCTL_6358_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) else if (BCMCPU_IS_6362())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) mask = CKCTL_6362_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) else if (BCMCPU_IS_6368())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mask = CKCTL_6368_ALL_SAFE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) reg = bcm_perf_readl(PERF_CKCTL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) reg &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) bcm_perf_writel(reg, PERF_CKCTL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* do low level board init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) board_prom_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* set up SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!register_bmips_smp_ops()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * BCM6328 might not have its second CPU enabled, while BCM3368
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * and BCM6358 need special handling for their shared TLB, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * disable SMP for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (BCMCPU_IS_6328()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) reg = bcm_readl(BCM_6328_OTP_BASE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) OTP_USER_BITS_6328_REG(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (reg & OTP_6328_REG3_TP1_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bmips_smp_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) } else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) bmips_smp_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!bmips_smp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * The bootloader has set up the CPU1 reset vector at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * 0xa000_0200.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * This conflicts with the special interrupt vector (IV).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * The bootloader has also set up CPU1 to respond to the wrong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * IPI interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Here we will start up CPU1 in the background and ask it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * reconfigure itself then go back to sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) memcpy((void *)0xa0000200, bmips_smp_movevec, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __sync();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) set_c0_cause(C_SW0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) cpumask_set_cpu(1, &bmips_booted_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * FIXME: we really should have some sort of hazard barrier here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void __init prom_free_prom_memory(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }