~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/a3m071/a3m071.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2003-2004
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 *
 
5
 * (C) Copyright 2004
 
6
 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
 
7
 *
 
8
 * (C) Copyright 2006
 
9
 * MicroSys GmbH
 
10
 *
 
11
 * Copyright 2012-2013 Stefan Roese <sr@denx.de>
 
12
 *
 
13
 * SPDX-License-Identifier:     GPL-2.0+
 
14
 */
 
15
 
 
16
#include <common.h>
 
17
#include <command.h>
 
18
#include <mpc5xxx.h>
 
19
#include <pci.h>
 
20
#include <miiphy.h>
 
21
#include <linux/compiler.h>
 
22
#include <asm/processor.h>
 
23
#include <asm/io.h>
 
24
 
 
25
#ifdef CONFIG_A4M2K
 
26
#include "is46r16320d.h"
 
27
#else
 
28
#include "mt46v16m16-75.h"
 
29
#endif
 
30
 
 
31
DECLARE_GLOBAL_DATA_PTR;
 
32
 
 
33
#if !defined(CONFIG_SYS_RAMBOOT) && \
 
34
        (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
 
35
static void sdram_start(int hi_addr)
 
36
{
 
37
        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
 
38
        long control = SDRAM_CONTROL | hi_addr_bit;
 
39
 
 
40
        /* unlock mode register */
 
41
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000000);
 
42
 
 
43
        /* precharge all banks */
 
44
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
 
45
 
 
46
#ifdef SDRAM_DDR
 
47
        /* set mode register: extended mode */
 
48
        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_EMODE);
 
49
 
 
50
        /* set mode register: reset DLL */
 
51
        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE | 0x04000000);
 
52
#endif
 
53
 
 
54
        /* precharge all banks */
 
55
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
 
56
 
 
57
        /* auto refresh */
 
58
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000004);
 
59
 
 
60
        /* set mode register */
 
61
        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE);
 
62
 
 
63
        /* normal operation */
 
64
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control);
 
65
 
 
66
        /*
 
67
         * Wait a short while for the DLL to lock before accessing
 
68
         * the SDRAM
 
69
         */
 
70
        udelay(100);
 
71
}
 
72
#endif
 
73
 
 
74
/*
 
75
 * ATTENTION: Although partially referenced initdram does NOT make real use
 
76
 * use of CONFIG_SYS_SDRAM_BASE. The code does not work if
 
77
 * CONFIG_SYS_SDRAM_BASE is something else than 0x00000000.
 
78
 */
 
79
phys_size_t initdram(int board_type)
 
80
{
 
81
        ulong dramsize = 0;
 
82
        ulong dramsize2 = 0;
 
83
        uint svr, pvr;
 
84
#if !defined(CONFIG_SYS_RAMBOOT) && \
 
85
        (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
 
86
        ulong test1, test2;
 
87
 
 
88
        /* setup SDRAM chip selects */
 
89
        out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0x0000001e);     /* 2GB at 0x0 */
 
90
        out_be32((void *)MPC5XXX_SDRAM_CS1CFG, 0x80000000);     /* disabled */
 
91
 
 
92
        /* setup config registers */
 
93
        out_be32((void *)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1);
 
94
        out_be32((void *)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2);
 
95
 
 
96
#ifdef SDRAM_DDR
 
97
        /* set tap delay */
 
98
        out_be32((void *)MPC5XXX_CDM_PORCFG, SDRAM_TAPDELAY);
 
99
#endif
 
100
 
 
101
        /* find RAM size using SDRAM CS0 only */
 
102
        sdram_start(0);
 
103
        test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 
104
        sdram_start(1);
 
105
        test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 
106
        if (test1 > test2) {
 
107
                sdram_start(0);
 
108
                dramsize = test1;
 
109
        } else {
 
110
                dramsize = test2;
 
111
        }
 
112
 
 
113
        /* memory smaller than 1MB is impossible */
 
114
        if (dramsize < (1 << 20))
 
115
                dramsize = 0;
 
116
 
 
117
        /* set SDRAM CS0 size according to the amount of RAM found */
 
118
        if (dramsize > 0) {
 
119
                out_be32((void *)MPC5XXX_SDRAM_CS0CFG,
 
120
                         0x13 + __builtin_ffs(dramsize >> 20) - 1);
 
121
        } else {
 
122
                out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0);      /* disabled */
 
123
        }
 
124
#else /* CONFIG_SYS_RAMBOOT */
 
125
 
 
126
        /* retrieve size of memory connected to SDRAM CS0 */
 
127
        dramsize = in_be32((void *)MPC5XXX_SDRAM_CS0CFG) & 0xFF;
 
128
        if (dramsize >= 0x13)
 
129
                dramsize = (1 << (dramsize - 0x13)) << 20;
 
130
        else
 
131
                dramsize = 0;
 
132
 
 
133
        /* retrieve size of memory connected to SDRAM CS1 */
 
134
        dramsize2 = in_be32((void *)MPC5XXX_SDRAM_CS1CFG) & 0xFF;
 
135
        if (dramsize2 >= 0x13)
 
136
                dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
 
137
        else
 
138
                dramsize2 = 0;
 
139
 
 
140
#endif /* CONFIG_SYS_RAMBOOT */
 
141
 
 
142
        /*
 
143
         * On MPC5200B we need to set the special configuration delay in the
 
144
         * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
 
145
         * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
 
146
         *
 
147
         * "The SDelay should be written to a value of 0x00000004. It is
 
148
         * required to account for changes caused by normal wafer processing
 
149
         * parameters."
 
150
         */
 
151
        svr = get_svr();
 
152
        pvr = get_pvr();
 
153
        if ((SVR_MJREV(svr) >= 2) && (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4))
 
154
                out_be32((void *)MPC5XXX_SDRAM_SDELAY, 0x04);
 
155
 
 
156
        return dramsize + dramsize2;
 
157
}
 
158
 
 
159
static void get_revisions(int *failsavelevel, int *digiboardversion,
 
160
        int *fpgaversion)
 
161
{
 
162
        struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
 
163
        u8 val;
 
164
 
 
165
        /* read digitalboard-version from TMR[2..4] */
 
166
        val = 0;
 
167
        val |= (gpt->gpt2.sr & (1 << (31 - 23))) ? (1) : 0;
 
168
        val |= (gpt->gpt3.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
 
169
        val |= (gpt->gpt4.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
 
170
        *digiboardversion = val;
 
171
 
 
172
        /*
 
173
         * A4M2K only supports digiboardversion. No failsavelevel and
 
174
         * fpgaversion here.
 
175
         */
 
176
#if !defined(CONFIG_A4M2K)
 
177
        /*
 
178
         * Figure out failsavelevel
 
179
         * see ticket dsvk#59
 
180
         */
 
181
        *failsavelevel = 0;     /* 0=failsave, 1=board ok, 2=fpga ok */
 
182
 
 
183
        if (*digiboardversion == 0) {
 
184
                *failsavelevel = 1;     /* digiboard-version ok */
 
185
 
 
186
                /* read fpga-version from TMR[5..7] */
 
187
                val = 0;
 
188
                val |= (gpt->gpt5.sr & (1 << (31 - 23))) ? (1) : 0;
 
189
                val |= (gpt->gpt6.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
 
190
                val |= (gpt->gpt7.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
 
191
                *fpgaversion = val;
 
192
 
 
193
                if (*fpgaversion == 1)
 
194
                        *failsavelevel = 2;     /* fpga-version ok */
 
195
        }
 
196
#endif
 
197
}
 
198
 
 
199
/*
 
200
 * This function is called from the SPL U-Boot version for
 
201
 * early init stuff, that needs to be done for OS (e.g. Linux)
 
202
 * booting. Doing it later in the real U-Boot would not work
 
203
 * in case that the SPL U-Boot boots Linux directly.
 
204
 */
 
205
void spl_board_init(void)
 
206
{
 
207
        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
 
208
        struct mpc5xxx_mmap_ctl *mm =
 
209
                (struct mpc5xxx_mmap_ctl *)CONFIG_SYS_MBAR;
 
210
 
 
211
#if defined(CONFIG_A4M2K)
 
212
        /* enable CS3 and CS5 (FPGA) */
 
213
        setbits_be32(&mm->ipbi_ws_ctrl, (1 << 19) | (1 << 21));
 
214
#else
 
215
        int digiboardversion;
 
216
        int failsavelevel;
 
217
        int fpgaversion;
 
218
        u32 val;
 
219
 
 
220
        get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
 
221
 
 
222
        val = in_be32(&mm->ipbi_ws_ctrl);
 
223
 
 
224
        /* first clear bits 19..21 (CS3...5) */
 
225
        val &= ~((1 << 19) | (1 << 20) | (1 << 21));
 
226
        if (failsavelevel == 2) {
 
227
                /* FPGA ok */
 
228
                val |= (1 << 19) | (1 << 21);
 
229
        }
 
230
 
 
231
        if (failsavelevel >= 1) {
 
232
                /* at least digiboard-version ok */
 
233
                val |= (1 << 20);
 
234
        }
 
235
 
 
236
        /* And write new value back to register */
 
237
        out_be32(&mm->ipbi_ws_ctrl, val);
 
238
 
 
239
 
 
240
        /* Setup pin multiplexing */
 
241
        if (failsavelevel == 2) {
 
242
                /* fpga-version ok */
 
243
#if defined(CONFIG_SYS_GPS_PORT_CONFIG_2)
 
244
                out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_2);
 
245
#endif
 
246
        } else if (failsavelevel == 1) {
 
247
                /* digiboard-version ok - fpga not */
 
248
#if defined(CONFIG_SYS_GPS_PORT_CONFIG_1)
 
249
                out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_1);
 
250
#endif
 
251
        } else {
 
252
                /* full failsave-mode */
 
253
#if defined(CONFIG_SYS_GPS_PORT_CONFIG)
 
254
                out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG);
 
255
#endif
 
256
        }
 
257
#endif
 
258
 
 
259
        /*
 
260
         * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see
 
261
         * ticket #60
 
262
         *
 
263
         * MPC5XXX_WU_GPIO_DIR direction is already 0 (INPUT)
 
264
         * set bit 0(msb) to 1
 
265
         */
 
266
        setbits_be32((void *)MPC5XXX_WU_GPIO_ENABLE, CONFIG_WDOG_GPIO_PIN);
 
267
 
 
268
#if defined(CONFIG_A4M2K)
 
269
        /* Setup USB[x] as MPCDiag[0..3] GPIO outputs */
 
270
 
 
271
        /* set USB0,6,7,8 (MPCDiag[0..3]) direction to output */
 
272
        gpio->simple_ddr |= 1 << (31 - 15);
 
273
        gpio->simple_ddr |= 1 << (31 - 14);
 
274
        gpio->simple_ddr |= 1 << (31 - 13);
 
275
        gpio->simple_ddr |= 1 << (31 - 12);
 
276
 
 
277
        /* enable USB0,6,7,8 (MPCDiag[0..3]) as GPIO */
 
278
        gpio->simple_gpioe |= 1 << (31 - 15);
 
279
        gpio->simple_gpioe |= 1 << (31 - 14);
 
280
        gpio->simple_gpioe |= 1 << (31 - 13);
 
281
        gpio->simple_gpioe |= 1 << (31 - 12);
 
282
 
 
283
        /* Setup PSC2[0..2] as STSLED[0..2] GPIO outputs */
 
284
 
 
285
        /* set PSC2[0..2] (STSLED[0..2]) direction to output */
 
286
        gpio->simple_ddr |= 1 << (31 - 27);
 
287
        gpio->simple_ddr |= 1 << (31 - 26);
 
288
        gpio->simple_ddr |= 1 << (31 - 25);
 
289
 
 
290
        /* enable PSC2[0..2] (STSLED[0..2]) as GPIO */
 
291
        gpio->simple_gpioe |= 1 << (31 - 27);
 
292
        gpio->simple_gpioe |= 1 << (31 - 26);
 
293
        gpio->simple_gpioe |= 1 << (31 - 25);
 
294
 
 
295
        /* Setup PSC6[2] as MRST2 self reset GPIO output */
 
296
 
 
297
        /* set PSC6[2]/IRDA_TX (MRST2) direction to output */
 
298
        gpio->simple_ddr |= 1 << (31 - 3);
 
299
 
 
300
        /* set PSC6[2]/IRDA_TX (MRST2) output as open drain */
 
301
        gpio->simple_ode |= 1 << (31 - 3);
 
302
 
 
303
        /* set PSC6[2]/IRDA_TX (MRST2) output as default high */
 
304
        gpio->simple_dvo |= 1 << (31 - 3);
 
305
 
 
306
        /* enable PSC6[2]/IRDA_TX (MRST2) as GPIO */
 
307
        gpio->simple_gpioe |= 1 << (31 - 3);
 
308
 
 
309
        /* Setup PSC6[3] as HARNSSCD harness code GPIO input */
 
310
 
 
311
        /* set PSC6[3]/IR_USB_CLK (HARNSSCD) direction to input */
 
312
        gpio->simple_ddr |= 0 << (31 - 2);
 
313
 
 
314
        /* enable PSC6[3]/IR_USB_CLK (HARNSSCD) as GPIO */
 
315
        gpio->simple_gpioe |= 1 << (31 - 2);
 
316
#else
 
317
        /* setup GPIOs for status-leds if needed - see ticket #57 */
 
318
        if (failsavelevel > 0) {
 
319
                /* digiboard-version is OK */
 
320
                /* LED is LOW ACTIVE - so deactivate by set output to 1 */
 
321
                gpio->simple_dvo |= 1 << (31 - 12);
 
322
                gpio->simple_dvo |= 1 << (31 - 13);
 
323
                /* set GPIO direction to output */
 
324
                gpio->simple_ddr |= 1 << (31 - 12);
 
325
                gpio->simple_ddr |= 1 << (31 - 13);
 
326
                /* open drain config is set to "normal output" at reset */
 
327
                /* gpio->simple_ode &=~ ( 1 << (31-12) ); */
 
328
                /* gpio->simple_ode &=~ ( 1 << (31-13) ); */
 
329
                /* enable as GPIO */
 
330
                gpio->simple_gpioe |= 1 << (31 - 12);
 
331
                gpio->simple_gpioe |= 1 << (31 - 13);
 
332
        }
 
333
 
 
334
        /* setup fpga irq - see ticket #65 */
 
335
        if (failsavelevel > 1) {
 
336
                /*
 
337
                 * The main irq initialisation is done in interrupts.c
 
338
                 * mpc5xxx_init_irq
 
339
                 */
 
340
                struct mpc5xxx_intr *intr =
 
341
                    (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
 
342
 
 
343
                setbits_be32(&intr->ctrl, 0x08C01801);
 
344
 
 
345
                /*
 
346
                 * The MBAR+0x0524 Bit 21:23 CSe are ignored here due to the
 
347
                 * already cleared (intr_ctrl) MBAR+0x0510 ECLR[0] bit above
 
348
                 */
 
349
        }
 
350
#endif
 
351
}
 
352
 
 
353
int checkboard(void)
 
354
{
 
355
        int digiboardversion;
 
356
        int failsavelevel;
 
357
        int fpgaversion;
 
358
 
 
359
        get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
 
360
 
 
361
#ifdef CONFIG_A4M2K
 
362
        puts("Board: A4M2K\n");
 
363
        printf("       digiboard IO version %u\n", digiboardversion);
 
364
#else
 
365
        puts("Board: A3M071\n");
 
366
        printf("Rev:   failsave level       %u\n", failsavelevel);
 
367
        printf("       digiboard IO version %u\n", digiboardversion);
 
368
        if (failsavelevel > 0)  /* only if fpga-version red */
 
369
                printf("       fpga IO version      %u\n", fpgaversion);
 
370
#endif
 
371
 
 
372
        return 0;
 
373
}
 
374
 
 
375
/* miscellaneous platform dependent initialisations */
 
376
int misc_init_r(void)
 
377
{
 
378
        /* adjust flash start and offset to detected values */
 
379
        gd->bd->bi_flashstart = flash_info[0].start[0];
 
380
        gd->bd->bi_flashoffset = 0;
 
381
 
 
382
        /* adjust mapping */
 
383
        out_be32((void *)MPC5XXX_BOOTCS_START,
 
384
                 START_REG(gd->bd->bi_flashstart));
 
385
        out_be32((void *)MPC5XXX_CS0_START, START_REG(gd->bd->bi_flashstart));
 
386
        out_be32((void *)MPC5XXX_BOOTCS_STOP,
 
387
                 STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
 
388
        out_be32((void *)MPC5XXX_CS0_STOP,
 
389
                 STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
 
390
 
 
391
        return 0;
 
392
}
 
393
 
 
394
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
 
395
void ft_board_setup(void *blob, bd_t * bd)
 
396
{
 
397
        ft_cpu_setup(blob, bd);
 
398
}
 
399
#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */
 
400
 
 
401
#ifdef CONFIG_SPL_OS_BOOT
 
402
/*
 
403
 * A3M071 specific implementation of spl_start_uboot()
 
404
 *
 
405
 * RETURN
 
406
 * 0 if booting into OS is selected (default)
 
407
 * 1 if booting into U-Boot is selected
 
408
 */
 
409
int spl_start_uboot(void)
 
410
{
 
411
        char s[8];
 
412
 
 
413
        env_init();
 
414
        getenv_f("boot_os", s, sizeof(s));
 
415
        if ((s != NULL) && (*s == '1' || *s == 'y' || *s == 'Y' ||
 
416
                            *s == 't' || *s == 'T'))
 
417
                return 0;
 
418
 
 
419
        return 1;
 
420
}
 
421
#endif
 
422
 
 
423
#if defined(CONFIG_HW_WATCHDOG)
 
424
static int watchdog_toggle;
 
425
 
 
426
void hw_watchdog_reset(void)
 
427
{
 
428
        int val;
 
429
 
 
430
        /*
 
431
         * Check if watchdog is enabled via user command
 
432
         */
 
433
        if ((gd->flags & GD_FLG_RELOC) && watchdog_toggle) {
 
434
                /* Set direction to output */
 
435
                setbits_be32((void *)MPC5XXX_WU_GPIO_DIR, CONFIG_WDOG_GPIO_PIN);
 
436
 
 
437
                /*
 
438
                 * Toggle watchdog output
 
439
                 */
 
440
                val = (in_be32((void *)MPC5XXX_WU_GPIO_DATA_O) &
 
441
                       CONFIG_WDOG_GPIO_PIN);
 
442
                if (val) {
 
443
                        clrbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
 
444
                                     CONFIG_WDOG_GPIO_PIN);
 
445
                } else {
 
446
                        setbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
 
447
                                     CONFIG_WDOG_GPIO_PIN);
 
448
                }
 
449
        }
 
450
}
 
451
 
 
452
int do_wdog_toggle(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
453
{
 
454
        if (argc != 2)
 
455
                goto usage;
 
456
 
 
457
        if (strncmp(argv[1], "on", 2) == 0)
 
458
                watchdog_toggle = 1;
 
459
        else if (strncmp(argv[1], "off", 3) == 0)
 
460
                watchdog_toggle = 0;
 
461
        else
 
462
                goto usage;
 
463
 
 
464
        return 0;
 
465
usage:
 
466
        printf("Usage: wdogtoggle %s\n", cmdtp->usage);
 
467
        return 1;
 
468
}
 
469
 
 
470
U_BOOT_CMD(
 
471
        wdogtoggle, CONFIG_SYS_MAXARGS, 2, do_wdog_toggle,
 
472
        "toggle GPIO pin to service watchdog",
 
473
        "[on/off] - Switch watchdog toggling via GPIO pin on/off"
 
474
);
 
475
#endif