ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / pmc-sierra / yosemite / prom.c
1 /*
2  * This program is free software; you can redistribute  it and/or modify it
3  * under  the terms of  the GNU General  Public License as published by the
4  * Free Software Foundation;  either version 2 of the  License, or (at your
5  * option) any later version.
6  *
7  * Copyright (C) 2003 PMC-Sierra Inc.
8  * Author: Manish Lachwani (lachwani@pmc-sierra.com)
9  */
10
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <asm/io.h>
14 #include <asm/pgtable.h>
15 #include <asm/processor.h>
16 #include <asm/reboot.h>
17 #include <asm/system.h>
18 #include <linux/delay.h>
19 #include <linux/smp.h>
20 #include <asm/bootinfo.h>
21
22 #include "setup.h"
23
24 /* Call Vectors */
25 struct callvectors {
26         int     (*open) (char*, int, int);
27         int     (*close) (int);
28         int     (*read) (int, void*, int);
29         int     (*write) (int, void*, int);
30         off_t   (*lseek) (int, off_t, int);
31         int     (*printf) (const char*, ...);
32         void    (*cacheflush) (void);
33         char*   (*gets) (char*);
34 };
35
36 struct callvectors* debug_vectors;
37
38 extern unsigned long yosemite_base;
39 extern unsigned long cpu_clock;
40 unsigned char titan_ge_mac_addr_base[6];
41
42 const char *get_system_type(void)
43 {
44         return "PMC-Sierra Yosemite";
45 }
46
47 static void prom_cpu0_exit(void)
48 {
49         void    *nvram = YOSEMITE_NVRAM_BASE_ADDR;
50         
51         /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
52         writeb(0x84, nvram + 0xff7);
53
54         /* wait for the watchdog to go off */
55         mdelay(100+(1000/16));
56
57         /* if the watchdog fails for some reason, let people know */
58         printk(KERN_NOTICE "Watchdog reset failed\n");
59 }
60
61 /*
62  * Reset the NVRAM over the local bus
63  */
64 static void prom_exit(void)
65 {
66 #ifdef CONFIG_SMP
67         if (smp_processor_id())
68                 /* CPU 1 */
69                 smp_call_function(prom_cpu0_exit, NULL, 1, 1);
70 #endif
71         prom_cpu0_exit;
72 }
73
74 /*
75  * Get the MAC address from the EEPROM using the I2C protocol
76  */
77 void get_mac_address(char dest[6])
78 {
79         /* Use the I2C command code in the i2c-yosemite */
80 }
81
82 /*
83  * Halt the system 
84  */
85 static void prom_halt(void)
86 {
87         printk(KERN_NOTICE "\n** You can safely turn off the power\n");
88         while (1)
89                 __asm__(".set\tmips3\n\t"
90                         "wait\n\t"
91                         ".set\tmips0");
92 }
93
94 /*
95  * Init routine which accepts the variables from PMON
96  */
97 __init prom_init(int argc, char **arg, char **env, struct callvectors *cv)
98 {
99         int     i = 0;
100
101         /* Callbacks for halt, restart */
102         _machine_restart = (void (*)(char *))prom_exit; 
103         _machine_halt = prom_halt;
104         _machine_power_off = prom_halt;
105
106 #ifdef CONFIG_MIPS64
107
108         /* Do nothing for the 64-bit for now. Just implement for the 32-bit */
109
110 #else /* CONFIG_MIPS64 */
111
112         debug_vectors = cv;
113         arcs_cmdline[0] = '\0';
114
115         /* Get the boot parameters */
116         for (i = 1; i < argc; i++) {
117                 if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline))
118                         break;
119
120                 strcat(arcs_cmdline, arg[i]);
121                 strcat(arcs_cmdline, " ");
122         }
123
124         while (*env) {
125                 if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) 
126                         yosemite_base = simple_strtol(*env + strlen("ocd_base="),
127                                                         NULL, 16);
128
129                 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) 
130                         cpu_clock = simple_strtol(*env + strlen("cpuclock="),
131                                                         NULL, 10);
132                 
133                 env++;
134         }
135 #endif /* CONFIG_MIPS64 */
136
137         mips_machgroup = MACH_GROUP_TITAN;
138         mips_machtype = MACH_TITAN_YOSEMITE;
139
140         get_mac_address(titan_ge_mac_addr_base);
141
142         debug_vectors->printf("Booting Linux kernel...\n");
143 }
144
145 void __init prom_free_prom_memory(void)
146 {
147 }
148
149 void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
150 {
151 }
152
153 extern void asmlinkage smp_bootstrap(void);
154
155 /*
156  * SMP support
157  */
158 int prom_setup_smp(void)
159 {
160         int     num_cpus = 2;
161
162         /*
163          * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this
164          * can be hardcoded for now.
165          */
166         return num_cpus;
167 }
168
169 int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
170 {
171         /* Clear the semaphore */
172         *(volatile uint32_t *)(0xbb000a68) = 0x80000000;
173
174         return 1;
175 }
176
177 void prom_init_secondary(void)
178 {
179         clear_c0_config(CONF_CM_CMASK);
180         set_c0_config(0x2);
181
182         clear_c0_status(ST0_IM);
183         set_c0_status(0x1ffff);
184 }
185
186 void prom_smp_finish(void)
187 {
188 }
189