source: SVN/rincon/u-boot/board/freescale/common/pixis.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 2 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 10.1 KB
Line 
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 <command.h>
27#include <watchdog.h>
28#include <asm/cache.h>
29#include <asm/io.h>
30
31#include "pixis.h"
32
33
34static ulong strfractoint(uchar *strptr);
35
36
37/*
38 * Simple board reset.
39 */
40void pixis_reset(void)
41{
42    out8(PIXIS_BASE + PIXIS_RST, 0);
43}
44
45
46/*
47 * Per table 27, page 58 of MPC8641HPCN spec.
48 */
49int set_px_sysclk(ulong sysclk)
50{
51        u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
52
53        switch (sysclk) {
54        case 33:
55                sysclk_s = 0x04;
56                sysclk_r = 0x04;
57                sysclk_v = 0x07;
58                sysclk_aux = 0x00;
59                break;
60        case 40:
61                sysclk_s = 0x01;
62                sysclk_r = 0x1F;
63                sysclk_v = 0x20;
64                sysclk_aux = 0x01;
65                break;
66        case 50:
67                sysclk_s = 0x01;
68                sysclk_r = 0x1F;
69                sysclk_v = 0x2A;
70                sysclk_aux = 0x02;
71                break;
72        case 66:
73                sysclk_s = 0x01;
74                sysclk_r = 0x04;
75                sysclk_v = 0x04;
76                sysclk_aux = 0x03;
77                break;
78        case 83:
79                sysclk_s = 0x01;
80                sysclk_r = 0x1F;
81                sysclk_v = 0x4B;
82                sysclk_aux = 0x04;
83                break;
84        case 100:
85                sysclk_s = 0x01;
86                sysclk_r = 0x1F;
87                sysclk_v = 0x5C;
88                sysclk_aux = 0x05;
89                break;
90        case 134:
91                sysclk_s = 0x06;
92                sysclk_r = 0x1F;
93                sysclk_v = 0x3B;
94                sysclk_aux = 0x06;
95                break;
96        case 166:
97                sysclk_s = 0x06;
98                sysclk_r = 0x1F;
99                sysclk_v = 0x4B;
100                sysclk_aux = 0x07;
101                break;
102        default:
103                printf("Unsupported SYSCLK frequency.\n");
104                return 0;
105        }
106
107        vclkh = (sysclk_s << 5) | sysclk_r;
108        vclkl = sysclk_v;
109
110        out8(PIXIS_BASE + PIXIS_VCLKH, vclkh);
111        out8(PIXIS_BASE + PIXIS_VCLKL, vclkl);
112
113        out8(PIXIS_BASE + PIXIS_AUX, sysclk_aux);
114
115        return 1;
116}
117
118
119int set_px_mpxpll(ulong mpxpll)
120{
121        u8 tmp;
122        u8 val;
123
124        switch (mpxpll) {
125        case 2:
126        case 4:
127        case 6:
128        case 8:
129        case 10:
130        case 12:
131        case 14:
132        case 16:
133                val = (u8) mpxpll;
134                break;
135        default:
136                printf("Unsupported MPXPLL ratio.\n");
137                return 0;
138        }
139
140        tmp = in8(PIXIS_BASE + PIXIS_VSPEED1);
141        tmp = (tmp & 0xF0) | (val & 0x0F);
142        out8(PIXIS_BASE + PIXIS_VSPEED1, tmp);
143
144        return 1;
145}
146
147
148int set_px_corepll(ulong corepll)
149{
150        u8 tmp;
151        u8 val;
152
153        switch ((int)corepll) {
154        case 20:
155                val = 0x08;
156                break;
157        case 25:
158                val = 0x0C;
159                break;
160        case 30:
161                val = 0x10;
162                break;
163        case 35:
164                val = 0x1C;
165                break;
166        case 40:
167                val = 0x14;
168                break;
169        case 45:
170                val = 0x0E;
171                break;
172        default:
173                printf("Unsupported COREPLL ratio.\n");
174                return 0;
175        }
176
177        tmp = in8(PIXIS_BASE + PIXIS_VSPEED0);
178        tmp = (tmp & 0xE0) | (val & 0x1F);
179        out8(PIXIS_BASE + PIXIS_VSPEED0, tmp);
180
181        return 1;
182}
183
184
185void read_from_px_regs(int set)
186{
187        u8 mask = 0x1C; /* COREPLL, MPXPLL, SYSCLK controlled by PIXIS */
188        u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN0);
189
190        if (set)
191                tmp = tmp | mask;
192        else
193                tmp = tmp & ~mask;
194        out8(PIXIS_BASE + PIXIS_VCFGEN0, tmp);
195}
196
197
198void read_from_px_regs_altbank(int set)
199{
200        u8 mask = 0x04; /* FLASHBANK and FLASHMAP controlled by PIXIS */
201        u8 tmp = in8(PIXIS_BASE + PIXIS_VCFGEN1);
202
203        if (set)
204                tmp = tmp | mask;
205        else
206                tmp = tmp & ~mask;
207        out8(PIXIS_BASE + PIXIS_VCFGEN1, tmp);
208}
209
210#ifndef CFG_PIXIS_VBOOT_MASK
211#define CFG_PIXIS_VBOOT_MASK    (0x40)
212#endif
213
214void clear_altbank(void)
215{
216        u8 tmp;
217
218        tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
219        tmp &= ~CFG_PIXIS_VBOOT_MASK;
220
221        out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
222}
223
224
225void set_altbank(void)
226{
227        u8 tmp;
228
229        tmp = in8(PIXIS_BASE + PIXIS_VBOOT);
230        tmp |= CFG_PIXIS_VBOOT_MASK;
231
232        out8(PIXIS_BASE + PIXIS_VBOOT, tmp);
233}
234
235
236void set_px_go(void)
237{
238        u8 tmp;
239
240        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
241        tmp = tmp & 0x1E;                       /* clear GO bit */
242        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
243
244        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
245        tmp = tmp | 0x01;       /* set GO bit - start reset sequencer */
246        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
247}
248
249
250void set_px_go_with_watchdog(void)
251{
252        u8 tmp;
253
254        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
255        tmp = tmp & 0x1E;
256        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
257
258        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
259        tmp = tmp | 0x09;
260        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
261}
262
263
264int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp,
265                               int flag, int argc, char *argv[])
266{
267        u8 tmp;
268
269        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
270        tmp = tmp & 0x1E;
271        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
272
273        /* setting VCTL[WDEN] to 0 to disable watch dog */
274        tmp = in8(PIXIS_BASE + PIXIS_VCTL);
275        tmp &= ~0x08;
276        out8(PIXIS_BASE + PIXIS_VCTL, tmp);
277
278        return 0;
279}
280
281U_BOOT_CMD(
282           diswd, 1, 0, pixis_disable_watchdog_cmd,
283           "diswd       - Disable watchdog timer \n",
284           NULL);
285
286#ifdef CONFIG_FSL_SGMII_RISER
287int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
288{
289        int which_tsec = -1;
290        uchar mask;
291        uchar switch_mask;
292
293        if (argc > 2)
294                if (strcmp(argv[1], "all") != 0)
295                        which_tsec = simple_strtoul(argv[1], NULL, 0);
296
297        switch (which_tsec) {
298        case 1:
299                mask = PIXIS_VSPEED2_TSEC1SER;
300                switch_mask = PIXIS_VCFGEN1_TSEC1SER;
301                break;
302        case 3:
303                mask = PIXIS_VSPEED2_TSEC3SER;
304                switch_mask = PIXIS_VCFGEN1_TSEC3SER;
305                break;
306        default:
307                mask = PIXIS_VSPEED2_TSEC1SER | PIXIS_VSPEED2_TSEC3SER;
308                switch_mask = PIXIS_VCFGEN1_TSEC1SER | PIXIS_VCFGEN1_TSEC3SER;
309                break;
310        }
311
312        /* Toggle whether the switches or FPGA control the settings */
313        if (!strcmp(argv[argc - 1], "switch"))
314                clrbits_8((unsigned char *)PIXIS_BASE + PIXIS_VCFGEN1,
315                        switch_mask);
316        else
317                setbits_8((unsigned char *)PIXIS_BASE + PIXIS_VCFGEN1,
318                        switch_mask);
319
320        /* If it's not the switches, enable or disable SGMII, as specified */
321        if (!strcmp(argv[argc - 1], "on"))
322                clrbits_8((unsigned char *)PIXIS_BASE + PIXIS_VSPEED2, mask);
323        else if (!strcmp(argv[argc - 1], "off"))
324                setbits_8((unsigned char *)PIXIS_BASE + PIXIS_VSPEED2, mask);
325
326        return 0;
327}
328
329U_BOOT_CMD(
330                pixis_set_sgmii, CFG_MAXARGS, 1, pixis_set_sgmii,
331                "pixis_set_sgmii"
332                " - Enable or disable SGMII mode for a given TSEC \n",
333                "\npixis_set_sgmii [TSEC num] <on|off|switch>\n"
334                "    TSEC num: 1,2,3,4 or 'all'.  'all' is default.\n"
335                "    on - enables SGMII\n"
336                "    off - disables SGMII\n"
337                "    switch - use switch settings\n");
338#endif
339
340/*
341 * This function takes the non-integral cpu:mpx pll ratio
342 * and converts it to an integer that can be used to assign
343 * FPGA register values.
344 * input: strptr i.e. argv[2]
345 */
346
347static ulong strfractoint(uchar *strptr)
348{
349        int i, j, retval;
350        int mulconst;
351        int intarr_len = 0, decarr_len = 0, no_dec = 0;
352        ulong intval = 0, decval = 0;
353        uchar intarr[3], decarr[3];
354
355        /* Assign the integer part to intarr[]
356         * If there is no decimal point i.e.
357         * if the ratio is an integral value
358         * simply create the intarr.
359         */
360        i = 0;
361        while (strptr[i] != '.') {
362                if (strptr[i] == 0) {
363                        no_dec = 1;
364                        break;
365                }
366                intarr[i] = strptr[i];
367                i++;
368        }
369
370        /* Assign length of integer part to intarr_len. */
371        intarr_len = i;
372        intarr[i] = '\0';
373
374        if (no_dec) {
375                /* Currently needed only for single digit corepll ratios */
376                mulconst = 10;
377                decval = 0;
378        } else {
379                j = 0;
380                i++;            /* Skipping the decimal point */
381                while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
382                        decarr[j] = strptr[i];
383                        i++;
384                        j++;
385                }
386
387                decarr_len = j;
388                decarr[j] = '\0';
389
390                mulconst = 1;
391                for (i = 0; i < decarr_len; i++)
392                        mulconst *= 10;
393                decval = simple_strtoul((char *)decarr, NULL, 10);
394        }
395
396        intval = simple_strtoul((char *)intarr, NULL, 10);
397        intval = intval * mulconst;
398
399        retval = intval + decval;
400
401        return retval;
402}
403
404
405int
406pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
407{
408        unsigned int i;
409        char *p_cf = NULL;
410        char *p_cf_sysclk = NULL;
411        char *p_cf_corepll = NULL;
412        char *p_cf_mpxpll = NULL;
413        char *p_altbank = NULL;
414        char *p_wd = NULL;
415        unsigned int unknown_param = 0;
416
417        /*
418         * No args is a simple reset request.
419         */
420        if (argc <= 1) {
421                pixis_reset();
422                /* not reached */
423        }
424
425        for (i = 1; i < argc; i++) {
426                if (strcmp(argv[i], "cf") == 0) {
427                        p_cf = argv[i];
428                        if (i + 3 >= argc) {
429                                break;
430                        }
431                        p_cf_sysclk = argv[i+1];
432                        p_cf_corepll = argv[i+2];
433                        p_cf_mpxpll = argv[i+3];
434                        i += 3;
435                        continue;
436                }
437
438                if (strcmp(argv[i], "altbank") == 0) {
439                        p_altbank = argv[i];
440                        continue;
441                }
442
443                if (strcmp(argv[i], "wd") == 0) {
444                        p_wd = argv[i];
445                        continue;
446                }
447
448                unknown_param = 1;
449        }
450
451        /*
452         * Check that cf has all required parms
453         */
454        if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
455            ||  unknown_param) {
456                puts(cmdtp->help);
457                return 1;
458        }
459
460        /*
461         * PIXIS seems to be sensitive to the ordering of
462         * the registers that are touched.
463         */
464        read_from_px_regs(0);
465
466        if (p_altbank) {
467                read_from_px_regs_altbank(0);
468        }
469        clear_altbank();
470
471        /*
472         * Clock configuration specified.
473         */
474        if (p_cf) {
475                unsigned long sysclk;
476                unsigned long corepll;
477                unsigned long mpxpll;
478
479                sysclk = simple_strtoul(p_cf_sysclk, NULL, 10);
480                corepll = strfractoint((uchar *) p_cf_corepll);
481                mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10);
482
483                if (!(set_px_sysclk(sysclk)
484                      && set_px_corepll(corepll)
485                      && set_px_mpxpll(mpxpll))) {
486                        puts(cmdtp->help);
487                        return 1;
488                }
489                read_from_px_regs(1);
490        }
491
492        /*
493         * Altbank specified
494         *
495         * NOTE CHANGE IN BEHAVIOR: previous code would default
496         * to enabling watchdog if altbank is specified.
497         * Now the watchdog must be enabled explicitly using 'wd'.
498         */
499        if (p_altbank) {
500                set_altbank();
501                read_from_px_regs_altbank(1);
502        }
503
504        /*
505         * Reset with watchdog specified.
506         */
507        if (p_wd) {
508                set_px_go_with_watchdog();
509        } else {
510                set_px_go();
511        }
512
513        /*
514         * Shouldn't be reached.
515         */
516        return 0;
517}
518
519
520U_BOOT_CMD(
521        pixis_reset, CFG_MAXARGS, 1, pixis_reset_cmd,
522        "pixis_reset - Reset the board using the FPGA sequencer\n",
523        "    pixis_reset\n"
524        "    pixis_reset [altbank]\n"
525        "    pixis_reset altbank wd\n"
526        "    pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
527        "    pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
528        );
Note: See TracBrowser for help on using the repository browser.