http://www.usr.com/support/gpl/USR9107_release1.1.tar.gz
[bcm963xx.git] / kernel / linux / arch / mips / brcm-boards / bcm963xx / prom.c
1 /*
2 <:copyright-gpl 
3  Copyright 2004 Broadcom Corp. 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 */
19 /*
20  * prom.c: PROM library initialization code.
21  *
22  */
23 #include <linux/init.h>
24 #include <linux/mm.h>
25 #include <linux/sched.h>
26 #include <linux/bootmem.h>
27 #include <linux/blkdev.h>
28 #include <asm/addrspace.h>
29 #include <asm/bootinfo.h>
30 #include <asm/cpu.h>
31 #include <asm/time.h>
32
33 #include <bcm_map_part.h>
34 #include <board.h>
35 #include "boardparms.h"
36 #include "softdsl/AdslCoreDefs.h"
37
38
39 extern int  do_syslog(int, char *, int);
40 extern void serial_init(void);
41 extern void __init InitNvramInfo( void );
42 extern void kerSysFlashInit( void );
43 extern unsigned long get_nvram_start_addr(void);
44 void __init create_root_nfs_cmdline( char *cmdline );
45
46 #if defined(CONFIG_BCM96338)
47 #define CPU_CLOCK                   240000000
48 #define MACH_BCM                    MACH_BCM96338
49 #endif
50 #if defined(CONFIG_BCM96345)
51 #define CPU_CLOCK                   140000000
52 #define MACH_BCM                    MACH_BCM96345
53 #endif
54 #if defined(CONFIG_BCM96348)
55 void __init calculateCpuSpeed(void);
56 static unsigned long cpu_speed;
57 #define CPU_CLOCK                   cpu_speed
58 #define MACH_BCM                    MACH_BCM96348
59 #endif
60
61 const char *get_system_type(void)
62 {
63     PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
64
65     return( pNvramData->szBoardId );
66 }
67
68 unsigned long getMemorySize(void)
69 {
70     unsigned long ulSdramType = BOARD_SDRAM_TYPE;
71
72     unsigned long ulSdramSize;
73
74     switch( ulSdramType )
75     {
76     case BP_MEMORY_16MB_1_CHIP:
77     case BP_MEMORY_16MB_2_CHIP:
78         ulSdramSize = 16 * 1024 * 1024;
79         break;
80     case BP_MEMORY_32MB_1_CHIP:
81     case BP_MEMORY_32MB_2_CHIP:
82         ulSdramSize = 32 * 1024 * 1024;
83         break;
84     case BP_MEMORY_64MB_2_CHIP:
85         ulSdramSize = 64 * 1024 * 1024;
86         break;
87     default:
88         ulSdramSize = 8 * 1024 * 1024;
89         break;
90     }
91
92     return ulSdramSize;
93 }
94
95 /* --------------------------------------------------------------------------
96     Name: prom_init
97  -------------------------------------------------------------------------- */
98 void __init prom_init(void)
99 {
100     extern ulong r4k_interval;
101
102     serial_init();
103
104     kerSysFlashInit();
105
106     do_syslog(8, NULL, 8);
107
108     printk( "%s prom init\n", get_system_type() );
109
110     PERF->IrqMask = 0;
111
112     arcs_cmdline[0] = '\0';
113
114 #if defined(CONFIG_ROOT_NFS)
115     create_root_nfs_cmdline( arcs_cmdline );
116 #elif defined(CONFIG_ROOT_FLASHFS)
117     strcpy(arcs_cmdline, CONFIG_ROOT_FLASHFS);
118 #endif
119
120     add_memory_region(0, (getMemorySize() - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
121
122 #if defined(CONFIG_BCM96348)
123     calculateCpuSpeed();
124 #endif
125     /* Count register increments every other clock */
126     r4k_interval = CPU_CLOCK / HZ / 2;
127     mips_hpt_frequency = CPU_CLOCK / 2;
128
129     mips_machgroup = MACH_GROUP_BRCM;
130     mips_machtype = MACH_BCM;
131 }
132
133 /* --------------------------------------------------------------------------
134     Name: prom_free_prom_memory
135 Abstract: 
136  -------------------------------------------------------------------------- */
137 void __init prom_free_prom_memory(void)
138 {
139
140 }
141
142
143 #if defined(CONFIG_ROOT_NFS)
144 /* This function reads in a line that looks something like this:
145  *
146  *
147  * CFE bootline=bcmEnet(0,0)host:vmlinux e=192.169.0.100:ffffff00 h=192.169.0.1
148  *
149  *
150  * and retuns in the cmdline parameter some that looks like this:
151  *
152  * CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/opt/targets/96345R/fs
153  * ip=192.168.0.100:192.168.0.1::255.255.255.0::eth0:off rw"
154  */
155 #define BOOT_LINE_ADDR   0x0
156 #define HEXDIGIT(d) ((d >= '0' && d <= '9') ? (d - '0') : ((d | 0x20) - 'W'))
157 #define HEXBYTE(b)  (HEXDIGIT((b)[0]) << 4) + HEXDIGIT((b)[1])
158 extern unsigned long get_nvram_start_addr(void);
159
160 void __init create_root_nfs_cmdline( char *cmdline )
161 {
162     char root_nfs_cl[] = "root=/dev/nfs nfsroot=%s:" CONFIG_ROOT_NFS_DIR
163         " ip=%s:%s::%s::eth0:off rw";
164
165     char *localip = NULL;
166     char *hostip = NULL;
167     char mask[16] = "";
168     PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr();
169     char bootline[128] = "";
170     char *p = bootline;
171
172     memcpy(bootline, pNvramData->szBootline, sizeof(bootline));
173     while( *p )
174     {
175         if( p[0] == 'e' && p[1] == '=' )
176         {
177             /* Found local ip address */
178             p += 2;
179             localip = p;
180             while( *p && *p != ' ' && *p != ':' )
181                 p++;
182             if( *p == ':' )
183             {
184                 /* Found network mask (eg FFFFFF00 */
185                 *p++ = '\0';
186                 sprintf( mask, "%u.%u.%u.%u", HEXBYTE(p), HEXBYTE(p + 2),
187                 HEXBYTE(p + 4), HEXBYTE(p + 6) );
188                 p += 4;
189             }
190             else if( *p == ' ' )
191                 *p++ = '\0';
192         }
193         else if( p[0] == 'h' && p[1] == '=' )
194         {
195             /* Found host ip address */
196             p += 2;
197             hostip = p;
198             while( *p && *p != ' ' )
199                 p++;
200             if( *p == ' ' )
201                     *p++ = '\0';
202         }
203         else 
204             p++;
205     }
206
207     if( localip && hostip ) 
208         sprintf( cmdline, root_nfs_cl, hostip, localip, hostip, mask );
209 }
210 #endif
211
212 #if defined(CONFIG_BCM96348)
213 /*  *********************************************************************
214     *  calculateCpuSpeed()
215     *      Calculate the BCM6348 CPU speed by reading the PLL strap register
216     *      and applying the following formula:
217     *      cpu_clk = (.25 * 64MHz freq) * (N1 + 1) * (N2 + 2) / (M1_CPU + 1)
218     *  Input parameters:
219     *      none
220     *  Return value:
221     *      none
222     ********************************************************************* */
223 void __init calculateCpuSpeed(void)
224 {
225     UINT32 pllStrap = PERF->PllStrap;
226     int n1 = (pllStrap & PLL_N1_MASK) >> PLL_N1_SHFT;
227     int n2 = (pllStrap & PLL_N2_MASK) >> PLL_N2_SHFT;
228     int m1cpu = (pllStrap & PLL_M1_CPU_MASK) >> PLL_M1_CPU_SHFT;
229
230     cpu_speed = (16 * (n1 + 1) * (n2 + 2) / (m1cpu + 1)) * 1000000;
231 }
232 #endif
233