xref: /openbmc/u-boot/board/gdsys/mpc8308/mpc8308.c (revision 50dcf89d)
1*50dcf89dSDirk Eibach /*
2*50dcf89dSDirk Eibach  * (C) Copyright 2014
3*50dcf89dSDirk Eibach  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
4*50dcf89dSDirk Eibach  *
5*50dcf89dSDirk Eibach  * SPDX-License-Identifier:	GPL-2.0+
6*50dcf89dSDirk Eibach  */
7*50dcf89dSDirk Eibach 
8*50dcf89dSDirk Eibach #include <common.h>
9*50dcf89dSDirk Eibach #include <command.h>
10*50dcf89dSDirk Eibach #include <asm/processor.h>
11*50dcf89dSDirk Eibach #include <asm/io.h>
12*50dcf89dSDirk Eibach #include <asm/ppc4xx-gpio.h>
13*50dcf89dSDirk Eibach #include <asm/global_data.h>
14*50dcf89dSDirk Eibach 
15*50dcf89dSDirk Eibach #include "mpc8308.h"
16*50dcf89dSDirk Eibach #include <gdsys_fpga.h>
17*50dcf89dSDirk Eibach 
18*50dcf89dSDirk Eibach #define REFLECTION_TESTPATTERN 0xdede
19*50dcf89dSDirk Eibach #define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff)
20*50dcf89dSDirk Eibach 
21*50dcf89dSDirk Eibach #ifdef CONFIG_SYS_FPGA_NO_RFL_HI
22*50dcf89dSDirk Eibach #define REFLECTION_TESTREG reflection_low
23*50dcf89dSDirk Eibach #else
24*50dcf89dSDirk Eibach #define REFLECTION_TESTREG reflection_high
25*50dcf89dSDirk Eibach #endif
26*50dcf89dSDirk Eibach 
27*50dcf89dSDirk Eibach DECLARE_GLOBAL_DATA_PTR;
28*50dcf89dSDirk Eibach 
29*50dcf89dSDirk Eibach int get_fpga_state(unsigned dev)
30*50dcf89dSDirk Eibach {
31*50dcf89dSDirk Eibach 	return gd->arch.fpga_state[dev];
32*50dcf89dSDirk Eibach }
33*50dcf89dSDirk Eibach 
34*50dcf89dSDirk Eibach void print_fpga_state(unsigned dev)
35*50dcf89dSDirk Eibach {
36*50dcf89dSDirk Eibach 	if (gd->arch.fpga_state[dev] & FPGA_STATE_DONE_FAILED)
37*50dcf89dSDirk Eibach 		puts("       Waiting for FPGA-DONE timed out.\n");
38*50dcf89dSDirk Eibach 	if (gd->arch.fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED)
39*50dcf89dSDirk Eibach 		puts("       FPGA reflection test failed.\n");
40*50dcf89dSDirk Eibach }
41*50dcf89dSDirk Eibach 
42*50dcf89dSDirk Eibach int board_early_init_f(void)
43*50dcf89dSDirk Eibach {
44*50dcf89dSDirk Eibach 	unsigned k;
45*50dcf89dSDirk Eibach 
46*50dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
47*50dcf89dSDirk Eibach 		gd->arch.fpga_state[k] = 0;
48*50dcf89dSDirk Eibach 
49*50dcf89dSDirk Eibach 	return 0;
50*50dcf89dSDirk Eibach }
51*50dcf89dSDirk Eibach 
52*50dcf89dSDirk Eibach int board_early_init_r(void)
53*50dcf89dSDirk Eibach {
54*50dcf89dSDirk Eibach 	unsigned k;
55*50dcf89dSDirk Eibach 	unsigned ctr;
56*50dcf89dSDirk Eibach 
57*50dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
58*50dcf89dSDirk Eibach 		gd->arch.fpga_state[k] = 0;
59*50dcf89dSDirk Eibach 
60*50dcf89dSDirk Eibach 	/*
61*50dcf89dSDirk Eibach 	 * reset FPGA
62*50dcf89dSDirk Eibach 	 */
63*50dcf89dSDirk Eibach 	mpc8308_init();
64*50dcf89dSDirk Eibach 
65*50dcf89dSDirk Eibach 	mpc8308_set_fpga_reset(1);
66*50dcf89dSDirk Eibach 
67*50dcf89dSDirk Eibach 	mpc8308_setup_hw();
68*50dcf89dSDirk Eibach 
69*50dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
70*50dcf89dSDirk Eibach 		ctr = 0;
71*50dcf89dSDirk Eibach 		while (!mpc8308_get_fpga_done(k)) {
72*50dcf89dSDirk Eibach 			udelay(100000);
73*50dcf89dSDirk Eibach 			if (ctr++ > 5) {
74*50dcf89dSDirk Eibach 				gd->arch.fpga_state[k] |=
75*50dcf89dSDirk Eibach 					FPGA_STATE_DONE_FAILED;
76*50dcf89dSDirk Eibach 				break;
77*50dcf89dSDirk Eibach 			}
78*50dcf89dSDirk Eibach 		}
79*50dcf89dSDirk Eibach 	}
80*50dcf89dSDirk Eibach 
81*50dcf89dSDirk Eibach 	udelay(10);
82*50dcf89dSDirk Eibach 
83*50dcf89dSDirk Eibach 	mpc8308_set_fpga_reset(0);
84*50dcf89dSDirk Eibach 
85*50dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
86*50dcf89dSDirk Eibach 		/*
87*50dcf89dSDirk Eibach 		 * wait for fpga out of reset
88*50dcf89dSDirk Eibach 		 */
89*50dcf89dSDirk Eibach 		ctr = 0;
90*50dcf89dSDirk Eibach 		while (1) {
91*50dcf89dSDirk Eibach 			u16 val;
92*50dcf89dSDirk Eibach 
93*50dcf89dSDirk Eibach 			FPGA_SET_REG(k, reflection_low, REFLECTION_TESTPATTERN);
94*50dcf89dSDirk Eibach 
95*50dcf89dSDirk Eibach 			FPGA_GET_REG(k, REFLECTION_TESTREG, &val);
96*50dcf89dSDirk Eibach 			if (val == REFLECTION_TESTPATTERN_INV)
97*50dcf89dSDirk Eibach 				break;
98*50dcf89dSDirk Eibach 
99*50dcf89dSDirk Eibach 			udelay(100000);
100*50dcf89dSDirk Eibach 			if (ctr++ > 5) {
101*50dcf89dSDirk Eibach 				gd->arch.fpga_state[k] |=
102*50dcf89dSDirk Eibach 					FPGA_STATE_REFLECTION_FAILED;
103*50dcf89dSDirk Eibach 				break;
104*50dcf89dSDirk Eibach 			}
105*50dcf89dSDirk Eibach 		}
106*50dcf89dSDirk Eibach 	}
107*50dcf89dSDirk Eibach 
108*50dcf89dSDirk Eibach 	return 0;
109*50dcf89dSDirk Eibach }
110