]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/keymile/km_arm/fpga_config.c
3 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/errno.h>
12 /* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
13 #define KM_XLX_PROGRAM_B_PIN 39
15 #define BOCO_ADDR 0x10
20 static int check_boco2(void)
25 ret
= i2c_read(BOCO_ADDR
, ID_REG
, 1, &id
, 1);
27 printf("%s: error reading the BOCO id !!\n", __func__
);
31 return (id
== BOCO2_ID
);
34 static int boco_clear_bits(u8 reg
, u8 flags
)
39 /* give access to the EEPROM from FPGA */
40 ret
= i2c_read(BOCO_ADDR
, reg
, 1, ®val
, 1);
42 printf("%s: error reading the BOCO @%#x !!\n",
47 ret
= i2c_write(BOCO_ADDR
, reg
, 1, ®val
, 1);
49 printf("%s: error writing the BOCO @%#x !!\n",
57 static int boco_set_bits(u8 reg
, u8 flags
)
62 /* give access to the EEPROM from FPGA */
63 ret
= i2c_read(BOCO_ADDR
, reg
, 1, ®val
, 1);
65 printf("%s: error reading the BOCO @%#x !!\n",
70 ret
= i2c_write(BOCO_ADDR
, reg
, 1, ®val
, 1);
72 printf("%s: error writing the BOCO @%#x !!\n",
81 #define CFG_EEPROM 0x02
82 #define FPGA_PROG 0x04
83 #define FPGA_INIT_B 0x10
84 #define FPGA_DONE 0x20
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;
107 int trigger_fpga_config(void)
111 /* if the FPGA is already configured, we do not want to
115 printf("PCIe FPGA config: skipped\n");
121 /* we have a BOCO2, this has to be triggered here */
123 /* make sure the FPGA_can access the EEPROM */
124 ret
= boco_clear_bits(SPI_REG
, CFG_EEPROM
);
128 /* trigger the config start */
129 ret
= boco_clear_bits(SPI_REG
, FPGA_PROG
| FPGA_INIT_B
);
133 /* small delay for the pulse */
136 /* up signal for pulse end */
137 ret
= boco_set_bits(SPI_REG
, FPGA_PROG
);
141 /* finally, raise INIT_B to remove the config delay */
142 ret
= boco_set_bits(SPI_REG
, FPGA_INIT_B
);
147 /* we do it the old way, with the gpio pin */
148 kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN
, 1);
149 kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN
, 0);
150 /* small delay for the pulse */
152 kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN
);
158 int wait_for_fpga_config(void)
167 if (!check_boco2()) {
168 /* we do not have BOCO2, this is not really used */
172 printf("PCIe FPGA config:");
174 ret
= i2c_read(BOCO_ADDR
, SPI_REG
, 1, &spictrl
, 1);
176 printf("%s: error reading the BOCO spictrl !!\n",
180 if (timeout
-- == 0) {
181 printf(" FPGA_DONE timeout\n");
185 } while (!(spictrl
& FPGA_DONE
));
193 #define PCIE_RST 0x10
194 #define TRAFFIC_RST 0x04
201 if (!check_boco2()) {
202 /* we do not have BOCO2, this is not really used */
206 /* if we have skipped, we only want to reset the PCIe part */
207 resets
= skip
? PCIE_RST
: PCIE_RST
| TRAFFIC_RST
;
209 ret
= boco_clear_bits(PRST1
, resets
);
213 /* small delay for the pulse */
216 ret
= boco_set_bits(PRST1
, resets
);
223 /* the FPGA was configured, we configure the BOCO2 so that the EEPROM
224 * is available from the Bobcat SPI bus */
225 int toggle_eeprom_spi_bus(void)
229 if (!check_boco2()) {
230 /* we do not have BOCO2, this is not really used */
234 ret
= boco_set_bits(SPI_REG
, CFG_EEPROM
);