linux/arch/mips/pmc-sierra/msp71xx/msp_setup.c
<<
>>
Prefs
   1/*
   2 * The generic setup file for PMC-Sierra MSP processors
   3 *
   4 * Copyright 2005-2007 PMC-Sierra, Inc,
   5 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
   6 *
   7 * This program is free software; you can redistribute  it and/or modify it
   8 * under  the terms of  the GNU General  Public License as published by the
   9 * Free Software Foundation;  either version 2 of the  License, or (at your
  10 * option) any later version.
  11 */
  12
  13#include <asm/bootinfo.h>
  14#include <asm/cacheflush.h>
  15#include <asm/r4kcache.h>
  16#include <asm/reboot.h>
  17#include <asm/time.h>
  18
  19#include <msp_prom.h>
  20#include <msp_regs.h>
  21
  22#if defined(CONFIG_PMC_MSP7120_GW)
  23#include <msp_regops.h>
  24#define MSP_BOARD_RESET_GPIO    9
  25#endif
  26
  27extern void msp_serial_setup(void);
  28extern void pmctwiled_setup(void);
  29
  30#if defined(CONFIG_PMC_MSP7120_EVAL) || \
  31    defined(CONFIG_PMC_MSP7120_GW) || \
  32    defined(CONFIG_PMC_MSP7120_FPGA)
  33/*
  34 * Performs the reset for MSP7120-based boards
  35 */
  36void msp7120_reset(void)
  37{
  38        void *start, *end, *iptr;
  39        register int i;
  40
  41        /* Diasble all interrupts */
  42        local_irq_disable();
  43#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING
  44        dvpe();
  45#endif
  46
  47        /* Cache the reset code of this function */
  48        __asm__ __volatile__ (
  49                "       .set    push                            \n"
  50                "       .set    mips3                           \n"
  51                "       la      %0,startpoint                   \n"
  52                "       la      %1,endpoint                     \n"
  53                "       .set    pop                             \n"
  54                : "=r" (start), "=r" (end)
  55                :
  56        );
  57
  58        for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1));
  59             iptr < end; iptr += L1_CACHE_BYTES)
  60                cache_op(Fill, iptr);
  61
  62        __asm__ __volatile__ (
  63                "startpoint:                                    \n"
  64        );
  65
  66        /* Put the DDRC into self-refresh mode */
  67        DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16);
  68
  69        /*
  70         * IMPORTANT!
  71         * DO NOT do anything from here on out that might even
  72         * think about fetching from RAM - i.e., don't call any
  73         * non-inlined functions, and be VERY sure that any inline
  74         * functions you do call do NOT access any sort of RAM
  75         * anywhere!
  76         */
  77
  78        /* Wait a bit for the DDRC to settle */
  79        for (i = 0; i < 100000000; i++);
  80
  81#if defined(CONFIG_PMC_MSP7120_GW)
  82        /*
  83         * Set GPIO 9 HI, (tied to board reset logic)
  84         * GPIO 9 is the 4th GPIO of register 3
  85         *
  86         * NOTE: We cannot use the higher-level msp_gpio_mode()/out()
  87         * as GPIO char driver may not be enabled and it would look up
  88         * data inRAM!
  89         */
  90        set_value_reg32(GPIO_CFG3_REG, 0xf000, 0x8000);
  91        set_reg32(GPIO_DATA3_REG, 8);
  92
  93        /*
  94         * In case GPIO9 doesn't reset the board (jumper configurable!)
  95         * fallback to device reset below.
  96         */
  97#endif
  98        /* Set bit 1 of the MSP7120 reset register */
  99        *RST_SET_REG = 0x00000001;
 100
 101        __asm__ __volatile__ (
 102                "endpoint:                                      \n"
 103        );
 104}
 105#endif
 106
 107void msp_restart(char *command)
 108{
 109        printk(KERN_WARNING "Now rebooting .......\n");
 110
 111#if defined(CONFIG_PMC_MSP7120_EVAL) || \
 112    defined(CONFIG_PMC_MSP7120_GW) || \
 113    defined(CONFIG_PMC_MSP7120_FPGA)
 114        msp7120_reset();
 115#else
 116        /* No chip-specific reset code, just jump to the ROM reset vector */
 117        set_c0_status(ST0_BEV | ST0_ERL);
 118        change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
 119        flush_cache_all();
 120        write_c0_wired(0);
 121
 122        __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
 123#endif
 124}
 125
 126void msp_halt(void)
 127{
 128        printk(KERN_WARNING "\n** You can safely turn off the power\n");
 129        while (1)
 130                /* If possible call official function to get CPU WARs */
 131                if (cpu_wait)
 132                        (*cpu_wait)();
 133                else
 134                        __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
 135}
 136
 137void msp_power_off(void)
 138{
 139        msp_halt();
 140}
 141
 142void __init plat_mem_setup(void)
 143{
 144        _machine_restart = msp_restart;
 145        _machine_halt = msp_halt;
 146        pm_power_off = msp_power_off;
 147}
 148
 149void __init prom_init(void)
 150{
 151        unsigned long family;
 152        unsigned long revision;
 153
 154        prom_argc = fw_arg0;
 155        prom_argv = (char **)fw_arg1;
 156        prom_envp = (char **)fw_arg2;
 157
 158        /*
 159         * Someday we can use this with PMON2000 to get a
 160         * platform call prom routines for output etc. without
 161         * having to use grody hacks.  For now it's unused.
 162         *
 163         * struct callvectors *cv = (struct callvectors *) fw_arg3;
 164         */
 165        family = identify_family();
 166        revision = identify_revision();
 167
 168        switch (family) {
 169        case FAMILY_FPGA:
 170                if (FPGA_IS_MSP4200(revision)) {
 171                        /* Old-style revision ID */
 172                        mips_machtype = MACH_MSP4200_FPGA;
 173                } else {
 174                        mips_machtype = MACH_MSP_OTHER;
 175                }
 176                break;
 177
 178        case FAMILY_MSP4200:
 179#if defined(CONFIG_PMC_MSP4200_EVAL)
 180                mips_machtype  = MACH_MSP4200_EVAL;
 181#elif defined(CONFIG_PMC_MSP4200_GW)
 182                mips_machtype  = MACH_MSP4200_GW;
 183#else
 184                mips_machtype = MACH_MSP_OTHER;
 185#endif
 186                break;
 187
 188        case FAMILY_MSP4200_FPGA:
 189                mips_machtype  = MACH_MSP4200_FPGA;
 190                break;
 191
 192        case FAMILY_MSP7100:
 193#if defined(CONFIG_PMC_MSP7120_EVAL)
 194                mips_machtype = MACH_MSP7120_EVAL;
 195#elif defined(CONFIG_PMC_MSP7120_GW)
 196                mips_machtype = MACH_MSP7120_GW;
 197#else
 198                mips_machtype = MACH_MSP_OTHER;
 199#endif
 200                break;
 201
 202        case FAMILY_MSP7100_FPGA:
 203                mips_machtype  = MACH_MSP7120_FPGA;
 204                break;
 205
 206        default:
 207                /* we don't recognize the machine */
 208                mips_machtype  = MACH_UNKNOWN;
 209                panic("***Bogosity factor five***, exiting\n");
 210                break;
 211        }
 212
 213        prom_init_cmdline();
 214
 215        prom_meminit();
 216
 217        /*
 218         * Sub-system setup follows.
 219         * Setup functions can  either be called here or using the
 220         * subsys_initcall mechanism (i.e. see msp_pci_setup). The
 221         * order in which they are called can be changed by using the
 222         * link order in arch/mips/pmc-sierra/msp71xx/Makefile.
 223         *
 224         * NOTE: Please keep sub-system specific initialization code
 225         * in separate specific files.
 226         */
 227        msp_serial_setup();
 228
 229#ifdef CONFIG_PMCTWILED
 230        /*
 231         * Setup LED states before the subsys_initcall loads other
 232         * dependant drivers/modules.
 233         */
 234        pmctwiled_setup();
 235#endif
 236}
 237