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 | ||
13 | #include <asm/bootinfo.h> | |
14 | #include <asm/cacheflush.h> | |
bdc92d74 | 15 | #include <asm/idle.h> |
35832e26 MSJ |
16 | #include <asm/r4kcache.h> |
17 | #include <asm/reboot.h> | |
2fd43108 | 18 | #include <asm/smp-ops.h> |
35832e26 MSJ |
19 | #include <asm/time.h> |
20 | ||
21 | #include <msp_prom.h> | |
22 | #include <msp_regs.h> | |
23 | ||
24 | #if defined(CONFIG_PMC_MSP7120_GW) | |
25 | #include <msp_regops.h> | |
35832e26 MSJ |
26 | #define MSP_BOARD_RESET_GPIO 9 |
27 | #endif | |
28 | ||
35832e26 MSJ |
29 | extern void msp_serial_setup(void); |
30 | extern void pmctwiled_setup(void); | |
31 | ||
32 | #if defined(CONFIG_PMC_MSP7120_EVAL) || \ | |
33 | defined(CONFIG_PMC_MSP7120_GW) || \ | |
34 | defined(CONFIG_PMC_MSP7120_FPGA) | |
35 | /* | |
36 | * Performs the reset for MSP7120-based boards | |
37 | */ | |
38 | void msp7120_reset(void) | |
39 | { | |
40 | void *start, *end, *iptr; | |
41 | register int i; | |
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" | |
52 | " .set mips3 \n" | |
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 */ | |
81 | for (i = 0; i < 100000000; i++); | |
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 | ||
088f3876 A |
151 | extern struct plat_smp_ops msp_smtc_smp_ops; |
152 | ||
35832e26 MSJ |
153 | void __init prom_init(void) |
154 | { | |
155 | unsigned long family; | |
156 | unsigned long revision; | |
157 | ||
158 | prom_argc = fw_arg0; | |
159 | prom_argv = (char **)fw_arg1; | |
160 | prom_envp = (char **)fw_arg2; | |
161 | ||
162 | /* | |
163 | * Someday we can use this with PMON2000 to get a | |
164 | * platform call prom routines for output etc. without | |
165 | * having to use grody hacks. For now it's unused. | |
166 | * | |
167 | * struct callvectors *cv = (struct callvectors *) fw_arg3; | |
168 | */ | |
169 | family = identify_family(); | |
170 | revision = identify_revision(); | |
171 | ||
70342287 | 172 | switch (family) { |
35832e26 MSJ |
173 | case FAMILY_FPGA: |
174 | if (FPGA_IS_MSP4200(revision)) { | |
175 | /* Old-style revision ID */ | |
35832e26 MSJ |
176 | mips_machtype = MACH_MSP4200_FPGA; |
177 | } else { | |
35832e26 MSJ |
178 | mips_machtype = MACH_MSP_OTHER; |
179 | } | |
180 | break; | |
181 | ||
182 | case FAMILY_MSP4200: | |
35832e26 MSJ |
183 | #if defined(CONFIG_PMC_MSP4200_EVAL) |
184 | mips_machtype = MACH_MSP4200_EVAL; | |
185 | #elif defined(CONFIG_PMC_MSP4200_GW) | |
186 | mips_machtype = MACH_MSP4200_GW; | |
187 | #else | |
188 | mips_machtype = MACH_MSP_OTHER; | |
189 | #endif | |
190 | break; | |
191 | ||
192 | case FAMILY_MSP4200_FPGA: | |
35832e26 MSJ |
193 | mips_machtype = MACH_MSP4200_FPGA; |
194 | break; | |
195 | ||
196 | case FAMILY_MSP7100: | |
35832e26 MSJ |
197 | #if defined(CONFIG_PMC_MSP7120_EVAL) |
198 | mips_machtype = MACH_MSP7120_EVAL; | |
199 | #elif defined(CONFIG_PMC_MSP7120_GW) | |
200 | mips_machtype = MACH_MSP7120_GW; | |
201 | #else | |
202 | mips_machtype = MACH_MSP_OTHER; | |
203 | #endif | |
204 | break; | |
205 | ||
206 | case FAMILY_MSP7100_FPGA: | |
35832e26 MSJ |
207 | mips_machtype = MACH_MSP7120_FPGA; |
208 | break; | |
209 | ||
210 | default: | |
211 | /* we don't recognize the machine */ | |
35832e26 | 212 | mips_machtype = MACH_UNKNOWN; |
ab75dc02 | 213 | panic("***Bogosity factor five***, exiting"); |
05dc8c02 | 214 | break; |
35832e26 MSJ |
215 | } |
216 | ||
217 | prom_init_cmdline(); | |
218 | ||
219 | prom_meminit(); | |
220 | ||
221 | /* | |
222 | * Sub-system setup follows. | |
70342287 | 223 | * Setup functions can either be called here or using the |
35832e26 MSJ |
224 | * subsys_initcall mechanism (i.e. see msp_pci_setup). The |
225 | * order in which they are called can be changed by using the | |
226 | * link order in arch/mips/pmc-sierra/msp71xx/Makefile. | |
227 | * | |
228 | * NOTE: Please keep sub-system specific initialization code | |
229 | * in separate specific files. | |
230 | */ | |
231 | msp_serial_setup(); | |
232 | ||
852fe310 | 233 | if (register_vsmp_smp_ops()) { |
088f3876 | 234 | #ifdef CONFIG_MIPS_MT_SMTC |
852fe310 | 235 | register_smp_ops(&msp_smtc_smp_ops); |
088f3876 | 236 | #endif |
852fe310 | 237 | } |
088f3876 | 238 | |
35832e26 MSJ |
239 | #ifdef CONFIG_PMCTWILED |
240 | /* | |
241 | * Setup LED states before the subsys_initcall loads other | |
25985edc | 242 | * dependent drivers/modules. |
35832e26 MSJ |
243 | */ |
244 | pmctwiled_setup(); | |
245 | #endif | |
246 | } |