1 /* 2 * Copyright (c) 2022 Meta 3 * Copyright (c) 2024 SILA Embedded Solutions GmbH 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef ZEPHYR_SUBSYS_FPGA_FPGA_ICE40_COMMON_H_ 9 #define ZEPHYR_SUBSYS_FPGA_FPGA_ICE40_COMMON_H_ 10 11 #include <stdbool.h> 12 #include <stdint.h> 13 #include <zephyr/kernel.h> 14 #include <zephyr/drivers/fpga.h> 15 #include <zephyr/drivers/gpio.h> 16 #include <zephyr/drivers/spi.h> 17 18 /* 19 * Values in Hz, intentionally to be comparable with the spi-max-frequency 20 * property from DT bindings in spi-device.yaml. 21 */ 22 #define FPGA_ICE40_SPI_HZ_MIN 1000000 23 #define FPGA_ICE40_SPI_HZ_MAX 25000000 24 25 #define FPGA_ICE40_CRESET_DELAY_US_MIN 1 /* 200ns absolute minimum */ 26 #define FPGA_ICE40_CONFIG_DELAY_US_MIN 1200 27 #define FPGA_ICE40_LEADING_CLOCKS_MIN 8 28 #define FPGA_ICE40_TRAILING_CLOCKS_MIN 49 29 30 #define FPGA_ICE40_CONFIG_DEFINE(inst, derived_config_) \ 31 BUILD_ASSERT(DT_INST_PROP(inst, spi_max_frequency) >= FPGA_ICE40_SPI_HZ_MIN); \ 32 BUILD_ASSERT(DT_INST_PROP(inst, spi_max_frequency) <= FPGA_ICE40_SPI_HZ_MAX); \ 33 BUILD_ASSERT(DT_INST_PROP(inst, config_delay_us) >= FPGA_ICE40_CONFIG_DELAY_US_MIN); \ 34 BUILD_ASSERT(DT_INST_PROP(inst, config_delay_us) <= UINT16_MAX); \ 35 BUILD_ASSERT(DT_INST_PROP(inst, creset_delay_us) >= FPGA_ICE40_CRESET_DELAY_US_MIN); \ 36 BUILD_ASSERT(DT_INST_PROP(inst, creset_delay_us) <= UINT16_MAX); \ 37 BUILD_ASSERT(DT_INST_PROP(inst, leading_clocks) >= FPGA_ICE40_LEADING_CLOCKS_MIN); \ 38 BUILD_ASSERT(DT_INST_PROP(inst, leading_clocks) <= UINT8_MAX); \ 39 BUILD_ASSERT(DT_INST_PROP(inst, trailing_clocks) >= FPGA_ICE40_TRAILING_CLOCKS_MIN); \ 40 BUILD_ASSERT(DT_INST_PROP(inst, trailing_clocks) <= UINT8_MAX); \ 41 \ 42 static const struct fpga_ice40_config fpga_ice40_config_##inst = { \ 43 .bus = SPI_DT_SPEC_INST_GET(inst, \ 44 SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | \ 45 SPI_WORD_SET(8) | SPI_TRANSFER_MSB, \ 46 0), \ 47 .creset = GPIO_DT_SPEC_INST_GET(inst, creset_gpios), \ 48 .cdone = GPIO_DT_SPEC_INST_GET(inst, cdone_gpios), \ 49 .config_delay_us = DT_INST_PROP(inst, config_delay_us), \ 50 .creset_delay_us = DT_INST_PROP(inst, creset_delay_us), \ 51 .leading_clocks = DT_INST_PROP(inst, leading_clocks), \ 52 .trailing_clocks = DT_INST_PROP(inst, trailing_clocks), \ 53 .derived_config = derived_config_, \ 54 } 55 56 struct fpga_ice40_data { 57 uint32_t crc; 58 /* simply use crc32 as info */ 59 char info[2 * sizeof(uint32_t) + 1]; 60 bool on; 61 bool loaded; 62 struct k_spinlock lock; 63 }; 64 65 struct fpga_ice40_config { 66 struct spi_dt_spec bus; 67 struct gpio_dt_spec cdone; 68 struct gpio_dt_spec creset; 69 uint16_t creset_delay_us; 70 uint16_t config_delay_us; 71 uint8_t leading_clocks; 72 uint8_t trailing_clocks; 73 const void *derived_config; 74 }; 75 76 void fpga_ice40_crc_to_str(uint32_t crc, char *s); 77 enum FPGA_status fpga_ice40_get_status(const struct device *dev); 78 int fpga_ice40_on(const struct device *dev); 79 int fpga_ice40_off(const struct device *dev); 80 int fpga_ice40_reset(const struct device *dev); 81 const char *fpga_ice40_get_info(const struct device *dev); 82 int fpga_ice40_init(const struct device *dev); 83 84 #endif /* ZEPHYR_SUBSYS_FPGA_FPGA_ICE40_COMMON_H_ */ 85