1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014
4  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
5  */
6 
7 #include <common.h>
8 #include <command.h>
9 #include <init.h>
10 #include <asm/processor.h>
11 #include <asm/io.h>
12 #include <asm/global_data.h>
13 #include <linux/delay.h>
14 
15 #include "mpc8308.h"
16 #include <gdsys_fpga.h>
17 
18 #define REFLECTION_TESTPATTERN 0xdede
19 #define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff)
20 
21 #ifdef CONFIG_SYS_FPGA_NO_RFL_HI
22 #define REFLECTION_TESTREG reflection_low
23 #else
24 #define REFLECTION_TESTREG reflection_high
25 #endif
26 
27 DECLARE_GLOBAL_DATA_PTR;
28 
29 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
30 /* as gpio output status cannot be read back, we have to buffer it locally */
31 u32 gpio0_out;
32 
setbits_gpio0_out(u32 mask)33 void setbits_gpio0_out(u32 mask)
34 {
35 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
36 
37 	gpio0_out |= mask;
38 	out_be32(&immr->gpio[0].dat, gpio0_out);
39 }
40 
clrbits_gpio0_out(u32 mask)41 void clrbits_gpio0_out(u32 mask)
42 {
43 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
44 
45 	gpio0_out &= ~mask;
46 	out_be32(&immr->gpio[0].dat, gpio0_out);
47 }
48 
get_fpga_state(uint dev)49 int get_fpga_state(uint dev)
50 {
51 	return gd->arch.fpga_state[dev];
52 }
53 
board_early_init_f(void)54 int board_early_init_f(void)
55 {
56 	uint k;
57 
58 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
59 		gd->arch.fpga_state[k] = 0;
60 
61 	return 0;
62 }
63 
board_early_init_r(void)64 int board_early_init_r(void)
65 {
66 	uint k;
67 	uint ctr;
68 
69 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
70 		gd->arch.fpga_state[k] = 0;
71 
72 	/*
73 	 * reset FPGA
74 	 */
75 	mpc8308_init();
76 
77 	mpc8308_set_fpga_reset(1);
78 
79 	mpc8308_setup_hw();
80 
81 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
82 		ctr = 0;
83 		while (!mpc8308_get_fpga_done(k)) {
84 			mdelay(100);
85 			if (ctr++ > 5) {
86 				gd->arch.fpga_state[k] |=
87 					FPGA_STATE_DONE_FAILED;
88 				break;
89 			}
90 		}
91 	}
92 
93 	udelay(10);
94 
95 	mpc8308_set_fpga_reset(0);
96 
97 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
98 		/*
99 		 * wait for fpga out of reset
100 		 */
101 		ctr = 0;
102 		while (1) {
103 			u16 val;
104 
105 			FPGA_SET_REG(k, reflection_low, REFLECTION_TESTPATTERN);
106 
107 			FPGA_GET_REG(k, REFLECTION_TESTREG, &val);
108 			if (val == REFLECTION_TESTPATTERN_INV)
109 				break;
110 
111 			mdelay(100);
112 			if (ctr++ > 5) {
113 				gd->arch.fpga_state[k] |=
114 					FPGA_STATE_REFLECTION_FAILED;
115 				break;
116 			}
117 		}
118 	}
119 
120 	return 0;
121 }
122 #endif
123