drivers: fpga: simplify load mode selection of iCE40

Replace the enum for load modes for the iCE40 with a boolean flag,
as there are only two options:
- SPI: default, which should be used whenever possible
- GPIO bitbang: workarorund, in case a low-end microcontroller is used

Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
Benedikt Schmidt 2024-11-04 14:14:04 +01:00 committed by Anas Nashif
commit 5aa835c66b
3 changed files with 10 additions and 30 deletions

View file

@ -42,14 +42,7 @@
* achieve the minimum 1 MHz clock rate for loading the iCE40 bistream. So
* in order to bitbang on lower-end microcontrollers, we actually require
* direct register access to the set and clear registers.
*
* With that, this driver is left with 2 possible modes of operation which
* are:
* - FPGA_ICE40_LOAD_MODE_SPI (for higher-end microcontrollers)
* - FPGA_ICE40_LOAD_MODE_GPIO (for lower-end microcontrollers)
*/
#define FPGA_ICE40_LOAD_MODE_SPI 0
#define FPGA_ICE40_LOAD_MODE_GPIO 1
/*
* Values in Hz, intentionally to be comparable with the spi-max-frequency
@ -111,7 +104,7 @@ static void fpga_ice40_crc_to_str(uint32_t crc, char *s)
/*
* This is a calibrated delay loop used to achieve a 1 MHz SPI_CLK frequency
* with FPGA_ICE40_LOAD_MODE_GPIO. It is used both in fpga_ice40_send_clocks()
* with the bitbang mode. It is used both in fpga_ice40_send_clocks()
* and fpga_ice40_spi_send_data().
*
* Calibration is achieved via the mhz_delay_count device tree parameter. See
@ -573,12 +566,8 @@ static int fpga_ice40_init(const struct device *dev)
#define FPGA_ICE40_GPIO_PINS(inst, name) (volatile gpio_port_pins_t *)DT_INST_PROP_OR(inst, name, 0)
#define FPGA_ICE40_LOAD_MODE(inst) DT_INST_PROP(inst, load_mode)
#define FPGA_ICE40_LOAD_FUNC(inst) \
(FPGA_ICE40_LOAD_MODE(inst) == FPGA_ICE40_LOAD_MODE_SPI \
? fpga_ice40_load_spi \
: (FPGA_ICE40_LOAD_MODE(inst) == FPGA_ICE40_LOAD_MODE_GPIO ? fpga_ice40_load_gpio \
: NULL))
(DT_INST_PROP(inst, load_mode_bitbang) ? fpga_ice40_load_gpio : fpga_ice40_load_spi)
#ifdef CONFIG_PINCTRL
#define FPGA_ICE40_PINCTRL_CONFIG(inst) .pincfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(inst)),
@ -589,8 +578,6 @@ static int fpga_ice40_init(const struct device *dev)
#endif
#define FPGA_ICE40_DEFINE(inst) \
BUILD_ASSERT(FPGA_ICE40_LOAD_MODE(inst) == FPGA_ICE40_LOAD_MODE_SPI || \
FPGA_ICE40_LOAD_MODE(inst) == FPGA_ICE40_LOAD_MODE_GPIO); \
BUILD_ASSERT(FPGA_ICE40_BUS_FREQ(inst) >= FPGA_ICE40_SPI_HZ_MIN); \
BUILD_ASSERT(FPGA_ICE40_BUS_FREQ(inst) <= FPGA_ICE40_SPI_HZ_MAX); \
BUILD_ASSERT(FPGA_ICE40_CONFIG_DELAY_US(inst) >= FPGA_ICE40_CONFIG_DELAY_US_MIN); \

View file

@ -8,20 +8,14 @@ compatible: "lattice,ice40-fpga"
include: spi-device.yaml
properties:
load-mode:
type: int
required: true
load-mode-bitbang:
type: boolean
description: |
Configure the method used to load the bitstream.
The bitstream may be loaded via 2 separate methods:
0 := load the FPGA via SPI transfer
1 := load the FPGA via bit-banged GPIO
Option 0 may be suitable for some high-end microcontrollers.
Option 1 is suitable for low-end microcontrollers. This option
requires clk-gpios, pico-gpios, gpios-set-reg, and gpios-clear-reg
to be defined.
Example usage:
load-mode = <0>;
Select the bitbang mode for loading the bitstream into the FPGA.
This is a workaround to meet the timing requirements fo the iCE40
on low-end microcontrollers.
This option requires clk-gpios, pico-gpios, gpios-set-reg, and
gpios-clear-reg to be defined.
cdone-gpios:
type: phandle-array
required: true

View file

@ -13,7 +13,7 @@ test_spi_fpga_ice40_gpio: ice40@0 {
reg = <0>;
spi-max-frequency = <1000000>;
load-mode = <0>;
load-mode-bitbang;
cdone-gpios = <&test_gpio 0 0>;
creset-gpios = <&test_gpio 0 0>;
config-delay-us = <3900>;
@ -26,7 +26,6 @@ test_spi_fpga_ice40_spi: ice40@1 {
reg = <1>;
spi-max-frequency = <1000000>;
load-mode = <1>;
cdone-gpios = <&test_gpio 0 0>;
creset-gpios = <&test_gpio 0 0>;
clk-gpios = <&test_gpio 0 0>;