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