]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - board/keymile/km_arm/fpga_config.c
1 // SPDX-License-Identifier: GPL-2.0+
4 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
9 #include <linux/errno.h>
11 /* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
12 #define KM_XLX_PROGRAM_B_PIN 39
14 #define BOCO_ADDR 0x10
19 static int check_boco2(void)
24 ret
= i2c_read(BOCO_ADDR
, ID_REG
, 1, &id
, 1);
26 printf("%s: error reading the BOCO id !!\n", __func__
);
30 return (id
== BOCO2_ID
);
33 static int boco_clear_bits(u8 reg
, u8 flags
)
38 /* give access to the EEPROM from FPGA */
39 ret
= i2c_read(BOCO_ADDR
, reg
, 1, ®val
, 1);
41 printf("%s: error reading the BOCO @%#x !!\n",
46 ret
= i2c_write(BOCO_ADDR
, reg
, 1, ®val
, 1);
48 printf("%s: error writing the BOCO @%#x !!\n",
56 static int boco_set_bits(u8 reg
, u8 flags
)
61 /* give access to the EEPROM from FPGA */
62 ret
= i2c_read(BOCO_ADDR
, reg
, 1, ®val
, 1);
64 printf("%s: error reading the BOCO @%#x !!\n",
69 ret
= i2c_write(BOCO_ADDR
, reg
, 1, ®val
, 1);
71 printf("%s: error writing the BOCO @%#x !!\n",
80 #define CFG_EEPROM 0x02
81 #define FPGA_PROG 0x04
82 #define FPGA_INIT_B 0x10
83 #define FPGA_DONE 0x20
85 static int fpga_done(void)
90 /* this is only supported with the boco2 design */
94 ret
= i2c_read(BOCO_ADDR
, SPI_REG
, 1, ®val
, 1);
96 printf("%s: error reading the BOCO @%#x !!\n",
101 return regval
& FPGA_DONE
? 1 : 0;
106 int trigger_fpga_config(void)
110 /* if the FPGA is already configured, we do not want to
114 printf("PCIe FPGA config: skipped\n");
120 /* we have a BOCO2, this has to be triggered here */
122 /* make sure the FPGA_can access the EEPROM */
123 ret
= boco_clear_bits(SPI_REG
, CFG_EEPROM
);
127 /* trigger the config start */
128 ret
= boco_clear_bits(SPI_REG
, FPGA_PROG
| FPGA_INIT_B
);
132 /* small delay for the pulse */
135 /* up signal for pulse end */
136 ret
= boco_set_bits(SPI_REG
, FPGA_PROG
);
140 /* finally, raise INIT_B to remove the config delay */
141 ret
= boco_set_bits(SPI_REG
, FPGA_INIT_B
);
146 /* we do it the old way, with the gpio pin */
147 kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN
, 1);
148 kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN
, 0);
149 /* small delay for the pulse */
151 kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN
);
157 int wait_for_fpga_config(void)
166 if (!check_boco2()) {
167 /* we do not have BOCO2, this is not really used */
171 printf("PCIe FPGA config:");
173 ret
= i2c_read(BOCO_ADDR
, SPI_REG
, 1, &spictrl
, 1);
175 printf("%s: error reading the BOCO spictrl !!\n",
179 if (timeout
-- == 0) {
180 printf(" FPGA_DONE timeout\n");
184 } while (!(spictrl
& FPGA_DONE
));
191 #if defined(KM_PCIE_RESET_MPP7)
193 #define KM_PEX_RST_GPIO_PIN 7
196 if (!check_boco2()) {
197 /* we do not have BOCO2, this is not really used */
201 printf("PCIe reset through GPIO7: ");
202 /* apply PCIe reset via GPIO */
203 kw_gpio_set_valid(KM_PEX_RST_GPIO_PIN
, 1);
204 kw_gpio_direction_output(KM_PEX_RST_GPIO_PIN
, 1);
205 kw_gpio_set_value(KM_PEX_RST_GPIO_PIN
, 0);
207 kw_gpio_set_value(KM_PEX_RST_GPIO_PIN
, 1);
217 #define PCIE_RST 0x10
218 #define TRAFFIC_RST 0x04
225 if (!check_boco2()) {
226 /* we do not have BOCO2, this is not really used */
230 /* if we have skipped, we only want to reset the PCIe part */
231 resets
= skip
? PCIE_RST
: PCIE_RST
| TRAFFIC_RST
;
233 ret
= boco_clear_bits(PRST1
, resets
);
237 /* small delay for the pulse */
240 ret
= boco_set_bits(PRST1
, resets
);
248 /* the FPGA was configured, we configure the BOCO2 so that the EEPROM
249 * is available from the Bobcat SPI bus */
250 int toggle_eeprom_spi_bus(void)
254 if (!check_boco2()) {
255 /* we do not have BOCO2, this is not really used */
259 ret
= boco_set_bits(SPI_REG
, CFG_EEPROM
);