android_kernel_motorola_sm6225/arch/mips/bcm63xx/prom.c
Jonas Gorski 6465460c92 MIPS: BMIPS: change compile time checks to runtime checks
Allow building for all bmips cpus at the same time by changing ifdefs
to checks for the cpu type, or adding appropriate checks to the
assembly.

Since BMIPS43XX and BMIPS5000 require different IPI implementations,
split the SMP ops into one for each, so the runtime overhead is only
at registration time for them.

Signed-off-by: Jonas Gorski <jogo@openwrt.org>
Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/6241/
2014-01-22 20:18:51 +01:00

106 lines
2.6 KiB
C

/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
*/
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/smp.h>
#include <asm/bootinfo.h>
#include <asm/bmips.h>
#include <asm/smp-ops.h>
#include <asm/mipsregs.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_gpio.h>
void __init prom_init(void)
{
u32 reg, mask;
bcm63xx_cpu_init();
/* stop any running watchdog */
bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
/* disable all hardware blocks clock for now */
if (BCMCPU_IS_3368())
mask = CKCTL_3368_ALL_SAFE_EN;
else if (BCMCPU_IS_6328())
mask = CKCTL_6328_ALL_SAFE_EN;
else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN;
else if (BCMCPU_IS_6345())
mask = CKCTL_6345_ALL_SAFE_EN;
else if (BCMCPU_IS_6348())
mask = CKCTL_6348_ALL_SAFE_EN;
else if (BCMCPU_IS_6358())
mask = CKCTL_6358_ALL_SAFE_EN;
else if (BCMCPU_IS_6362())
mask = CKCTL_6362_ALL_SAFE_EN;
else if (BCMCPU_IS_6368())
mask = CKCTL_6368_ALL_SAFE_EN;
else
mask = 0;
reg = bcm_perf_readl(PERF_CKCTL_REG);
reg &= ~mask;
bcm_perf_writel(reg, PERF_CKCTL_REG);
/* register gpiochip */
bcm63xx_gpio_init();
/* do low level board init */
board_prom_init();
if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
/* set up SMP */
register_smp_ops(&bmips43xx_smp_ops);
/*
* BCM6328 might not have its second CPU enabled, while BCM3368
* and BCM6358 need special handling for their shared TLB, so
* disable SMP for now.
*/
if (BCMCPU_IS_6328()) {
reg = bcm_readl(BCM_6328_OTP_BASE +
OTP_USER_BITS_6328_REG(3));
if (reg & OTP_6328_REG3_TP1_DISABLED)
bmips_smp_enabled = 0;
} else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
bmips_smp_enabled = 0;
}
if (!bmips_smp_enabled)
return;
/*
* The bootloader has set up the CPU1 reset vector at
* 0xa000_0200.
* This conflicts with the special interrupt vector (IV).
* The bootloader has also set up CPU1 to respond to the wrong
* IPI interrupt.
* Here we will start up CPU1 in the background and ask it to
* reconfigure itself then go back to sleep.
*/
memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
__sync();
set_c0_cause(C_SW0);
cpumask_set_cpu(1, &bmips_booted_mask);
/*
* FIXME: we really should have some sort of hazard barrier here
*/
}
}
void __init prom_free_prom_memory(void)
{
}