1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2012
4  * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
5  */
6 
7 #include <common.h>
8 #include <i2c.h>
9 #include <linux/delay.h>
10 #include <linux/errno.h>
11 
12 /* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
13 #define KM_XLX_PROGRAM_B_PIN    39
14 
15 #define BOCO_ADDR	0x10
16 
17 #define ID_REG		0x00
18 #define BOCO2_ID	0x5b
19 
check_boco2(void)20 static int check_boco2(void)
21 {
22 	int ret;
23 	u8 id;
24 
25 	ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1);
26 	if (ret) {
27 		printf("%s: error reading the BOCO id !!\n", __func__);
28 		return ret;
29 	}
30 
31 	return (id == BOCO2_ID);
32 }
33 
boco_clear_bits(u8 reg,u8 flags)34 static int boco_clear_bits(u8 reg, u8 flags)
35 {
36 	int ret;
37 	u8 regval;
38 
39 	/* give access to the EEPROM from FPGA */
40 	ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
41 	if (ret) {
42 		printf("%s: error reading the BOCO @%#x !!\n",
43 		       __func__, reg);
44 		return ret;
45 	}
46 	regval &= ~flags;
47 	ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
48 	if (ret) {
49 		printf("%s: error writing the BOCO @%#x !!\n",
50 		       __func__, reg);
51 		return ret;
52 	}
53 
54 	return 0;
55 }
56 
boco_set_bits(u8 reg,u8 flags)57 static int boco_set_bits(u8 reg, u8 flags)
58 {
59 	int ret;
60 	u8 regval;
61 
62 	/* give access to the EEPROM from FPGA */
63 	ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
64 	if (ret) {
65 		printf("%s: error reading the BOCO @%#x !!\n",
66 		       __func__, reg);
67 		return ret;
68 	}
69 	regval |= flags;
70 	ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
71 	if (ret) {
72 		printf("%s: error writing the BOCO @%#x !!\n",
73 		       __func__, reg);
74 		return ret;
75 	}
76 
77 	return 0;
78 }
79 
80 #define SPI_REG		0x06
81 #define CFG_EEPROM	0x02
82 #define FPGA_PROG	0x04
83 #define FPGA_INIT_B	0x10
84 #define FPGA_DONE	0x20
85 
86 #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
fpga_done(void)87 static int fpga_done(void)
88 {
89 	int ret = 0;
90 	u8 regval;
91 
92 	/* this is only supported with the boco2 design */
93 	if (!check_boco2())
94 		return 0;
95 
96 	ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &regval, 1);
97 	if (ret) {
98 		printf("%s: error reading the BOCO @%#x !!\n",
99 			__func__, SPI_REG);
100 		return 0;
101 	}
102 
103 	return regval & FPGA_DONE ? 1 : 0;
104 }
105 #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
106 
107 static int skip;
108 
trigger_fpga_config(void)109 int trigger_fpga_config(void)
110 {
111 	int ret = 0;
112 
113 	skip = 0;
114 #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
115 	/* if the FPGA is already configured, we do not want to
116 	 * reconfigure it
117 	 */
118 	skip = 0;
119 	if (fpga_done()) {
120 		printf("PCIe FPGA config: skipped\n");
121 		skip = 1;
122 		return 0;
123 	}
124 #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
125 
126 	if (check_boco2()) {
127 		/* we have a BOCO2, this has to be triggered here */
128 
129 		/* make sure the FPGA_can access the EEPROM */
130 		ret = boco_clear_bits(SPI_REG, CFG_EEPROM);
131 		if (ret)
132 			return ret;
133 
134 		/* trigger the config start */
135 		ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B);
136 		if (ret)
137 			return ret;
138 
139 		/* small delay for the pulse */
140 		udelay(10);
141 
142 		/* up signal for pulse end */
143 		ret = boco_set_bits(SPI_REG, FPGA_PROG);
144 		if (ret)
145 			return ret;
146 
147 		/* finally, raise INIT_B to remove the config delay */
148 		ret = boco_set_bits(SPI_REG, FPGA_INIT_B);
149 		if (ret)
150 			return ret;
151 
152 	} else {
153 		/* we do it the old way, with the gpio pin */
154 		kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
155 		kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
156 		/* small delay for the pulse */
157 		udelay(10);
158 		kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
159 	}
160 
161 	return 0;
162 }
163 
wait_for_fpga_config(void)164 int wait_for_fpga_config(void)
165 {
166 	int ret = 0;
167 	u8 spictrl;
168 	u32 timeout = 20000;
169 
170 	if (skip)
171 		return 0;
172 
173 	if (!check_boco2()) {
174 		/* we do not have BOCO2, this is not really used */
175 		return 0;
176 	}
177 
178 	printf("PCIe FPGA config:");
179 	do {
180 		ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1);
181 		if (ret) {
182 			printf("%s: error reading the BOCO spictrl !!\n",
183 			       __func__);
184 			return ret;
185 		}
186 		if (timeout-- == 0) {
187 			printf(" FPGA_DONE timeout\n");
188 			return -EFAULT;
189 		}
190 		udelay(10);
191 	} while (!(spictrl & FPGA_DONE));
192 
193 	printf(" done\n");
194 
195 	return 0;
196 }
197 
198 #if defined(CONFIG_KM_FPGA_NO_RESET)
fpga_reset(void)199 int fpga_reset(void)
200 {
201 	/* no dedicated reset pin for FPGA */
202 	return 0;
203 }
204 #else
205 
206 #define PRST1		0x4
207 #define PCIE_RST	0x10
208 #define TRAFFIC_RST	0x04
209 
fpga_reset(void)210 int fpga_reset(void)
211 {
212 	int ret = 0;
213 	u8 resets;
214 
215 	if (!check_boco2()) {
216 		/* we do not have BOCO2, this is not really used */
217 		return 0;
218 	}
219 
220 	/* if we have skipped, we only want to reset the PCIe part */
221 	resets = skip ? PCIE_RST : PCIE_RST | TRAFFIC_RST;
222 
223 	ret = boco_clear_bits(PRST1, resets);
224 	if (ret)
225 		return ret;
226 
227 	/* small delay for the pulse */
228 	udelay(10);
229 
230 	ret = boco_set_bits(PRST1, resets);
231 	if (ret)
232 		return ret;
233 
234 	return 0;
235 }
236 #endif
237 
238 /* the FPGA was configured, we configure the BOCO2 so that the EEPROM
239  * is available from the Bobcat SPI bus
240  */
toggle_eeprom_spi_bus(void)241 int toggle_eeprom_spi_bus(void)
242 {
243 	int ret = 0;
244 
245 	if (!check_boco2()) {
246 		/* we do not have BOCO2, this is not really used */
247 		return 0;
248 	}
249 
250 	ret = boco_set_bits(SPI_REG, CFG_EEPROM);
251 	if (ret)
252 		return ret;
253 
254 	return 0;
255 }
256