uboot/arch/powerpc/cpu/mpc512x/cpu.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2010 DENX Software Engineering
   3 * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * CPU specific code for the MPC512x family.
  26 *
  27 * Derived from the MPC83xx code.
  28 */
  29
  30#include <common.h>
  31#include <command.h>
  32#include <net.h>
  33#include <netdev.h>
  34#include <asm/processor.h>
  35#include <asm/io.h>
  36
  37#if defined(CONFIG_OF_LIBFDT)
  38#include <fdt_support.h>
  39#endif
  40
  41DECLARE_GLOBAL_DATA_PTR;
  42
  43int checkcpu (void)
  44{
  45        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
  46        ulong clock = gd->cpu_clk;
  47        u32 pvr = get_pvr ();
  48        u32 spridr = in_be32(&immr->sysconf.spridr);
  49        char buf1[32], buf2[32];
  50
  51        puts ("CPU:   ");
  52
  53        switch (spridr & 0xffff0000) {
  54        case SPR_5121E:
  55                puts ("MPC5121e ");
  56                break;
  57        default:
  58                printf ("Unknown part ID %08x ", spridr & 0xffff0000);
  59        }
  60        printf ("rev. %d.%d, Core ", SVR_MJREV (spridr), SVR_MNREV (spridr));
  61
  62        switch (pvr & 0xffff0000) {
  63        case PVR_E300C4:
  64                puts ("e300c4 ");
  65                break;
  66        default:
  67                puts ("unknown ");
  68        }
  69        printf ("at %s MHz, CSB at %s MHz (RSR=0x%04lx)\n",
  70                strmhz(buf1, clock),
  71                strmhz(buf2, gd->arch.csb_clk),
  72                gd->arch.reset_status & 0xffff);
  73        return 0;
  74}
  75
  76
  77int
  78do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  79{
  80        ulong msr;
  81        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  82
  83        /* Interrupts and MMU off */
  84        __asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
  85
  86        msr &= ~( MSR_EE | MSR_IR | MSR_DR);
  87        __asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
  88
  89        /*
  90         * Enable Reset Control Reg - "RSTE" is the magic word that let us go
  91         */
  92        out_be32(&immap->reset.rpr, 0x52535445);
  93
  94        /* Verify Reset Control Reg is enabled */
  95        while (!(in_be32(&immap->reset.rcer) & RCER_CRE))
  96                ;
  97
  98        printf ("Resetting the board.\n");
  99        udelay(200);
 100
 101        /* Perform reset */
 102        out_be32(&immap->reset.rcr, RCR_SWHR);
 103
 104        /* Unreached... */
 105        return 1;
 106}
 107
 108
 109/*
 110 * Get timebase clock frequency (like cpu_clk in Hz)
 111 */
 112unsigned long get_tbclk (void)
 113{
 114        ulong tbclk;
 115
 116        tbclk = (gd->bus_clk + 3L) / 4L;
 117
 118        return tbclk;
 119}
 120
 121
 122#if defined(CONFIG_WATCHDOG)
 123void watchdog_reset (void)
 124{
 125        int re_enable = disable_interrupts ();
 126
 127        /* Reset watchdog */
 128        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 129        out_be32(&immr->wdt.swsrr, 0x556c);
 130        out_be32(&immr->wdt.swsrr, 0xaa39);
 131
 132        if (re_enable)
 133                enable_interrupts ();
 134}
 135#endif
 136
 137#ifdef CONFIG_OF_LIBFDT
 138
 139#ifdef CONFIG_OF_SUPPORT_OLD_DEVICE_TREES
 140/*
 141 * fdt setup for old device trees
 142 * fix up
 143 *      cpu clocks
 144 *      soc clocks
 145 *      ethernet addresses
 146 */
 147static void old_ft_cpu_setup(void *blob, bd_t *bd)
 148{
 149        /*
 150         * avoid fixing up by path because that
 151         * produces scary error messages
 152         */
 153        uchar enetaddr[6];
 154
 155        /*
 156         * old device trees have ethernet nodes with
 157         * device_type = "network"
 158         */
 159        eth_getenv_enetaddr("ethaddr", enetaddr);
 160        do_fixup_by_prop(blob, "device_type", "network", 8,
 161                "local-mac-address", enetaddr, 6, 0);
 162        do_fixup_by_prop(blob, "device_type", "network", 8,
 163                "address", enetaddr, 6, 0);
 164        /*
 165         * old device trees have soc nodes with
 166         * device_type = "soc"
 167         */
 168        do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
 169                "bus-frequency", bd->bi_ipsfreq, 0);
 170}
 171#endif
 172
 173static void ft_clock_setup(void *blob, bd_t *bd)
 174{
 175        char *cpu_path = "/cpus/" OF_CPU;
 176
 177        /*
 178         * fixup cpu clocks using path
 179         */
 180        do_fixup_by_path_u32(blob, cpu_path,
 181                "timebase-frequency", OF_TBCLK, 1);
 182        do_fixup_by_path_u32(blob, cpu_path,
 183                "bus-frequency", bd->bi_busfreq, 1);
 184        do_fixup_by_path_u32(blob, cpu_path,
 185                "clock-frequency", bd->bi_intfreq, 1);
 186        /*
 187         * fixup soc clocks using compatible
 188         */
 189        do_fixup_by_compat_u32(blob, OF_SOC_COMPAT,
 190                "bus-frequency", bd->bi_ipsfreq, 1);
 191}
 192
 193void ft_cpu_setup(void *blob, bd_t *bd)
 194{
 195#ifdef CONFIG_OF_SUPPORT_OLD_DEVICE_TREES
 196        old_ft_cpu_setup(blob, bd);
 197#endif
 198        ft_clock_setup(blob, bd);
 199#ifdef CONFIG_HAS_ETH0
 200        fdt_fixup_ethernet(blob);
 201#endif
 202        fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
 203}
 204#endif
 205
 206#ifdef CONFIG_MPC512x_FEC
 207/* Default initializations for FEC controllers.  To override,
 208 * create a board-specific function called:
 209 *      int board_eth_init(bd_t *bis)
 210 */
 211
 212int cpu_eth_init(bd_t *bis)
 213{
 214        return mpc512x_fec_initialize(bis);
 215}
 216#endif
 217