uboot/arch/powerpc/cpu/mpc83xx/cpu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
   4 */
   5
   6/*
   7 * CPU specific code for the MPC83xx family.
   8 *
   9 * Derived from the MPC8260 and MPC85xx.
  10 */
  11
  12#include <common.h>
  13#include <cpu_func.h>
  14#include <irq_func.h>
  15#include <net.h>
  16#include <time.h>
  17#include <vsprintf.h>
  18#include <watchdog.h>
  19#include <command.h>
  20#include <mpc83xx.h>
  21#include <asm/global_data.h>
  22#include <asm/processor.h>
  23#include <linux/delay.h>
  24#include <linux/libfdt.h>
  25#include <tsec.h>
  26#include <netdev.h>
  27#include <fsl_esdhc.h>
  28#if defined(CONFIG_BOOTCOUNT_LIMIT) && !defined(CONFIG_ARCH_MPC831X)
  29#include <linux/immap_qe.h>
  30#include <asm/io.h>
  31#endif
  32
  33DECLARE_GLOBAL_DATA_PTR;
  34
  35#ifndef CONFIG_CPU_MPC83XX
  36int checkcpu(void)
  37{
  38        volatile immap_t *immr;
  39        ulong clock = gd->cpu_clk;
  40        u32 pvr = get_pvr();
  41        u32 spridr;
  42        char buf[32];
  43        int ret;
  44        int i;
  45
  46        const struct cpu_type {
  47                char name[15];
  48                u32 partid;
  49        } cpu_type_list [] = {
  50                CPU_TYPE_ENTRY(8308),
  51                CPU_TYPE_ENTRY(8309),
  52                CPU_TYPE_ENTRY(8311),
  53                CPU_TYPE_ENTRY(8313),
  54                CPU_TYPE_ENTRY(8314),
  55                CPU_TYPE_ENTRY(8315),
  56                CPU_TYPE_ENTRY(8321),
  57                CPU_TYPE_ENTRY(8323),
  58                CPU_TYPE_ENTRY(8343),
  59                CPU_TYPE_ENTRY(8347_TBGA_),
  60                CPU_TYPE_ENTRY(8347_PBGA_),
  61                CPU_TYPE_ENTRY(8349),
  62                CPU_TYPE_ENTRY(8358_TBGA_),
  63                CPU_TYPE_ENTRY(8358_PBGA_),
  64                CPU_TYPE_ENTRY(8360),
  65                CPU_TYPE_ENTRY(8377),
  66                CPU_TYPE_ENTRY(8378),
  67                CPU_TYPE_ENTRY(8379),
  68        };
  69
  70        immr = (immap_t *)CONFIG_SYS_IMMR;
  71
  72        ret = prt_83xx_rsr();
  73        if (ret)
  74                return ret;
  75
  76        puts("CPU:   ");
  77
  78        switch (pvr & 0xffff0000) {
  79                case PVR_E300C1:
  80                        printf("e300c1, ");
  81                        break;
  82
  83                case PVR_E300C2:
  84                        printf("e300c2, ");
  85                        break;
  86
  87                case PVR_E300C3:
  88                        printf("e300c3, ");
  89                        break;
  90
  91                case PVR_E300C4:
  92                        printf("e300c4, ");
  93                        break;
  94
  95                default:
  96                        printf("Unknown core, ");
  97        }
  98
  99        spridr = immr->sysconf.spridr;
 100
 101        for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
 102                if (cpu_type_list[i].partid == PARTID_NO_E(spridr)) {
 103                        puts("MPC");
 104                        puts(cpu_type_list[i].name);
 105                        if (IS_E_PROCESSOR(spridr))
 106                                puts("E");
 107                        if ((SPR_FAMILY(spridr) == SPR_834X_FAMILY ||
 108                             SPR_FAMILY(spridr) == SPR_836X_FAMILY) &&
 109                            REVID_MAJOR(spridr) >= 2)
 110                                puts("A");
 111                        printf(", Rev: %d.%d", REVID_MAJOR(spridr),
 112                               REVID_MINOR(spridr));
 113                        break;
 114                }
 115
 116        if (i == ARRAY_SIZE(cpu_type_list))
 117                printf("(SPRIDR %08x unknown), ", spridr);
 118
 119        printf(" at %s MHz, ", strmhz(buf, clock));
 120
 121        printf("CSB: %s MHz\n", strmhz(buf, gd->arch.csb_clk));
 122
 123        return 0;
 124}
 125#endif
 126
 127#ifndef CONFIG_SYSRESET
 128int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 129{
 130        ulong msr;
 131        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 132
 133        puts("Resetting the board.\n");
 134
 135        /* Interrupts and MMU off */
 136        msr = mfmsr();
 137        msr &= ~(MSR_EE | MSR_IR | MSR_DR);
 138        mtmsr(msr);
 139
 140        /* enable Reset Control Reg */
 141        immap->reset.rpr = 0x52535445;
 142        sync();
 143        isync();
 144
 145        /* confirm Reset Control Reg is enabled */
 146        while(!((immap->reset.rcer) & RCER_CRE))
 147                ;
 148
 149        udelay(200);
 150
 151        /* perform reset, only one bit */
 152        immap->reset.rcr = RCR_SWHR;
 153
 154        return 1;
 155}
 156#endif
 157
 158/*
 159 * Get timebase clock frequency (like cpu_clk in Hz)
 160 */
 161#ifndef CONFIG_TIMER
 162unsigned long get_tbclk(void)
 163{
 164        return (gd->bus_clk + 3L) / 4L;
 165}
 166#endif
 167
 168#if defined(CONFIG_WATCHDOG)
 169void watchdog_reset (void)
 170{
 171        int re_enable = disable_interrupts();
 172
 173        /* Reset the 83xx watchdog */
 174        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 175        immr->wdt.swsrr = 0x556c;
 176        immr->wdt.swsrr = 0xaa39;
 177
 178        if (re_enable)
 179                enable_interrupts();
 180}
 181#endif
 182
 183#ifndef CONFIG_DM_ETH
 184/*
 185 * Initializes on-chip ethernet controllers.
 186 * to override, implement board_eth_init()
 187 */
 188int cpu_eth_init(struct bd_info *bis)
 189{
 190#if defined(CONFIG_UEC_ETH)
 191        uec_standard_init(bis);
 192#endif
 193
 194#if defined(CONFIG_TSEC_ENET)
 195        tsec_standard_init(bis);
 196#endif
 197        return 0;
 198}
 199#endif /* !CONFIG_DM_ETH */
 200
 201/*
 202 * Initializes on-chip MMC controllers.
 203 * to override, implement board_mmc_init()
 204 */
 205int cpu_mmc_init(struct bd_info *bis)
 206{
 207#ifdef CONFIG_FSL_ESDHC
 208        return fsl_esdhc_mmc_init(bis);
 209#else
 210        return 0;
 211#endif
 212}
 213
 214void ppcDWstore(unsigned int *addr, unsigned int *value)
 215{
 216        asm("lfd 1, 0(%1)\n\t"
 217            "stfd 1, 0(%0)"
 218            :
 219            : "r" (addr), "r" (value)
 220            : "memory");
 221}
 222
 223void ppcDWload(unsigned int *addr, unsigned int *ret)
 224{
 225        asm("lfd 1, 0(%0)\n\t"
 226            "stfd 1, 0(%1)"
 227            :
 228            : "r" (addr), "r" (ret)
 229            : "memory");
 230}
 231