Browse Source

drivers: fpga controller: add eos_s3 fpga driver

This adds driver for EOS_S3 SoC FPGA.

Signed-off-by: Mateusz Sierszulski <msierszulski@internships.antmicro.com>
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
pull/38300/head
Mateusz Sierszulski 4 years ago committed by Christopher Friedt
parent
commit
a64ce1fc6b
  1. 1
      CODEOWNERS
  2. 4
      boards/arm/quick_feather/quick_feather.dts
  3. 2
      drivers/fpga/CMakeLists.txt
  4. 2
      drivers/fpga/Kconfig
  5. 9
      drivers/fpga/Kconfig.eos_s3
  6. 146
      drivers/fpga/fpga_eos_s3.c
  7. 73
      drivers/fpga/fpga_eos_s3.h
  8. 7
      samples/drivers/fpga/fpga_controller/CMakeLists.txt
  9. 21
      samples/drivers/fpga/fpga_controller/README.md
  10. 2
      samples/drivers/fpga/fpga_controller/prj.conf
  11. 2722
      samples/drivers/fpga/fpga_controller/src/greenled.h
  12. 41
      samples/drivers/fpga/fpga_controller/src/main.c
  13. 2722
      samples/drivers/fpga/fpga_controller/src/redled.h

1
CODEOWNERS

@ -232,6 +232,7 @@ @@ -232,6 +232,7 @@
/drivers/flash/ @nashif @nvlsianpu
/drivers/flash/*b91* @yurvyn
/drivers/flash/*nrf* @nvlsianpu
/drivers/fpga/ @tgorochowik @kgugala
/drivers/gpio/ @mnkp
/drivers/gpio/*b91* @yurvyn
/drivers/gpio/*lmp90xxx* @henrikbrixandersen

4
boards/arm/quick_feather/quick_feather.dts

@ -50,6 +50,10 @@ @@ -50,6 +50,10 @@
label = "User Push Button 0";
};
};
fpga {
status = "okay";
};
};
&cpu0 {

2
drivers/fpga/CMakeLists.txt

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources_ifdef(CONFIG_EOS_S3_FPGA fpga_eos_s3.c)

2
drivers/fpga/Kconfig

@ -14,4 +14,6 @@ module = fpga @@ -14,4 +14,6 @@ module = fpga
module-str = fpga
source "subsys/logging/Kconfig.template.log_config"
source "drivers/fpga/Kconfig.eos_s3"
endif # FPGA

9
drivers/fpga/Kconfig.eos_s3

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
# FPGA EOS S3 driver configuration options
# Copyright (c) 2021 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: Apache-2.0
config EOS_S3_FPGA
bool "EOS S3 fpga driver"
help
Enable EOS S3 FPGA driver.

146
drivers/fpga/fpga_eos_s3.c

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
/*
* Copyright (c) 2021 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <string.h>
#include <device.h>
#include <drivers/fpga.h>
#include "fpga_eos_s3.h"
void eos_s3_fpga_enable_clk(void)
{
CRU->C16_CLK_GATE = C16_CLK_GATE_PATH_0_ON;
CRU->C21_CLK_GATE = C21_CLK_GATE_PATH_0_ON;
CRU->C09_CLK_GATE = C09_CLK_GATE_PATH_1_ON | C09_CLK_GATE_PATH_2_ON;
CRU->C02_CLK_GATE = C02_CLK_GATE_PATH_1_ON;
}
void eos_s3_fpga_disable_clk(void)
{
CRU->C16_CLK_GATE = C16_CLK_GATE_PATH_0_OFF;
CRU->C21_CLK_GATE = C21_CLK_GATE_PATH_0_OFF;
CRU->C09_CLK_GATE = C09_CLK_GATE_PATH_1_OFF | C09_CLK_GATE_PATH_2_OFF;
CRU->C02_CLK_GATE = C02_CLK_GATE_PATH_1_OFF;
}
struct quickfeather_fpga_data {
char *FPGA_info;
};
static enum FPGA_status eos_s3_fpga_get_status(const struct device *dev)
{
ARG_UNUSED(dev);
if (PMU->FB_STATUS == FPGA_STATUS_ACTIVE) {
return FPGA_STATUS_ACTIVE;
} else
return FPGA_STATUS_INACTIVE;
}
static const char *eos_s3_fpga_get_info(const struct device *dev)
{
struct quickfeather_fpga_data *data = dev->data;
return data->FPGA_info;
}
static int eos_s3_fpga_on(const struct device *dev)
{
if (eos_s3_fpga_get_status(dev) == FPGA_STATUS_ACTIVE) {
return 0;
}
/* wake up the FPGA power domain */
PMU->FFE_FB_PF_SW_WU = PMU_FFE_FB_PF_SW_WU_FB_WU;
while (PMU->FFE_FB_PF_SW_WU == PMU_FFE_FB_PF_SW_WU_FB_WU) {
/* The register will clear itself if the FPGA starts */
};
eos_s3_fpga_enable_clk();
/* enable FPGA programming */
PMU->GEN_PURPOSE_0 = FB_CFG_ENABLE;
PIF->CFG_CTL = CFG_CTL_LOAD_ENABLE;
return 0;
}
static int eos_s3_fpga_off(const struct device *dev)
{
if (eos_s3_fpga_get_status(dev) == FPGA_STATUS_INACTIVE) {
return 0;
}
PMU->FB_PWR_MODE_CFG = PMU_FB_PWR_MODE_CFG_FB_SD;
PMU->FFE_FB_PF_SW_PD = PMU_FFE_FB_PF_SW_PD_FB_PD;
eos_s3_fpga_disable_clk();
return 0;
}
static int eos_s3_fpga_reset(const struct device *dev)
{
if (eos_s3_fpga_get_status(dev) == FPGA_STATUS_ACTIVE) {
eos_s3_fpga_off(dev);
}
eos_s3_fpga_on(dev);
if (eos_s3_fpga_get_status(dev) == FPGA_STATUS_INACTIVE) {
return -EAGAIN;
}
return 0;
}
static int eos_s3_fpga_load(const struct device *dev, uint32_t *image_ptr, uint32_t img_size)
{
if (eos_s3_fpga_get_status(dev) == FPGA_STATUS_INACTIVE) {
return -EINVAL;
}
volatile uint32_t *bitstream = (volatile uint32_t *)image_ptr;
for (uint32_t chunk_cnt = 0; chunk_cnt < (img_size / 4); chunk_cnt++) {
PIF->CFG_DATA = *bitstream;
bitstream++;
}
/* disable FPGA programming */
PMU->GEN_PURPOSE_0 = FB_CFG_DISABLE;
PIF->CFG_CTL = CFG_CTL_LOAD_DISABLE;
PMU->FB_ISOLATION = FB_ISOLATION_DISABLE;
return 0;
}
static int eos_s3_fpga_init(const struct device *dev)
{
IO_MUX->PAD_19_CTRL = PAD_ENABLE;
struct quickfeather_fpga_data *data = dev->data;
data->FPGA_info = FPGA_INFO;
eos_s3_fpga_reset(dev);
return 0;
}
static struct quickfeather_fpga_data fpga_data;
static const struct fpga_driver_api eos_s3_api = {
.reset = eos_s3_fpga_reset,
.load = eos_s3_fpga_load,
.get_status = eos_s3_fpga_get_status,
.on = eos_s3_fpga_on,
.off = eos_s3_fpga_off,
.get_info = eos_s3_fpga_get_info
};
DEVICE_DEFINE(fpga, "FPGA", &eos_s3_fpga_init, NULL, &fpga_data, NULL, APPLICATION,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &eos_s3_api);

73
drivers/fpga/fpga_eos_s3.h

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
/*
* Copyright (c) 2021 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_FPGA_EOS_S3_H_
#define ZEPHYR_DRIVERS_FPGA_EOS_S3_H_
#include <eoss3_dev.h>
struct PIF_struct {
/* Fabric Configuration Control Register, offset: 0x000 */
__IO uint32_t CFG_CTL;
/* Maximum Bit Length Count, offset: 0x004 */
__IO uint32_t MAX_BL_CNT;
/* Maximum Word Length Count, offset: 0x008 */
__IO uint32_t MAX_WL_CNT;
uint32_t reserved[1020];
/* Configuration Data, offset: 0xFFC */
__IO uint32_t CFG_DATA;
};
#define PIF ((struct PIF_struct *)PIF_CTRL_BASE)
#define FB_CFG_ENABLE ((uint32_t)(0x00000200))
#define FB_CFG_DISABLE ((uint32_t)(0x00000000))
#define CFG_CTL_APB_CFG_WR ((uint32_t)(0x00008000))
#define CFG_CTL_APB_CFG_RD ((uint32_t)(0x00004000))
#define CFG_CTL_APB_WL_DIN ((uint32_t)(0x00003C00))
#define CFG_CTL_APB_PARTIAL_LOAD ((uint32_t)(0x00000200))
#define CFG_CTL_APB_BL_SEL ((uint32_t)(0x00000100))
#define CFG_CTL_APB_BLM_SEL ((uint32_t)(0x00000080))
#define CFG_CTL_APB_BR_SEL ((uint32_t)(0x00000040))
#define CFG_CTL_APB_BRM_SEL ((uint32_t)(0x00000020))
#define CFG_CTL_APB_TL_SEL ((uint32_t)(0x00000010))
#define CFG_CTL_APB_TLM_SEL ((uint32_t)(0x00000008))
#define CFG_CTL_APB_TR_SEL ((uint32_t)(0x00000004))
#define CFG_CTL_APB_TRM_SEL ((uint32_t)(0x00000002))
#define CFG_CTL_APB_SEL_CFG ((uint32_t)(0x00000001))
#define FB_ISOLATION_ENABLE ((uint32_t)(0x00000001))
#define FB_ISOLATION_DISABLE ((uint32_t)(0x00000000))
#define PMU_FFE_FB_PF_SW_PD_FB_PD ((uint32_t)(0x00000002))
#define PMU_FB_PWR_MODE_CFG_FB_SD ((uint32_t)(0x00000002))
#define PMU_FB_PWR_MODE_CFG_FB_DP ((uint32_t)(0x00000001))
#define FPGA_INFO \
"eos_s3 eFPGA features:\n" \
"891 Logic Cells\n" \
"8 FIFO Controllers\n" \
"32 Configurable Interfaces\n" \
"2x32x32(or 4x16x16) Multiplier\n" \
"64Kbit SRAM\n"
#define PAD_ENABLE \
(PAD_E_4MA | PAD_P_PULLDOWN | PAD_OEN_NORMAL | PAD_SMT_DISABLE | PAD_REN_DISABLE | \
PAD_SR_SLOW | PAD_CTRL_SEL_AO_REG)
#define PAD_DISABLE \
(PAD_SMT_DISABLE | PAD_REN_DISABLE | PAD_SR_SLOW | PAD_E_4MA | PAD_P_PULLDOWN | \
PAD_OEN_NORMAL | PAD_CTRL_SEL_AO_REG)
#define CFG_CTL_LOAD_ENABLE \
(CFG_CTL_APB_CFG_WR | CFG_CTL_APB_WL_DIN | CFG_CTL_APB_BL_SEL | CFG_CTL_APB_BLM_SEL | \
CFG_CTL_APB_BR_SEL | CFG_CTL_APB_BRM_SEL | CFG_CTL_APB_TL_SEL | CFG_CTL_APB_TLM_SEL | \
CFG_CTL_APB_TR_SEL | CFG_CTL_APB_TRM_SEL | CFG_CTL_APB_SEL_CFG)
#define CFG_CTL_LOAD_DISABLE 0
#endif /* ZEPHYR_DRIVERS_FPGA_EOS_S3_H_ */

7
samples/drivers/fpga/fpga_controller/CMakeLists.txt

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(fpga_controller)
target_sources(app PRIVATE src/main.c)

21
samples/drivers/fpga/fpga_controller/README.md

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
# Zephyr FPGA controller
This module is an FPGA driver that can easily load a bitstream, reset it, check its status, enable or disable the FPGA.
This sample demonstrates how to use the FPGA driver API.
Currently the sample works with [Quicklogic Quickfeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board).
## Requirements
* Zephyr RTOS
* [Quicklogic Quickfeather board](https://github.com/QuickLogic-Corp/quick-feather-dev-board)
## Building
For the QuickLogic QuickFeather board:
```bash
west build -b quick_feather samples/drivers/fpga/fpga_controller
```
## Running
See [QuickFeather programming and debugging](https://docs.zephyrproject.org/latest/boards/arm/quick_feather/doc/index.html#programming-and-debugging) on how to load an image to the board.
## Sample output
Once the board is programmed, the LED should alternately flash red and green.

2
samples/drivers/fpga/fpga_controller/prj.conf

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
CONFIG_FPGA=y
CONFIG_EOS_S3_FPGA=y

2722
samples/drivers/fpga/fpga_controller/src/greenled.h

File diff suppressed because it is too large Load Diff

41
samples/drivers/fpga/fpga_controller/src/main.c

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <device.h>
#include <sys/printk.h>
#include <drivers/fpga.h>
#include "redled.h"
#include "greenled.h"
#include <eoss3_dev.h>
const struct device *fpga;
void main(void)
{
IO_MUX->PAD_21_CTRL = (PAD_E_4MA | PAD_P_PULLDOWN | PAD_OEN_NORMAL |
PAD_SMT_DISABLE | PAD_REN_DISABLE | PAD_SR_SLOW |
PAD_CTRL_SEL_AO_REG); /* Enable red led */
IO_MUX->PAD_22_CTRL = (PAD_E_4MA | PAD_P_PULLDOWN | PAD_OEN_NORMAL |
PAD_SMT_DISABLE | PAD_REN_DISABLE | PAD_SR_SLOW |
PAD_CTRL_SEL_AO_REG); /* Enable green led */
fpga = device_get_binding("FPGA");
if (!fpga) {
printk("unable to find fpga device\n");
}
while (1) {
fpga_load(fpga, axFPGABitStream_red,
sizeof(axFPGABitStream_red));
k_msleep(2000);
fpga_reset(fpga);
fpga_load(fpga, axFPGABitStream_green,
sizeof(axFPGABitStream_green));
k_msleep(2000);
fpga_reset(fpga);
}
}

2722
samples/drivers/fpga/fpga_controller/src/redled.h

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save