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 #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
86 static int fpga_done(void)
91 /* this is only supported with the boco2 design */
95 ret = i2c_read(BOCO_ADDR, SPI_REG, 1, ®val, 1);
97 printf("%s: error reading the BOCO @%#x !!\n",
102 return regval & FPGA_DONE ? 1 : 0;
104 #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
108 int trigger_fpga_config(void)
113 #ifndef CONFIG_KM_FPGA_FORCE_CONFIG
114 /* if the FPGA is already configured, we do not want to
118 printf("PCIe FPGA config: skipped\n");
122 #endif /* CONFIG_KM_FPGA_FORCE_CONFIG */
125 /* we have a BOCO2, this has to be triggered here */
127 /* make sure the FPGA_can access the EEPROM */
128 ret = boco_clear_bits(SPI_REG, CFG_EEPROM);
132 /* trigger the config start */
133 ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B);
137 /* small delay for the pulse */
140 /* up signal for pulse end */
141 ret = boco_set_bits(SPI_REG, FPGA_PROG);
145 /* finally, raise INIT_B to remove the config delay */
146 ret = boco_set_bits(SPI_REG, FPGA_INIT_B);
151 /* we do it the old way, with the gpio pin */
152 kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
153 kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
154 /* small delay for the pulse */
156 kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
162 int wait_for_fpga_config(void)
171 if (!check_boco2()) {
172 /* we do not have BOCO2, this is not really used */
176 printf("PCIe FPGA config:");
178 ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1);
180 printf("%s: error reading the BOCO spictrl !!\n",
184 if (timeout-- == 0) {
185 printf(" FPGA_DONE timeout\n");
189 } while (!(spictrl & FPGA_DONE));
196 #if defined(CONFIG_KM_FPGA_NO_RESET)
199 /* no dedicated reset pin for FPGA */
205 #define PCIE_RST 0x10
206 #define TRAFFIC_RST 0x04
213 if (!check_boco2()) {
214 /* we do not have BOCO2, this is not really used */
218 /* if we have skipped, we only want to reset the PCIe part */
219 resets = skip ? PCIE_RST : PCIE_RST | TRAFFIC_RST;
221 ret = boco_clear_bits(PRST1, resets);
225 /* small delay for the pulse */
228 ret = boco_set_bits(PRST1, resets);
236 /* the FPGA was configured, we configure the BOCO2 so that the EEPROM
237 * is available from the Bobcat SPI bus */
238 int toggle_eeprom_spi_bus(void)
242 if (!check_boco2()) {
243 /* we do not have BOCO2, this is not really used */
247 ret = boco_set_bits(SPI_REG, CFG_EEPROM);