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