]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc86xx/speed.c
0f5a6388ce11cdbeb8badb80a1b0be803e53d502
[karo-tx-uboot.git] / cpu / mpc86xx / speed.c
1 /*
2  * Copyright 2004 Freescale Semiconductor.
3  * Jeff Brown (jeffrey@freescale.com)
4  * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
5  *
6  * (C) Copyright 2000-2002
7  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <common.h>
29 #include <mpc86xx.h>
30 #include <asm/processor.h>
31
32 unsigned long get_board_sys_clk(ulong dummy);
33 unsigned long get_sysclk_from_px_regs(void);
34
35
36 /* --------------------------------------------------------------- */
37
38 void get_sys_info (sys_info_t * sysInfo)
39 {
40         volatile immap_t    *immap = (immap_t *)CFG_IMMR;
41         volatile ccsr_gur_t *gur = &immap->im_gur;
42         uint plat_ratio, e600_ratio;
43
44         plat_ratio = (gur->porpllsr) & 0x0000003e;
45         plat_ratio >>= 1;
46         
47         switch(plat_ratio) {
48         case 0x0:
49                 sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ;
50                 break;
51         case 0x02:
52         case 0x03:
53         case 0x04:
54         case 0x05:
55         case 0x06:
56         case 0x08:
57         case 0x09:
58         case 0x0a:
59         case 0x0c:
60         case 0x10:
61                 sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
62                 break;
63         default:
64                 sysInfo->freqSystemBus = 0;
65                 break;
66         }
67
68         //        printf("assigned system bus freq = %d for plat ratio 0x%08lx\n", sysInfo->freqSystemBus, plat_ratio);
69         e600_ratio = (gur->porpllsr) & 0x003f0000;
70         e600_ratio >>= 16;
71         switch(e600_ratio) {     
72         case 0x10:
73                 sysInfo->freqProcessor = 2*sysInfo->freqSystemBus;
74                 break;
75         case 0x19:                
76                 sysInfo->freqProcessor = 5*sysInfo->freqSystemBus/2;
77                 break;
78         case 0x20:
79                 sysInfo->freqProcessor = 3*sysInfo->freqSystemBus;
80                 break;
81         case 0x39:
82                 sysInfo->freqProcessor = 7*sysInfo->freqSystemBus/2;
83                 break;
84         case 0x28:
85                 sysInfo->freqProcessor = 4*sysInfo->freqSystemBus;
86                 break;
87         case 0x1d:
88                 sysInfo->freqProcessor = 9*sysInfo->freqSystemBus/2;
89                 break;
90         default:
91           /* JB - Emulator workaround until real cop is plugged in */
92           sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus;
93           //sysInfo->freqProcessor = 3*sysInfo->freqSystemBus;
94                 break;
95         }
96         //        printf("assigned processor freq = %d for e600 ratio 0x%08lx\n", sysInfo->freqProcessor, e600_ratio);
97
98 }
99
100
101 /* ------------------------------------------------------------------------- */
102
103 /*
104  * Measure CPU clock speed (core clock GCLK1, GCLK2)
105  *
106  * (Approx. GCLK frequency in Hz)
107  */
108
109 int get_clocks (void)
110 {
111         DECLARE_GLOBAL_DATA_PTR;
112         sys_info_t sys_info;
113
114         get_sys_info (&sys_info);
115         gd->cpu_clk = sys_info.freqProcessor;
116         gd->bus_clk = sys_info.freqSystemBus;
117         
118         if(gd->cpu_clk != 0) return (0);
119         else return (1);
120 }
121
122 /* ------------------------------------------------------------------------- */
123 /********************************************
124  * get_bus_freq
125  * return system bus freq in Hz
126  *********************************************/
127 ulong get_bus_freq (ulong dummy)
128 {
129         ulong val;
130
131         sys_info_t sys_info;
132
133         get_sys_info (&sys_info);
134         val = sys_info.freqSystemBus;
135
136         return val;
137 }
138
139 unsigned long get_sysclk_from_px_regs()
140 {
141    ulong val;
142    u8 vclkh,vclkl;
143    
144    vclkh = in8(PIXIS_BASE+PIXIS_VCLKH);
145    vclkl = in8(PIXIS_BASE+PIXIS_VCLKL);
146    
147    if((vclkh == 0x84) && (vclkl ==0x07))
148    {
149       val = 33000000;
150    }
151    if((vclkh == 0x3F) && (vclkl ==0x20))
152    {
153       val = 40000000;
154    }
155    if((vclkh == 0x3F) && (vclkl ==0x2A))
156    {
157       val = 50000000;
158    }
159    if((vclkh == 0x24) && (vclkl ==0x04))
160    {
161       val = 66000000;
162    }
163    if((vclkh == 0x3F) && (vclkl ==0x4B))
164    {
165       val = 83000000;
166    }
167    if((vclkh == 0x3F) && (vclkl ==0x5C))
168    {
169       val = 100000000;
170    }
171    if((vclkh == 0xDF) && (vclkl ==0x3B))
172    {
173       val = 134000000;
174    }
175    if((vclkh == 0xDF) && (vclkl ==0x4B))
176    {
177       val = 166000000;
178    }
179    
180    return val;
181 }
182
183 /******* From MPC8641HPCN Design Workbook ************
184  *
185  * get_board_sys_clk
186  * reads the FPGA on board for CONFIG_SYS_CLK_FREQ
187  *
188  ********************************************************/
189
190 unsigned long get_board_sys_clk(ulong dummy)
191 {
192    u8 i, go_bit, rd_clks;
193    ulong val;
194
195    go_bit = in8(PIXIS_BASE+PIXIS_VCTL);
196    go_bit &= 0x01;
197
198    rd_clks = in8(PIXIS_BASE+PIXIS_VCFGEN0);
199    rd_clks &= 0x1C;
200
201    /* Only if both go bit and the SCLK bit in VCFGEN0 are set
202     * should we be using the AUX register. Remember, we also set the
203     * GO bit to boot from the alternate bank on the on-board flash
204     */
205    
206    if(go_bit)
207    {
208       if(rd_clks == 0x1c)
209          i = in8(PIXIS_BASE+PIXIS_AUX);
210       else
211          i = in8(PIXIS_BASE+PIXIS_SPD);
212       //val = get_sysclk_from_px_regs();
213    }
214    else
215       i = in8(PIXIS_BASE+PIXIS_SPD);
216    
217    i &= 0x07;
218       
219    switch(i)
220    {
221       case 0:
222          val = 33000000;
223          break;
224       case 1:
225          val = 40000000;
226          break;
227       case 2:
228          val = 50000000;
229          break;
230       case 3:
231          val = 66000000;
232          break;
233       case 4:
234          val = 83000000;
235          break;
236       case 5:
237          val = 100000000;
238          break;
239       case 6:
240          val = 134000000;
241          break;
242       case 7:
243          val = 166000000;
244          break;
245    }
246    
247    return val;
248 }