Modified makefile for new build mechanism.
[oweals/u-boot.git] / board / mpc8641hpcn / pixis.c
1 /*
2  * Copyright 2006 Freescale Semiconductor
3  * Jeff Brown
4  * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <watchdog.h>
27 #include <command.h>
28 #include <asm/cache.h>
29 #include <mpc86xx.h>
30
31 #include "pixis.h"
32
33
34 /*
35  * Per table 27, page 58 of MPC8641HPCN spec.
36  */
37 int set_px_sysclk(ulong sysclk)
38 {
39         u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
40
41         switch (sysclk) {
42         case 33:
43                 sysclk_s = 0x04;
44                 sysclk_r = 0x04;
45                 sysclk_v = 0x07;
46                 sysclk_aux = 0x00;
47                 break;
48         case 40:
49                 sysclk_s = 0x01;
50                 sysclk_r = 0x1F;
51                 sysclk_v = 0x20;
52                 sysclk_aux = 0x01;
53                 break;
54         case 50:
55                 sysclk_s = 0x01;
56                 sysclk_r = 0x1F;
57                 sysclk_v = 0x2A;
58                 sysclk_aux = 0x02;
59                 break;
60         case 66:
61                 sysclk_s = 0x01;
62                 sysclk_r = 0x04;
63                 sysclk_v = 0x04;
64                 sysclk_aux = 0x03;
65                 break;
66         case 83:
67                 sysclk_s = 0x01;
68                 sysclk_r = 0x1F;
69                 sysclk_v = 0x4B;
70                 sysclk_aux = 0x04;
71                 break;
72         case 100:
73                 sysclk_s = 0x01;
74                 sysclk_r = 0x1F;
75                 sysclk_v = 0x5C;
76                 sysclk_aux = 0x05;
77                 break;
78         case 134:
79                 sysclk_s = 0x06;
80                 sysclk_r = 0x1F;
81                 sysclk_v = 0x3B;
82                 sysclk_aux = 0x06;
83                 break;
84         case 166:
85                 sysclk_s = 0x06;
86                 sysclk_r = 0x1F;
87                 sysclk_v = 0x4B;
88                 sysclk_aux = 0x07;
89                 break;
90         default:
91                 printf("Unsupported SYSCLK frequency.\n");
92                 return 0;
93         }
94
95         vclkh = (sysclk_s << 5) | sysclk_r;
96         vclkl = sysclk_v;
97
98         out8(PIXIS_BASE + PIXIS_VCLKH, vclkh);
99         out8(PIXIS_BASE + PIXIS_VCLKL, vclkl);
100
101         out8(PIXIS_BASE + PIXIS_AUX, sysclk_aux);
102
103         return 1;
104 }
105
106
107 int set_px_mpxpll(ulong mpxpll)
108 {
109         u8 tmp;
110         u8 val;
111
112         switch (mpxpll) {
113         case 2:
114         case 4:
115         case 6:
116         case 8:
117         case 10:
118         case 12:
119         case 14:
120         case 16:
121                 val = (u8) mpxpll;
122                 break;
123         default:
124                 printf("Unsupported MPXPLL ratio.\n");
125                 return 0;
126         }
127
128         tmp = in8(PIXIS_BASE + PIXIS_VSPEED1);
129         tmp = (tmp & 0xF0) | (val & 0x0F);
130         out8(PIXIS_BASE + PIXIS_VSPEED1, tmp);
131
132         return 1;
133 }
134
135
136 int set_px_corepll(ulong corepll)
137 {
138         u8 tmp;
139         u8 val;
140
141         switch ((int)corepll) {
142         case 20:
143                 val = 0x08;
144                 break;
145         case 25:
146                 val = 0x0C;
147                 break;
148         case 30:
149                 val = 0x10;
150                 break;
151         case 35:
152                 val = 0x1C;
153                 break;
154         case 40:
155                 val = 0x14;
156                 break;
157         case 45:
158                 val = 0x0E;
159                 break;
160         default:
161                 printf("Unsupported COREPLL ratio.\n");
162                 return 0;
163         }
164
165         tmp = in8(PIXIS_BASE + PIXIS_VSPEED0);
166         tmp = (tmp & 0xE0) | (val & 0x1F);
167         out8(PIXIS_BASE + PIXIS_VSPEED0, tmp);
168
169         return 1;
170 }
171
172
173 void read_from_px_regs(int set)
174 {
175         u8 mask = 0x1C;
176         u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0);
177
178         if (set)
179                 tmp = tmp | mask;
180         else
181                 tmp = tmp & ~mask;
182         out8(PIXIS_BASE + PIXIS_VCFGEN0, tmp);
183 }
184
185
186 void read_from_px_regs_altbank(int set)
187 {
188         u8 mask = 0x04;
189         u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1);
190
191         if (set)
192                 tmp = tmp | mask;
193         else
194                 tmp = tmp & ~mask;
195         out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp);
196 }
197
198
199 void set_altbank(void)
200 {
201         u8 tmp;
202
203         tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
204         tmp ^= 0x40;
205
206         out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
207 }
208
209
210 void set_px_go(void)
211 {
212         u8 tmp;
213
214         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
215         tmp = tmp & 0x1E;
216         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
217
218         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
219         tmp = tmp | 0x01;
220         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
221 }
222
223
224 void set_px_go_with_watchdog(void)
225 {
226         u8 tmp;
227
228         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
229         tmp = tmp & 0x1E;
230         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
231
232         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
233         tmp = tmp | 0x09;
234         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
235 }
236
237
238 int disable_watchdog(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
239 {
240         u8 tmp;
241
242         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
243         tmp = tmp & 0x1E;
244         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
245
246         /* setting VCTL[WDEN] to 0 to disable watch dog */
247         tmp = in8(PIXIS_BASE + PIXIS_VCTL);
248         tmp &= ~0x08;
249         out8(PIXIS_BASE + PIXIS_VCTL, tmp);
250
251         return 0;
252 }
253
254 U_BOOT_CMD(
255            diswd, 1, 0, disable_watchdog,
256            "diswd       - Disable watchdog timer \n",
257            NULL);
258
259 /*
260  * This function takes the non-integral cpu:mpx pll ratio
261  * and converts it to an integer that can be used to assign
262  * FPGA register values.
263  * input: strptr i.e. argv[2]
264  */
265
266 ulong strfractoint(uchar *strptr)
267 {
268         int i, j, retval;
269         int mulconst;
270         int intarr_len = 0, decarr_len = 0, no_dec = 0;
271         ulong intval = 0, decval = 0;
272         uchar intarr[3], decarr[3];
273
274         /* Assign the integer part to intarr[]
275          * If there is no decimal point i.e.
276          * if the ratio is an integral value
277          * simply create the intarr.
278          */
279         i = 0;
280         while (strptr[i] != 46) {
281                 if (strptr[i] == 0) {
282                         no_dec = 1;
283                         break;
284                 }
285                 intarr[i] = strptr[i];
286                 i++;
287         }
288
289         /* Assign length of integer part to intarr_len. */
290         intarr_len = i;
291         intarr[i] = '\0';
292
293         if (no_dec) {
294                 /* Currently needed only for single digit corepll ratios */
295                 mulconst = 10;
296                 decval = 0;
297         } else {
298                 j = 0;
299                 i++;            /* Skipping the decimal point */
300                 while ((strptr[i] > 47) && (strptr[i] < 58)) {
301                         decarr[j] = strptr[i];
302                         i++;
303                         j++;
304                 }
305
306                 decarr_len = j;
307                 decarr[j] = '\0';
308
309                 mulconst = 1;
310                 for (i = 0; i < decarr_len; i++)
311                         mulconst *= 10;
312                 decval = simple_strtoul(decarr, NULL, 10);
313         }
314
315         intval = simple_strtoul(intarr, NULL, 10);
316         intval = intval * mulconst;
317
318         retval = intval + decval;
319
320         return retval;
321 }