source: SVN/laguna/u-boot-2008.10/board/cavium/cns3000/vega.c @ 59

Last change on this file since 59 was 59, checked in by Tim Harvey, 3 years ago

laguna: Change GPIO_PERST for GW2393

Like the GW2391, the GW2393 uses a different gpio for the PERST line. Update
accordingly.

Signed-off-by: Pushpal Sidhu <psidhu@…>

File size: 11.1 KB
Line 
1/*
2 * (C) Copyright 2002
3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4 * Marius Groeger <mgroeger@sysgo.de>
5 *
6 * (C) Copyright 2002
7 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
8 *
9 * (C) Copyright 2003
10 * Texas Instruments, <www.ti.com>
11 * Kshitij Gupta <Kshitij@ti.com>
12 *
13 * (C) Copyright 2004
14 * ARM Ltd.
15 * Philippe Robin, <philippe.robin@arm.com>
16 *
17 * See file CREDITS for list of people who contributed to this
18 * project.
19 *
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License as
22 * published by the Free Software Foundation; either version 2 of
23 * the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33 * MA 02111-1307 USA
34 */
35/*
36 * The RealView Emulation BaseBoard provides timers and soft reset
37 * - the cpu code does not need to provide these.
38 */
39#include <common.h>
40#include <i2c.h>
41
42DECLARE_GLOBAL_DATA_PTR;
43
44static ulong timestamp;
45static ulong lastdec;
46uint8_t model[16];
47uint8_t rev;
48int sp;
49
50#define READ_TIMER1 (*(volatile ulong *)(CFG_TIMERBASE))
51#define READ_TIMER2 (*(volatile ulong *)(CFG_TIMERBASE + 0x10))
52
53static void timer_init(void);
54
55#if defined(CONFIG_SHOW_BOOT_PROGRESS)
56void show_boot_progress(int progress)
57{
58        printf("Boot reached stage %d\n", progress);
59}
60#endif
61
62#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
63
64static inline void delay (unsigned long loops)
65{
66        __asm__ volatile ("1:\n"
67                "subs %0, %1, #1\n"
68                "bne 1b":"=r" (loops):"0" (loops));
69}
70
71
72#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
73#define IO_READ(addr) (*(volatile unsigned int *)(addr))
74#define PCIE_CLK_GATE_REG 0x77000014
75#define MISC_PCIE0_REG 0x76000900
76#define MISC_PCIE1_REG 0x76000A00
77#define PCIE0_CTRL 0x7600095C
78#define PCIE1_CTRL 0x76000A5C
79#define PMU_SOFT_RST   0x77000004
80#define PCIE0_PHY_ERRATA 0x76000940
81#define PCIE1_PHY_ERRATA 0x76000A40
82#define GPIOA_DIR 0x74000008
83#define GPIOA_OUT 0x74000000
84#define GPIOB_DIR 0x74800008
85#define GPIOB_IN  0x74800004
86#define GPIOB_OUT 0x74800000
87
88static void pcie_init(void)
89{
90        unsigned char eeprom;
91        unsigned int temp;
92        unsigned char external_clkgen;
93        int gpio_perst = -1;
94
95        /* Errata C-01 */
96        IO_WRITE(PCIE0_PHY_ERRATA, 0xe2c);
97        IO_WRITE(PCIE1_PHY_ERRATA, 0xe2c);
98
99#ifdef GPIOA_PERST
100        gpio_perst = GPIOA_PERST;
101        if (strncmp(model, "GW2391", 6) == 0 ||
102            strncmp(model, "GW2393", 6) == 0) {
103                gpio_perst = 8;
104        }
105#endif
106
107        /**
108         * All boards with external PCI clockgen have GPIOB26 high at powerup.
109         * However, exceptions exist with the GW2386 after a certain revision
110         * and special number, the GW2391, and GW2393.
111         */
112        if (strncmp(model, "GW2386", 6) == 0) {
113                if ((sp == 217) && (rev >= 'E'))
114                        external_clkgen = 1;
115                else if ((sp == 0) && (rev == 'D'))
116                        external_clkgen = 1;
117                else
118                        external_clkgen = 0;
119        }
120        else if (strncmp(model, "GW2391", 6) == 0) {
121                if (rev >= 'C')
122                        external_clkgen = 1;
123                else
124                        external_clkgen = 0;
125        }
126        else if (strncmp(model, "GW2393", 6) == 0)
127                external_clkgen = 1;
128        else
129                external_clkgen = (IO_READ(GPIOB_IN) & (1 << 26)) ? 1 : 0;
130
131        printf("PCI:   PERST:GPIOA%d clock:%s\n", gpio_perst,
132               external_clkgen ? "external" : "internal");
133
134        /* enable and assert PERST# */
135        if (gpio_perst != -1) {
136                temp = IO_READ(GPIOA_DIR);
137                temp |= (1 << gpio_perst);  /* output */
138                IO_WRITE(GPIOA_DIR, temp);
139
140                temp = IO_READ(GPIOA_OUT);
141                temp &= ~(1 << gpio_perst); /* low */
142                IO_WRITE(GPIOA_OUT, temp);
143        }
144
145        i2c_read(0x51, 0x43, 1, &eeprom, 1);
146
147        /* pcie0 init */
148        if (eeprom & 0x2) {
149                if (external_clkgen) {
150                        /* select external clock */
151                        temp = IO_READ(MISC_PCIE0_REG);
152                        temp &= ~(1 << 11);
153                        IO_WRITE(MISC_PCIE0_REG, temp);
154                } else {
155                        /* enable PCIe Ref clock 0 */
156                        temp = IO_READ(PCIE_CLK_GATE_REG);
157                        temp |= (1 << 28);
158                        IO_WRITE(PCIE_CLK_GATE_REG, temp);
159                        /* select internal clock */
160                        temp = IO_READ(MISC_PCIE0_REG);
161                        temp |= (1 << 11);
162                        IO_WRITE(MISC_PCIE0_REG, temp);
163                }
164
165                /* soft reset PCIe0 */
166                temp = IO_READ(PMU_SOFT_RST);
167                temp &= ~(1 << 17);
168                IO_WRITE(PMU_SOFT_RST, temp);
169                temp |= (1 << 17);
170                IO_WRITE(PMU_SOFT_RST, temp);
171                /* exit L1 and enable LTSSM */
172                temp = IO_READ(PCIE0_CTRL);
173                temp |= 0x3;
174                IO_WRITE(PCIE0_CTRL, temp);
175        }
176
177        /* pcie1 init */
178        if (eeprom & 0x4) {
179                if (external_clkgen) {
180                        /* select external clock */
181                        temp = IO_READ(MISC_PCIE1_REG);
182                        temp &= ~(1 << 11);
183                        IO_WRITE(MISC_PCIE1_REG, temp);
184                } else {
185                        /* enable PCIe Ref clock 1 */
186                        temp = IO_READ(PCIE_CLK_GATE_REG);
187                        temp |= (1 << 29);
188                        IO_WRITE(PCIE_CLK_GATE_REG, temp);
189                        /* select internal clock */
190                        temp = IO_READ(MISC_PCIE1_REG);
191                        temp |= (1 << 11);
192                        IO_WRITE(MISC_PCIE1_REG, temp);
193                }
194
195                /* soft reset PCIe1 */
196                temp = IO_READ(PMU_SOFT_RST);
197                temp &= ~(1 << 18);
198                IO_WRITE(PMU_SOFT_RST, temp);
199                temp |= (1 << 18);
200                IO_WRITE(PMU_SOFT_RST, temp);
201                /* exit L1 and enable LTSSM */
202                temp = IO_READ(PCIE1_CTRL);
203                temp |= 0x3;
204                IO_WRITE(PCIE1_CTRL, temp);
205        }
206
207        /* de-assert PERST# after some delay for clock to become stable */
208        if (gpio_perst != -1) {
209                udelay(1000);
210                temp = IO_READ(GPIOA_OUT);
211                temp |= (1 << gpio_perst); /* high */
212                IO_WRITE(GPIOA_OUT, temp);
213        }
214}
215
216/*
217 * Miscellaneous platform dependent initialisations
218 */
219
220int board_init (void)
221{
222        gd->bd->bi_arch_number = 2635;
223
224        /* adress of boot parameters */
225        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x00000100;
226
227        gd->flags = 0;
228
229        icache_enable ();
230        timer_init();
231#ifdef CONFIG_AHCI_CNS3000
232        //dram_init();
233        scsi_init();
234#endif
235        return 0;
236}
237
238
239int misc_init_r (void)
240{
241        int i;
242        uint8_t eeprom_enetaddr[6];
243        uint8_t env_enetaddr[6];
244        uint32_t serial = 0;
245        uint8_t date[4];
246
247        char ethaddr[20];
248
249        char *tmp = getenv("ethaddr");
250        char *tmp1 = getenv("eth1addr");
251        char *tmp2 = getenv("eth2addr");
252        char *end;
253
254        i2c_read(0x51, 0x20, 1, date, 4);
255        i2c_read(0x51, 0x18, 1, eeprom_enetaddr, 4);
256        serial |= ((eeprom_enetaddr[0]) | (eeprom_enetaddr[1] << 8) |
257                  (eeprom_enetaddr[2] << 16) | (eeprom_enetaddr[3] << 24));
258
259
260        printf("Gateworks Corporation Copyright 2010\n");
261        printf("Model Number: %s\n", model);
262        printf("Manufacturer Date: %02x-%02x-%02x%02x\n", date[0], date[1],
263               date[2], date[3]);
264        printf("Serial #: %i\n", serial);       
265
266        i2c_read(0x51, 0x0, 1, eeprom_enetaddr, 6);
267
268        for (i = 0; i < 6; i++) {
269                env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
270                if (tmp)
271                        tmp = (*end) ? end+1 : end;
272        }
273
274        if (!tmp) {
275                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
276                        eeprom_enetaddr[0], eeprom_enetaddr[1],
277                        eeprom_enetaddr[2], eeprom_enetaddr[3],
278                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
279                printf("### Setting environment from ROM MAC address = \"%s\"\n",
280                        ethaddr);
281                setenv("ethaddr", ethaddr);
282        }
283
284        i2c_read(0x51, 0x6, 1, eeprom_enetaddr, 6);
285
286        for (i = 0; i < 6; i++) {
287                env_enetaddr[i] = tmp1 ? simple_strtoul(tmp1, &end, 16) : 0;
288                if (tmp1)
289                        tmp1 = (*end) ? end+1 : end;
290        }
291
292        if (!tmp1) {
293                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
294                        eeprom_enetaddr[0], eeprom_enetaddr[1],
295                        eeprom_enetaddr[2], eeprom_enetaddr[3],
296                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
297                printf("### Setting environment from ROM MAC address = \"%s\"\n",
298                        ethaddr);
299                setenv("eth1addr", ethaddr);
300        }
301
302        i2c_read(0x51, 0xc, 1, eeprom_enetaddr, 6);
303
304        for (i = 0; i < 6; i++) {
305                env_enetaddr[i] = tmp2 ? simple_strtoul(tmp2, &end, 16) : 0;
306                if (tmp2)
307                        tmp2 = (*end) ? end+1 : end;
308        }
309
310        if (!tmp2) {
311                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
312                        eeprom_enetaddr[0], eeprom_enetaddr[1],
313                        eeprom_enetaddr[2], eeprom_enetaddr[3],
314                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
315                printf("### Setting environment from ROM MAC address = \"%s\"\n",
316                        ethaddr);
317                setenv("eth2addr", ethaddr);
318        }
319
320        return (0);
321}
322
323/*************************************************************
324 Routine:checkboard
325 Description: Check Board Identity
326*************************************************************/
327int checkboard(void)
328{
329        int i;
330
331        /* determine board model */
332        i2c_read(0x51, 0x30, 1, model, 16);
333
334        /* determine board revision */
335        rev = '\0';
336        for (i = sizeof(model) - 1; i >= 0; i--) {
337                if (model[i] >= 'A') {
338                        rev = model[i];
339                        break;
340                }
341        }
342
343        /* determine board sp number (assume 3 digit special number) */
344        sp = 0;
345        for (i = sizeof(model) - 4; i > 0; i--) {
346                if (model[i - 1] == 'S' && model[i] == 'P') {
347                        /* Convert SPXXX to numeric */
348                        sp = (sp * 10) + (model[i+1] - '0');
349                        sp = (sp * 10) + (model[i+2] - '0');
350                        sp = (sp * 10) + (model[i+3] - '0');
351                        break;
352                }
353        }
354
355        pcie_init();
356        return (0);
357}
358
359/******************************
360 Routine:
361 Description:
362******************************/
363int dram_init (void)
364{
365        unsigned char eeprom;
366        unsigned int temp = 0x01000000;
367        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
368
369        i2c_read(0x51, 0x2b, 1, &eeprom, 1);
370        gd->bd->bi_dram[0].size = temp << eeprom;
371
372        return 0;
373}
374
375/*
376 * Start the timer
377 * U-Boot expects a 32 bit timer, running at CFG_HZ == 1000
378 */
379#include "cns3000.h"
380
381#define PMU_REG_VALUE(addr) (*((volatile unsigned int *)(CNS3000_VEGA_PMU_BASE+addr)))
382#define CLK_GATE_REG PMU_REG_VALUE(0)
383#define SOFT_RST_REG PMU_REG_VALUE(4)
384#define HS_REG PMU_REG_VALUE(8)
385
386static void timer_init(void)
387{
388        // Setup timer to be a 1khz timer to make things easy
389        CLK_GATE_REG |= (1 << 14);
390        SOFT_RST_REG &= (~(1 << 14));
391        SOFT_RST_REG |= (1 << 14);
392        //HS_REG |= (1 << 14);
393        /*
394         * Now setup timer1
395         */     
396        *(volatile ulong *)(CFG_TIMERBASE + 0x00) = CFG_TIMER_RELOAD;
397        *(volatile ulong *)(CFG_TIMERBASE + 0x04) = CFG_TIMER_RELOAD;
398        *(volatile ulong *)(CFG_TIMERBASE + 0x30) |= 0x0203;    /* Enabled,
399                                                                 * down counter,
400                                                                 * no interrupt,
401                                                                 * 32-bit,
402                                                                 */
403
404        reset_timer_masked();
405}
406
407int interrupt_init (void){
408        return 0;
409}
410
411// udelay, exactly what it says, delay 1us
412void udelay (unsigned long usec)
413{
414
415        /*
416         *  This could possibly be a problem due to overflow
417         *  If usec is greater than 57266230 then we would have
418         *  an overflow and it wouldn't work right
419         */
420
421        *(volatile ulong *)(CFG_TIMERBASE + 0x30) &= ~0x8;      /* Disable */
422        *(volatile ulong *)(CFG_TIMERBASE + 0x10) = 75000000 / 1000000 * usec;
423        *(volatile ulong *)(CFG_TIMERBASE + 0x14) = 0;
424        *(volatile ulong *)(CFG_TIMERBASE + 0x30) |= 0x0408;    /* Enabled, */
425
426        while (READ_TIMER2 != 0);
427}
428
429// timestamp ticks at 1ms
430ulong get_timer (ulong base)
431{
432        return get_timer_masked () - base;
433}
434
435void reset_timer_masked (void)
436{
437        /* reset time */
438        lastdec = READ_TIMER1;
439        timestamp = 0;              /* start "advancing" time stamp from 0 */
440}
441
442/* ASSUMES 1kHz timer */
443ulong get_timer_masked(void)
444{
445        ulong now = READ_TIMER1;
446
447        if (lastdec >= now) {
448                /* normal mode */
449                timestamp += lastdec - now; /* move stamp forward with absolute diff ticks */
450        } else {                        /* we have overflow of the count down timer */
451                timestamp += lastdec + TIMER_LOAD_VAL - now;
452        }
453        lastdec = now;
454        return timestamp;
455}
456
457/*
458 *  u32 get_board_rev() for ARM supplied development boards
459 */
460ARM_SUPPLIED_GET_BOARD_REV
461
Note: See TracBrowser for help on using the repository browser.