blob: f0df2e39e6a9159c5a2641d66cd40ccc9dc2cd66 [file] [log] [blame]
Dirk Eibacha605ea72010-10-21 10:50:05 +02001/*
2 * (C) Copyright 2010
3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Dirk Eibacha605ea72010-10-21 10:50:05 +02006 */
7
8#include <common.h>
9#include <command.h>
10#include <asm/processor.h>
11#include <asm/io.h>
12#include <asm/ppc4xx-gpio.h>
Dirk Eibach2da0fc02011-01-21 09:31:21 +010013#include <asm/global_data.h>
Dirk Eibacha605ea72010-10-21 10:50:05 +020014
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000015#include "405ep.h"
Dirk Eibach2da0fc02011-01-21 09:31:21 +010016#include <gdsys_fpga.h>
Dirk Eibacha605ea72010-10-21 10:50:05 +020017
Dirk Eibacha605ea72010-10-21 10:50:05 +020018#define REFLECTION_TESTPATTERN 0xdede
19#define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff)
20
Dirk Eibach2da0fc02011-01-21 09:31:21 +010021DECLARE_GLOBAL_DATA_PTR;
22
23int get_fpga_state(unsigned dev)
24{
Simon Glass923a6622012-12-13 20:49:02 +000025 return gd->arch.fpga_state[dev];
Dirk Eibach2da0fc02011-01-21 09:31:21 +010026}
27
28void print_fpga_state(unsigned dev)
29{
Simon Glass923a6622012-12-13 20:49:02 +000030 if (gd->arch.fpga_state[dev] & FPGA_STATE_DONE_FAILED)
Dirk Eibach2da0fc02011-01-21 09:31:21 +010031 puts(" Waiting for FPGA-DONE timed out.\n");
Simon Glass923a6622012-12-13 20:49:02 +000032 if (gd->arch.fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED)
Dirk Eibach2da0fc02011-01-21 09:31:21 +010033 puts(" FPGA reflection test failed.\n");
34}
35
Dirk Eibacha605ea72010-10-21 10:50:05 +020036int board_early_init_f(void)
37{
Dirk Eibach2da0fc02011-01-21 09:31:21 +010038 unsigned k;
Dirk Eibach2da0fc02011-01-21 09:31:21 +010039
40 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
Simon Glass923a6622012-12-13 20:49:02 +000041 gd->arch.fpga_state[k] = 0;
Dirk Eibach2da0fc02011-01-21 09:31:21 +010042
Dirk Eibacha605ea72010-10-21 10:50:05 +020043 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
44 mtdcr(UIC0ER, 0x00000000); /* disable all ints */
45 mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical */
46 mtdcr(UIC0PR, 0xFFFFFF80); /* set int polarities */
47 mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
48 mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest prio */
49 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
50
51 /*
52 * EBC Configuration Register: set ready timeout to 512 ebc-clks
53 * -> ca. 15 us
54 */
55 mtebc(EBC0_CFG, 0xa8400000); /* ebc always driven */
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000056 return 0;
57}
58
59int board_early_init_r(void)
60{
61 unsigned k;
62 unsigned ctr;
63
64 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
Simon Glass923a6622012-12-13 20:49:02 +000065 gd->arch.fpga_state[k] = 0;
Dirk Eibacha605ea72010-10-21 10:50:05 +020066
67 /*
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000068 * reset FPGA
Dirk Eibacha605ea72010-10-21 10:50:05 +020069 */
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000070 gd405ep_init();
Dirk Eibacha605ea72010-10-21 10:50:05 +020071
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000072 gd405ep_set_fpga_reset(1);
Dirk Eibacha605ea72010-10-21 10:50:05 +020073
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000074 gd405ep_setup_hw();
75
Dirk Eibach2da0fc02011-01-21 09:31:21 +010076 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
77 ctr = 0;
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000078 while (!gd405ep_get_fpga_done(k)) {
Dirk Eibach2da0fc02011-01-21 09:31:21 +010079 udelay(100000);
80 if (ctr++ > 5) {
Simon Glass923a6622012-12-13 20:49:02 +000081 gd->arch.fpga_state[k] |=
82 FPGA_STATE_DONE_FAILED;
Dirk Eibach2da0fc02011-01-21 09:31:21 +010083 break;
84 }
85 }
86 }
Dirk Eibacha605ea72010-10-21 10:50:05 +020087
Dirk Eibacha605ea72010-10-21 10:50:05 +020088 udelay(10);
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000089
90 gd405ep_set_fpga_reset(0);
Dirk Eibacha605ea72010-10-21 10:50:05 +020091
Dirk Eibach2da0fc02011-01-21 09:31:21 +010092 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
Dirk Eibach0e60aa82012-04-27 10:33:46 +020093 struct ihs_fpga *fpga =
94 (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(k);
Dirk Eibach5cb41002011-04-06 13:53:46 +020095#ifdef CONFIG_SYS_FPGA_NO_RFL_HI
96 u16 *reflection_target = &fpga->reflection_low;
97#else
98 u16 *reflection_target = &fpga->reflection_high;
99#endif
Dirk Eibach2da0fc02011-01-21 09:31:21 +0100100 /*
101 * wait for fpga out of reset
102 */
103 ctr = 0;
104 while (1) {
105 out_le16(&fpga->reflection_low,
106 REFLECTION_TESTPATTERN);
Dirk Eibach5cb41002011-04-06 13:53:46 +0200107
108 if (in_le16(reflection_target) ==
Dirk Eibach2da0fc02011-01-21 09:31:21 +0100109 REFLECTION_TESTPATTERN_INV)
110 break;
Dirk Eibach5cb41002011-04-06 13:53:46 +0200111
Dirk Eibach2da0fc02011-01-21 09:31:21 +0100112 udelay(100000);
113 if (ctr++ > 5) {
Simon Glass923a6622012-12-13 20:49:02 +0000114 gd->arch.fpga_state[k] |=
Dirk Eibach2da0fc02011-01-21 09:31:21 +0100115 FPGA_STATE_REFLECTION_FAILED;
116 break;
117 }
118 }
Dirk Eibacha605ea72010-10-21 10:50:05 +0200119 }
120
121 return 0;
122}