Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[sfrench/cifs-2.6.git] / arch / mips / momentum / jaguar_atx / prom.c
1 /*
2  * Copyright 2002 Momentum Computer Inc.
3  * Author: Matthew Dharm <mdharm@momenco.com>
4  *
5  * Louis Hamilton, Red Hat, Inc.
6  * hamilton@redhat.com  [MIPS64 modifications]
7  *
8  * Based on Ocelot Linux port, which is
9  * Copyright 2001 MontaVista Software Inc.
10  * Author: jsun@mvista.com or jsun@junsun.net
11  *
12  * This program is free software; you can redistribute  it and/or modify it
13  * under  the terms of  the GNU General  Public License as published by the
14  * Free Software Foundation;  either version 2 of the  License, or (at your
15  * option) any later version.
16  *
17  * Added changes for SMP - Manish Lachwani (lachwani@pmc-sierra.com)
18  */
19 #include <linux/init.h>
20 #include <linux/mm.h>
21 #include <linux/sched.h>
22 #include <linux/bootmem.h>
23 #include <linux/mv643xx.h>
24
25 #include <asm/addrspace.h>
26 #include <asm/bootinfo.h>
27 #include <asm/pmon.h>
28
29 #include "jaguar_atx_fpga.h"
30
31 extern void ja_setup_console(void);
32
33 struct callvectors *debug_vectors;
34
35 extern unsigned long cpu_clock;
36
37 const char *get_system_type(void)
38 {
39         return "Momentum Jaguar-ATX";
40 }
41
42 #ifdef CONFIG_64BIT
43
44 unsigned long signext(unsigned long addr)
45 {
46         addr &= 0xffffffff;
47         return (unsigned long)((int)addr);
48 }
49
50 void *get_arg(unsigned long args, int arc)
51 {
52         unsigned long ul;
53         unsigned char *puc, uc;
54
55         args += (arc * 4);
56         ul = (unsigned long)signext(args);
57         puc = (unsigned char *)ul;
58         if (puc == 0)
59                 return (void *)0;
60
61 #ifdef CONFIG_CPU_LITTLE_ENDIAN
62         uc = *puc++;
63         l = (unsigned long)uc;
64         uc = *puc++;
65         ul |= (((unsigned long)uc) << 8);
66         uc = *puc++;
67         ul |= (((unsigned long)uc) << 16);
68         uc = *puc++;
69         ul |= (((unsigned long)uc) << 24);
70 #else
71         uc = *puc++;
72         ul = ((unsigned long)uc) << 24;
73         uc = *puc++;
74         ul |= (((unsigned long)uc) << 16);
75         uc = *puc++;
76         ul |= (((unsigned long)uc) << 8);
77         uc = *puc++;
78         ul |= ((unsigned long)uc);
79 #endif
80         ul = signext(ul);
81
82         return (void *)ul;
83 }
84
85 char *arg64(unsigned long addrin, int arg_index)
86 {
87         unsigned long args;
88         char *p;
89
90         args = signext(addrin);
91         p = (char *)get_arg(args, arg_index);
92
93         return p;
94 }
95 #endif  /* CONFIG_64BIT */
96
97 /* PMON passes arguments in C main() style */
98 void __init prom_init(void)
99 {
100         int argc = fw_arg0;
101         char **arg = (char **) fw_arg1;
102         char **env = (char **) fw_arg2;
103         struct callvectors *cv = (struct callvectors *) fw_arg3;
104         int i;
105
106 #ifdef CONFIG_SERIAL_8250_CONSOLE
107 //      ja_setup_console();     /* The very first thing.  */
108 #endif
109
110 #ifdef CONFIG_64BIT
111         char *ptr;
112
113         printk("Mips64 Jaguar-ATX\n");
114         /* save the PROM vectors for debugging use */
115         debug_vectors = (struct callvectors *)signext((unsigned long)cv);
116
117         /* arg[0] is "g", the rest is boot parameters */
118         arcs_cmdline[0] = '\0';
119
120         for (i = 1; i < argc; i++) {
121                 ptr = (char *)arg64((unsigned long)arg, i);
122                 if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
123                     sizeof(arcs_cmdline))
124                         break;
125                 strcat(arcs_cmdline, ptr);
126                 strcat(arcs_cmdline, " ");
127         }
128
129         i = 0;
130         while (1) {
131                 ptr = (char *)arg64((unsigned long)env, i);
132                 if (! ptr)
133                         break;
134
135                 if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
136                         marvell_base = simple_strtol(ptr + strlen("gtbase="),
137                                                         NULL, 16);
138
139                         if ((marvell_base & 0xffffffff00000000) == 0)
140                                 marvell_base |= 0xffffffff00000000;
141
142                         printk("marvell_base set to 0x%016lx\n", marvell_base);
143                 }
144                 if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
145                         cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
146                                                         NULL, 10);
147                         printk("cpu_clock set to %d\n", cpu_clock);
148                 }
149                 i++;
150         }
151         printk("arcs_cmdline: %s\n", arcs_cmdline);
152
153 #else   /* CONFIG_64BIT */
154         /* save the PROM vectors for debugging use */
155         debug_vectors = cv;
156
157         /* arg[0] is "g", the rest is boot parameters */
158         arcs_cmdline[0] = '\0';
159         for (i = 1; i < argc; i++) {
160                 if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
161                     >= sizeof(arcs_cmdline))
162                         break;
163                 strcat(arcs_cmdline, arg[i]);
164                 strcat(arcs_cmdline, " ");
165         }
166
167         while (*env) {
168                 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
169                         marvell_base = simple_strtol(*env + strlen("gtbase="),
170                                                         NULL, 16);
171                 }
172                 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
173                         cpu_clock = simple_strtol(*env + strlen("cpuclock="),
174                                                         NULL, 10);
175                 }
176                 env++;
177         }
178 #endif /* CONFIG_64BIT */
179         mips_machgroup = MACH_GROUP_MOMENCO;
180         mips_machtype = MACH_MOMENCO_JAGUAR_ATX;
181 }
182
183 void __init prom_free_prom_memory(void)
184 {
185 }
186
187 void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
188 {
189 }
190
191 int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
192 {
193         /* Clear the semaphore */
194         *(volatile uint32_t *)(0xbb000a68) = 0x80000000;
195
196         return 1;
197 }
198
199 void prom_init_secondary(void)
200 {
201         clear_c0_config(CONF_CM_CMASK);
202         set_c0_config(0x2);
203
204         clear_c0_status(ST0_IM);
205         set_c0_status(0x1ffff);
206 }
207
208 void prom_smp_finish(void)
209 {
210 }