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>
This commit is contained in:
parent
2c718b2726
commit
a64ce1fc6b
13 changed files with 5752 additions and 0 deletions
|
@ -1,3 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_EOS_S3_FPGA fpga_eos_s3.c)
|
||||
|
|
|
@ -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
Normal file
9
drivers/fpga/Kconfig.eos_s3
Normal file
|
@ -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
Normal file
146
drivers/fpga/fpga_eos_s3.c
Normal file
|
@ -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
Normal file
73
drivers/fpga/fpga_eos_s3.h
Normal file
|
@ -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_ */
|
Loading…
Add table
Add a link
Reference in a new issue