import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / mips / mips-boards / generic / init.c
1 /*
2  * Carsten Langgaard, carstenl@mips.com
3  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
4  *
5  *  This program is free software; you can distribute it and/or modify it
6  *  under the terms of the GNU General Public License (Version 2) as
7  *  published by the Free Software Foundation.
8  *
9  *  This program is distributed in the hope it will be useful, but WITHOUT
10  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  *  for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17  *
18  * PROM library initialisation code.
19  */
20 #include <linux/config.h>
21 #include <linux/init.h>
22 #include <linux/string.h>
23 #include <linux/kernel.h>
24
25 #include <asm/io.h>
26 #include <asm/mips-boards/prom.h>
27 #include <asm/mips-boards/generic.h>
28 #include <asm/gt64120/gt64120.h>
29 #include <asm/mips-boards/msc01_pci.h>
30 #include <asm/mips-boards/bonito64.h>
31 #ifdef CONFIG_MIPS_MALTA
32 #include <asm/mips-boards/malta.h>
33 #endif
34
35 /* Environment variable */
36 typedef struct {
37         char *name;
38         char *val;
39 } t_env_var;
40
41 int prom_argc;
42 int *_prom_argv, *_prom_envp;
43
44 /*
45  * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
46  * This macro take care of sign extension, if running in 64-bit mode.
47  */
48 #define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)]))
49
50 int init_debug = 0;
51
52 unsigned int mips_revision_corid;
53
54 /*
55  * Algorithmics Bonito64 system controller register base.
56  */
57 char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE);
58
59 char *prom_getenv(char *envname)
60 {
61         /*
62          * Return a pointer to the given environment variable.
63          * In 64-bit mode: we're using 64-bit pointers, but all pointers
64          * in the PROM structures are only 32-bit, so we need some
65          * workarounds, if we are running in 64-bit mode.
66          */
67         int i, index=0;
68
69         i = strlen(envname);
70
71         while (prom_envp(index)) {
72                 if(strncmp(envname, prom_envp(index), i) == 0) {
73                         return(prom_envp(index+1));
74                 }
75                 index += 2;
76         }
77
78         return NULL;
79 }
80
81 static inline unsigned char str2hexnum(unsigned char c)
82 {
83         if (c >= '0' && c <= '9')
84                 return c - '0';
85         if (c >= 'a' && c <= 'f')
86                 return c - 'a' + 10;
87         return 0; /* foo */
88 }
89
90 static inline void str2eaddr(unsigned char *ea, unsigned char *str)
91 {
92         int i;
93
94         for (i = 0; i < 6; i++) {
95                 unsigned char num;
96
97                 if((*str == '.') || (*str == ':'))
98                         str++;
99                 num = str2hexnum(*str++) << 4;
100                 num |= (str2hexnum(*str++));
101                 ea[i] = num;
102         }
103 }
104
105 int get_ethernet_addr(char *ethernet_addr)
106 {
107         char *ethaddr_str;
108
109         ethaddr_str = prom_getenv("ethaddr");
110         if (!ethaddr_str) {
111                 printk("ethaddr not set in boot prom\n");
112                 return -1;
113         }
114         str2eaddr(ethernet_addr, ethaddr_str);
115
116         if (init_debug > 1) {
117                 int i;
118                 printk("get_ethernet_addr: ");
119                 for (i=0; i<5; i++)
120                         printk("%02x:", (unsigned char)*(ethernet_addr+i));
121                 printk("%02x\n", *(ethernet_addr+i));
122         }
123
124         return 0;
125 }
126
127 int __init prom_init(int argc, char **argv, char **envp)
128 {
129         prom_argc = argc;
130         _prom_argv = (int *)argv;
131         _prom_envp = (int *)envp;
132
133         mips_display_message("LINUX");
134
135 #ifdef CONFIG_MIPS_SEAD
136         set_io_port_base(KSEG1);
137 #else
138         mips_revision_corid = MIPS_REVISION_CORID;
139         switch(mips_revision_corid) {
140         case MIPS_REVISION_CORID_QED_RM5261:
141         case MIPS_REVISION_CORID_CORE_LV:
142         case MIPS_REVISION_CORID_CORE_FPGA:
143                 /*
144                  * Setup the North bridge to do Master byte-lane swapping
145                  * when running in bigendian.
146                  */
147 #ifdef CONFIG_CPU_LITTLE_ENDIAN
148                 GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
149                          GT_PCI0_CMD_SBYTESWAP_BIT);
150 #else
151                 GT_WRITE(GT_PCI0_CMD_OFS, 0);
152 #endif
153
154 #ifdef CONFIG_MIPS_MALTA
155                 set_io_port_base(MALTA_GT_PORT_BASE);
156 #else
157                 set_io_port_base(KSEG1);
158 #endif
159
160                 break;
161         case MIPS_REVISION_CORID_BONITO64:
162         case MIPS_REVISION_CORID_CORE_20K:
163                 /*
164                  * Disable Bonito IOBC.
165                  */
166                 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
167                         ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
168                           BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
169
170                 /*
171                  * Setup the North bridge to do Master byte-lane swapping
172                  * when running in bigendian.
173                  */
174 #ifdef CONFIG_CPU_LITTLE_ENDIAN
175                 BONITO_BONGENCFG = BONITO_BONGENCFG &
176                         ~(BONITO_BONGENCFG_MSTRBYTESWAP |
177                           BONITO_BONGENCFG_BYTESWAP);
178 #else
179                 BONITO_BONGENCFG = BONITO_BONGENCFG |
180                         BONITO_BONGENCFG_MSTRBYTESWAP |
181                         BONITO_BONGENCFG_BYTESWAP;
182 #endif
183
184 #ifdef CONFIG_MIPS_MALTA
185                 set_io_port_base(MALTA_BONITO_PORT_BASE);
186 #else
187                 set_io_port_base(KSEG1);
188 #endif
189                 break;
190
191         case MIPS_REVISION_CORID_CORE_MSC:
192 #ifdef CONFIG_MIPS_MALTA
193                 set_io_port_base(MALTA_MSC_PORT_BASE);
194 #endif
195 #ifdef CONFIG_CPU_LITTLE_ENDIAN
196                 MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
197 #else
198                 MSC_WRITE(MSC01_PCI_SWAP,
199                           MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
200                           MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
201                           MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
202 #endif
203                 break;
204         default:
205                 /* Unknown Core card */
206                 mips_display_message("CC Error");
207                 while(1);   /* We die here... */
208         }
209 #endif
210         prom_printf("\nLINUX started...\n");
211         prom_init_cmdline();
212         prom_meminit();
213
214         return 0;
215 }