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