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

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

Laguna: move prebuilt images and bootloader

svn directory cleanup

File size: 10.0 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];
47
48#define READ_TIMER1 (*(volatile ulong *)(CFG_TIMERBASE))
49#define READ_TIMER2 (*(volatile ulong *)(CFG_TIMERBASE + 0x10))
50
51static void timer_init(void);
52
53#if defined(CONFIG_SHOW_BOOT_PROGRESS)
54void show_boot_progress(int progress)
55{
56        printf("Boot reached stage %d\n", progress);
57}
58#endif
59
60#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
61
62static inline void delay (unsigned long loops)
63{
64        __asm__ volatile ("1:\n"
65                "subs %0, %1, #1\n"
66                "bne 1b":"=r" (loops):"0" (loops));
67}
68
69
70#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
71#define IO_READ(addr) (*(volatile unsigned int *)(addr))
72#define PCIE_CLK_GATE_REG 0x77000014
73#define MISC_PCIE0_REG 0x76000900
74#define MISC_PCIE1_REG 0x76000A00
75#define PCIE0_CTRL 0x7600095C
76#define PCIE1_CTRL 0x76000A5C
77#define PMU_SOFT_RST   0x77000004
78#define PCIE0_PHY_ERRATA 0x76000940
79#define PCIE1_PHY_ERRATA 0x76000A40
80#define GPIOA_DIR 0x74000008
81#define GPIOA_OUT 0x74000000
82#define GPIOB_DIR 0x74800008
83#define GPIOB_IN  0x74800004
84#define GPIOB_OUT 0x74800000
85
86static void pcie_init(void)
87{
88        unsigned char eeprom;
89        unsigned int temp;
90        unsigned char external_clkgen;
91        int gpio_perst = -1;
92
93        /* Errata C-01 */
94        IO_WRITE(PCIE0_PHY_ERRATA, 0xe2c);
95        IO_WRITE(PCIE1_PHY_ERRATA, 0xe2c);
96
97#ifdef GPIOA_PERST
98        gpio_perst = GPIOA_PERST;
99        if (strncmp(model, "GW2391", 6) == 0) {
100                gpio_perst = 8;
101        }
102#endif
103
104        /* boards with external PCI clockgen have GPIOB26 high at powerup */
105        external_clkgen = (IO_READ(GPIOB_IN) & (1 << 26)) ? 1 : 0;
106
107        printf("PCI:   PERST:GPIOA%d clock:%s\n", gpio_perst,
108               external_clkgen ? "external" : "internal");
109
110        /* enable and assert PERST# */
111        if (gpio_perst != -1) {
112                temp = IO_READ(GPIOA_DIR);
113                temp |= (1 << gpio_perst);  /* output */
114                IO_WRITE(GPIOA_DIR, temp);
115
116                temp = IO_READ(GPIOA_OUT);
117                temp &= ~(1 << gpio_perst); /* low */
118                IO_WRITE(GPIOA_OUT, temp);
119        }
120
121        i2c_read(0x51, 0x43, 1, &eeprom, 1);
122
123        /* pcie0 init */
124        if (eeprom & 0x2) {
125                if (external_clkgen) {
126                        /* select external clock */
127                        temp = IO_READ(MISC_PCIE0_REG);
128                        temp &= ~(1 << 11);
129                        IO_WRITE(MISC_PCIE0_REG, temp);
130                } else {
131                        /* enable PCIe Ref clock 0 */
132                        temp = IO_READ(PCIE_CLK_GATE_REG);
133                        temp |= (1 << 28);
134                        IO_WRITE(PCIE_CLK_GATE_REG, temp);
135                        /* select internal clock */
136                        temp = IO_READ(MISC_PCIE0_REG);
137                        temp |= (1 << 11);
138                        IO_WRITE(MISC_PCIE0_REG, temp);
139                }
140
141                /* soft reset PCIe0 */
142                temp = IO_READ(PMU_SOFT_RST);
143                temp &= ~(1 << 17);
144                IO_WRITE(PMU_SOFT_RST, temp);
145                temp |= (1 << 17);
146                IO_WRITE(PMU_SOFT_RST, temp);
147                /* exit L1 and enable LTSSM */
148                temp = IO_READ(PCIE0_CTRL);
149                temp |= 0x3;
150                IO_WRITE(PCIE0_CTRL, temp);
151        }
152
153        /* pcie1 init */
154        if (eeprom & 0x4) {
155                if (external_clkgen) {
156                        /* select external clock */
157                        temp = IO_READ(MISC_PCIE1_REG);
158                        temp &= ~(1 << 11);
159                        IO_WRITE(MISC_PCIE1_REG, temp);
160                } else {
161                        /* enable PCIe Ref clock 1 */
162                        temp = IO_READ(PCIE_CLK_GATE_REG);
163                        temp |= (1 << 29);
164                        IO_WRITE(PCIE_CLK_GATE_REG, temp);
165                        /* select internal clock */
166                        temp = IO_READ(MISC_PCIE1_REG);
167                        temp |= (1 << 11);
168                        IO_WRITE(MISC_PCIE1_REG, temp);
169                }
170
171                /* soft reset PCIe1 */
172                temp = IO_READ(PMU_SOFT_RST);
173                temp &= ~(1 << 18);
174                IO_WRITE(PMU_SOFT_RST, temp);
175                temp |= (1 << 18);
176                IO_WRITE(PMU_SOFT_RST, temp);
177                /* exit L1 and enable LTSSM */
178                temp = IO_READ(PCIE1_CTRL);
179                temp |= 0x3;
180                IO_WRITE(PCIE1_CTRL, temp);
181        }
182
183        /* de-assert PERST# after some delay for clock to become stable */
184        if (gpio_perst != -1) {
185                udelay(1000);
186                temp = IO_READ(GPIOA_OUT);
187                temp |= (1 << gpio_perst); /* high */
188                IO_WRITE(GPIOA_OUT, temp);
189        }
190}
191
192/*
193 * Miscellaneous platform dependent initialisations
194 */
195
196int board_init (void)
197{
198        gd->bd->bi_arch_number = 2635;
199
200        /* adress of boot parameters */
201        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x00000100;
202
203        gd->flags = 0;
204
205        icache_enable ();
206        timer_init();
207#ifdef CONFIG_AHCI_CNS3000
208        //dram_init();
209        scsi_init();
210#endif
211        return 0;
212}
213
214
215int misc_init_r (void)
216{
217        int i;
218        uint8_t eeprom_enetaddr[6];
219        uint8_t env_enetaddr[6];
220        uint32_t serial = 0;
221        uint8_t date[4];
222
223        char ethaddr[20];
224
225        char *tmp = getenv("ethaddr");
226        char *tmp1 = getenv("eth1addr");
227        char *tmp2 = getenv("eth2addr");
228        char *end;
229
230        i2c_read(0x51, 0x20, 1, date, 4);
231        i2c_read(0x51, 0x18, 1, eeprom_enetaddr, 4);
232        serial |= ((eeprom_enetaddr[0]) | (eeprom_enetaddr[1] << 8) |
233                  (eeprom_enetaddr[2] << 16) | (eeprom_enetaddr[3] << 24));
234
235
236        printf("Gateworks Corporation Copyright 2010\n");
237        printf("Model Number: %s\n", model);
238        printf("Manufacturer Date: %02x-%02x-%02x%02x\n", date[0], date[1],
239               date[2], date[3]);
240        printf("Serial #: %i\n", serial);       
241
242        i2c_read(0x51, 0x0, 1, eeprom_enetaddr, 6);
243
244        for (i = 0; i < 6; i++) {
245                env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
246                if (tmp)
247                        tmp = (*end) ? end+1 : end;
248        }
249
250        if (!tmp) {
251                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
252                        eeprom_enetaddr[0], eeprom_enetaddr[1],
253                        eeprom_enetaddr[2], eeprom_enetaddr[3],
254                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
255                printf("### Setting environment from ROM MAC address = \"%s\"\n",
256                        ethaddr);
257                setenv("ethaddr", ethaddr);
258        }
259
260        i2c_read(0x51, 0x6, 1, eeprom_enetaddr, 6);
261
262        for (i = 0; i < 6; i++) {
263                env_enetaddr[i] = tmp1 ? simple_strtoul(tmp1, &end, 16) : 0;
264                if (tmp1)
265                        tmp1 = (*end) ? end+1 : end;
266        }
267
268        if (!tmp1) {
269                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
270                        eeprom_enetaddr[0], eeprom_enetaddr[1],
271                        eeprom_enetaddr[2], eeprom_enetaddr[3],
272                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
273                printf("### Setting environment from ROM MAC address = \"%s\"\n",
274                        ethaddr);
275                setenv("eth1addr", ethaddr);
276        }
277
278        i2c_read(0x51, 0xc, 1, eeprom_enetaddr, 6);
279
280        for (i = 0; i < 6; i++) {
281                env_enetaddr[i] = tmp2 ? simple_strtoul(tmp2, &end, 16) : 0;
282                if (tmp2)
283                        tmp2 = (*end) ? end+1 : end;
284        }
285
286        if (!tmp2) {
287                sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
288                        eeprom_enetaddr[0], eeprom_enetaddr[1],
289                        eeprom_enetaddr[2], eeprom_enetaddr[3],
290                        eeprom_enetaddr[4], eeprom_enetaddr[5]) ;       
291                printf("### Setting environment from ROM MAC address = \"%s\"\n",
292                        ethaddr);
293                setenv("eth2addr", ethaddr);
294        }
295
296        return (0);
297}
298
299/*************************************************************
300 Routine:checkboard
301 Description: Check Board Identity
302*************************************************************/
303int checkboard(void)
304{
305        i2c_read(0x51, 0x30, 1, model, 16);
306
307        pcie_init();
308        return (0);
309}
310
311/******************************
312 Routine:
313 Description:
314******************************/
315int dram_init (void)
316{
317        unsigned char eeprom;
318        unsigned int temp = 0x01000000;
319        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
320
321        i2c_read(0x51, 0x2b, 1, &eeprom, 1);
322        gd->bd->bi_dram[0].size = temp << eeprom;
323
324        return 0;
325}
326
327/*
328 * Start the timer
329 * U-Boot expects a 32 bit timer, running at CFG_HZ == 1000
330 */
331#include "cns3000.h"
332
333#define PMU_REG_VALUE(addr) (*((volatile unsigned int *)(CNS3000_VEGA_PMU_BASE+addr)))
334#define CLK_GATE_REG PMU_REG_VALUE(0)
335#define SOFT_RST_REG PMU_REG_VALUE(4)
336#define HS_REG PMU_REG_VALUE(8)
337
338static void timer_init(void)
339{
340        // Setup timer to be a 1khz timer to make things easy
341        CLK_GATE_REG |= (1 << 14);
342        SOFT_RST_REG &= (~(1 << 14));
343        SOFT_RST_REG |= (1 << 14);
344        //HS_REG |= (1 << 14);
345        /*
346         * Now setup timer1
347         */     
348        *(volatile ulong *)(CFG_TIMERBASE + 0x00) = CFG_TIMER_RELOAD;
349        *(volatile ulong *)(CFG_TIMERBASE + 0x04) = CFG_TIMER_RELOAD;
350        *(volatile ulong *)(CFG_TIMERBASE + 0x30) |= 0x0203;    /* Enabled,
351                                                                 * down counter,
352                                                                 * no interrupt,
353                                                                 * 32-bit,
354                                                                 */
355
356        reset_timer_masked();
357}
358
359int interrupt_init (void){
360        return 0;
361}
362
363// udelay, exactly what it says, delay 1us
364void udelay (unsigned long usec)
365{
366
367        /*
368         *  This could possibly be a problem due to overflow
369         *  If usec is greater than 57266230 then we would have
370         *  an overflow and it wouldn't work right
371         */
372
373        *(volatile ulong *)(CFG_TIMERBASE + 0x30) &= ~0x8;      /* Disable */
374        *(volatile ulong *)(CFG_TIMERBASE + 0x10) = 75000000 / 1000000 * usec;
375        *(volatile ulong *)(CFG_TIMERBASE + 0x14) = 0;
376        *(volatile ulong *)(CFG_TIMERBASE + 0x30) |= 0x0408;    /* Enabled, */
377
378        while (READ_TIMER2 != 0);
379}
380
381// timestamp ticks at 1ms
382ulong get_timer (ulong base)
383{
384        return get_timer_masked () - base;
385}
386
387void reset_timer_masked (void)
388{
389        /* reset time */
390        lastdec = READ_TIMER1;
391        timestamp = 0;              /* start "advancing" time stamp from 0 */
392}
393
394/* ASSUMES 1kHz timer */
395ulong get_timer_masked(void)
396{
397        ulong now = READ_TIMER1;
398
399        if (lastdec >= now) {
400                /* normal mode */
401                timestamp += lastdec - now; /* move stamp forward with absolute diff ticks */
402        } else {                        /* we have overflow of the count down timer */
403                timestamp += lastdec + TIMER_LOAD_VAL - now;
404        }
405        lastdec = now;
406        return timestamp;
407}
408
409/*
410 *  u32 get_board_rev() for ARM supplied development boards
411 */
412ARM_SUPPLIED_GET_BOARD_REV
413
Note: See TracBrowser for help on using the repository browser.