diff options
30 files changed, 947 insertions, 302 deletions
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 41b779c5ca9..286bfef8ca2 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -9,7 +9,6 @@ obj-y += board.o obj-y += clock_manager.o -obj-y += fpga_manager.o obj-y += misc.o obj-y += reset_manager.o obj-y += timer.o @@ -21,6 +20,7 @@ obj-y += reset_manager_gen5.o obj-y += scan_manager.o obj-y += system_manager_gen5.o obj-y += wrap_pll_config.o +obj-y += fpga_manager.o endif ifdef CONFIG_TARGET_SOCFPGA_ARRIA10 diff --git a/arch/arm/mach-socfpga/include/mach/fpga_manager.h b/arch/arm/mach-socfpga/include/mach/fpga_manager.h index a077e2284e6..a21c71665c1 100644 --- a/arch/arm/mach-socfpga/include/mach/fpga_manager.h +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Altera Corporation <www.altera.com> + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -10,58 +10,11 @@ #include <altera.h> -struct socfpga_fpga_manager { - /* FPGA Manager Module */ - u32 stat; /* 0x00 */ - u32 ctrl; - u32 dclkcnt; - u32 dclkstat; - u32 gpo; /* 0x10 */ - u32 gpi; - u32 misci; /* 0x18 */ - u32 _pad_0x1c_0x82c[517]; - - /* Configuration Monitor (MON) Registers */ - u32 gpio_inten; /* 0x830 */ - u32 gpio_intmask; - u32 gpio_inttype_level; - u32 gpio_int_polarity; - u32 gpio_intstatus; /* 0x840 */ - u32 gpio_raw_intstatus; - u32 _pad_0x848; - u32 gpio_porta_eoi; - u32 gpio_ext_porta; /* 0x850 */ - u32 _pad_0x854_0x85c[3]; - u32 gpio_1s_sync; /* 0x860 */ - u32 _pad_0x864_0x868[2]; - u32 gpio_ver_id_code; - u32 gpio_config_reg2; /* 0x870 */ - u32 gpio_config_reg1; -}; - -#define FPGAMGRREGS_STAT_MODE_MASK 0x7 -#define FPGAMGRREGS_STAT_MSEL_MASK 0xf8 -#define FPGAMGRREGS_STAT_MSEL_LSB 3 - -#define FPGAMGRREGS_CTRL_CFGWDTH_MASK 0x200 -#define FPGAMGRREGS_CTRL_AXICFGEN_MASK 0x100 -#define FPGAMGRREGS_CTRL_NCONFIGPULL_MASK 0x4 -#define FPGAMGRREGS_CTRL_NCE_MASK 0x2 -#define FPGAMGRREGS_CTRL_EN_MASK 0x1 -#define FPGAMGRREGS_CTRL_CDRATIO_LSB 6 - -#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CRC_MASK 0x8 -#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK 0x4 -#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK 0x2 -#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK 0x1 - -/* FPGA Mode */ -#define FPGAMGRREGS_MODE_FPGAOFF 0x0 -#define FPGAMGRREGS_MODE_RESETPHASE 0x1 -#define FPGAMGRREGS_MODE_CFGPHASE 0x2 -#define FPGAMGRREGS_MODE_INITPHASE 0x3 -#define FPGAMGRREGS_MODE_USERMODE 0x4 -#define FPGAMGRREGS_MODE_UNKNOWN 0x5 +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) +#include <asm/arch/fpga_manager_gen5.h> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +#include <asm/arch/fpga_manager_arria10.h> +#endif /* FPGA CD Ratio Value */ #define CDRATIO_x1 0x0 @@ -69,9 +22,14 @@ struct socfpga_fpga_manager { #define CDRATIO_x4 0x2 #define CDRATIO_x8 0x3 -/* SoCFPGA support functions */ -int fpgamgr_test_fpga_ready(void); -int fpgamgr_poll_fpga_ready(void); +#ifndef __ASSEMBLY__ + +/* Common prototypes */ int fpgamgr_get_mode(void); +int fpgamgr_poll_fpga_ready(void); +void fpgamgr_program_write(const void *rbf_data, size_t rbf_size); +int fpgamgr_test_fpga_ready(void); +int fpgamgr_dclkcnt_set(unsigned long cnt); +#endif /* __ASSEMBLY__ */ #endif /* _FPGA_MANAGER_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h new file mode 100644 index 00000000000..9cbf696830c --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 Intel Corporation <www.intel.com> + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _FPGA_MANAGER_ARRIA10_H_ +#define _FPGA_MANAGER_ARRIA10_H_ + +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR_SET_MSK BIT(0) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE_SET_MSK BIT(1) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK BIT(2) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_INITDONE_OE_SET_MSK BIT(3) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK BIT(4) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_OE_SET_MSK BIT(5) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN_SET_MSK BIT(6) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_OE_SET_MSK BIT(7) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_CVP_CONF_DONE_SET_MSK BIT(8) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_PR_READY_SET_MSK BIT(9) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE_SET_MSK BIT(10) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR_SET_MSK BIT(11) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN_SET_MSK BIT(12) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_NCEO_OE_SET_MSK BIT(13) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL0_SET_MSK BIT(16) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL1_SET_MSK BIT(17) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL2_SET_MSK BIT(18) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SET_MSD (\ + ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL0_SET_MSK |\ + ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL1_SET_MSK |\ + ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL2_SET_MSK) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_IMGCFG_FIFOEMPTY_SET_MSK BIT(24) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_IMGCFG_FIFOFULL_SET_MSK BIT(25) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_JTAGM_SET_MSK BIT(28) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_EMR_SET_MSK BIT(29) +#define ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL0_LSB 16 + +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG_SET_MSK BIT(0) +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS_SET_MSK BIT(1) +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE_SET_MSK BIT(2) +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG_SET_MSK BIT(8) +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE_SET_MSK BIT(16) +#define ALT_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE_SET_MSK BIT(24) + +#define ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG_SET_MSK BIT(0) +#define ALT_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST_SET_MSK BIT(16) +#define ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NCE_SET_MSK BIT(24) + +#define ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL_SET_MSK BIT(0) +#define ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA_SET_MSK BIT(8) +#define ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SET_MSK 0x00030000 +#define ALT_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SET_MSK BIT(24) +#define ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_LSB 16 + +#ifndef __ASSEMBLY__ + +struct socfpga_fpga_manager { + u32 _pad_0x0_0x7[2]; + u32 dclkcnt; + u32 dclkstat; + u32 gpo; + u32 gpi; + u32 misci; + u32 _pad_0x1c_0x2f[5]; + u32 emr_data0; + u32 emr_data1; + u32 emr_data2; + u32 emr_data3; + u32 emr_data4; + u32 emr_data5; + u32 emr_valid; + u32 emr_en; + u32 jtag_config; + u32 jtag_status; + u32 jtag_kick; + u32 _pad_0x5c_0x5f; + u32 jtag_data_w; + u32 jtag_data_r; + u32 _pad_0x68_0x6f[2]; + u32 imgcfg_ctrl_00; + u32 imgcfg_ctrl_01; + u32 imgcfg_ctrl_02; + u32 _pad_0x7c_0x7f; + u32 imgcfg_stat; + u32 intr_masked_status; + u32 intr_mask; + u32 intr_polarity; + u32 dma_config; + u32 imgcfg_fifo_status; +}; + +/* Functions */ +int fpgamgr_program_init(u32 * rbf_data, size_t rbf_size); +int fpgamgr_program_finish(void); +int is_fpgamgr_user_mode(void); +int fpgamgr_wait_early_user_mode(void); + +#endif /* __ASSEMBLY__ */ + +#endif /* _FPGA_MANAGER_ARRIA10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/fpga_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/fpga_manager_gen5.h new file mode 100644 index 00000000000..2de7a117f95 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager_gen5.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FPGA_MANAGER_GEN5_H_ +#define _FPGA_MANAGER_GEN5_H_ + +#define FPGAMGRREGS_STAT_MODE_MASK 0x7 +#define FPGAMGRREGS_STAT_MSEL_MASK 0xf8 +#define FPGAMGRREGS_STAT_MSEL_LSB 3 + +#define FPGAMGRREGS_CTRL_CFGWDTH_MASK BIT(9) +#define FPGAMGRREGS_CTRL_AXICFGEN_MASK BIT(8) +#define FPGAMGRREGS_CTRL_NCONFIGPULL_MASK BIT(2) +#define FPGAMGRREGS_CTRL_NCE_MASK BIT(1) +#define FPGAMGRREGS_CTRL_EN_MASK BIT(0) +#define FPGAMGRREGS_CTRL_CDRATIO_LSB 6 + +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CRC_MASK BIT(3) +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK BIT(2) +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK BIT(1) +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK BIT(0) + +/* FPGA Mode */ +#define FPGAMGRREGS_MODE_FPGAOFF 0x0 +#define FPGAMGRREGS_MODE_RESETPHASE 0x1 +#define FPGAMGRREGS_MODE_CFGPHASE 0x2 +#define FPGAMGRREGS_MODE_INITPHASE 0x3 +#define FPGAMGRREGS_MODE_USERMODE 0x4 +#define FPGAMGRREGS_MODE_UNKNOWN 0x5 + +#ifndef __ASSEMBLY__ + +struct socfpga_fpga_manager { + /* FPGA Manager Module */ + u32 stat; /* 0x00 */ + u32 ctrl; + u32 dclkcnt; + u32 dclkstat; + u32 gpo; /* 0x10 */ + u32 gpi; + u32 misci; /* 0x18 */ + u32 _pad_0x1c_0x82c[517]; + + /* Configuration Monitor (MON) Registers */ + u32 gpio_inten; /* 0x830 */ + u32 gpio_intmask; + u32 gpio_inttype_level; + u32 gpio_int_polarity; + u32 gpio_intstatus; /* 0x840 */ + u32 gpio_raw_intstatus; + u32 _pad_0x848; + u32 gpio_porta_eoi; + u32 gpio_ext_porta; /* 0x850 */ + u32 _pad_0x854_0x85c[3]; + u32 gpio_1s_sync; /* 0x860 */ + u32 _pad_0x864_0x868[2]; + u32 gpio_ver_id_code; + u32 gpio_config_reg2; /* 0x870 */ + u32 gpio_config_reg1; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* _FPGA_MANAGER_GEN5_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h index 7922db815ce..b6d7f4f6f96 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h @@ -17,7 +17,7 @@ int socfpga_reset_deassert_bridges_handoff(void); void socfpga_reset_assert_fpga_connected_peripherals(void); void socfpga_reset_deassert_osc1wd0(void); void socfpga_reset_uart(int assert); -int socfpga_bridges_reset(int enable); +int socfpga_bridges_reset(void); struct socfpga_reset_manager { u32 stat; diff --git a/arch/arm/mach-socfpga/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c index d8c858c833b..66f1ec21f13 100644 --- a/arch/arm/mach-socfpga/reset_manager_arria10.c +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c @@ -318,13 +318,13 @@ void socfpga_per_reset_all(void) } #if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) -int socfpga_bridges_reset(int enable) +int socfpga_bridges_reset(void) { /* For SoCFPGA-VT, this is NOP. */ return 0; } #else -int socfpga_bridges_reset(int enable) +int socfpga_bridges_reset(void) { int ret; diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig index 888bb334bf6..add26efc837 100644 --- a/configs/astro_mcf5373l_defconfig +++ b/configs/astro_mcf5373l_defconfig @@ -12,4 +12,5 @@ CONFIG_CMD_FPGA_LOADMK=y CONFIG_CMD_CACHE=y CONFIG_CMD_DATE=y CONFIG_CMD_JFFS2=y +CONFIG_FPGA_ALTERA=y CONFIG_MTD_NOR_FLASH=y diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig index 3acdf445496..7db657a6333 100644 --- a/configs/socfpga_arria10_defconfig +++ b/configs/socfpga_arria10_defconfig @@ -7,6 +7,7 @@ CONFIG_DEFAULT_DEVICE_TREE="socfpga_arria10_socdk_sdmmc" CONFIG_ENV_IS_IN_MMC=y CONFIG_DEFAULT_FDT_FILE="socfpga_arria10_socdk_sdmmc.dtb" CONFIG_SPL=y +CONFIG_SPL_FPGA_SUPPORT=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_IMLS is not set CONFIG_CMD_ASKENV=y @@ -23,6 +24,7 @@ CONFIG_DOS_PARTITION=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_DM_MMC=y diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig index c105e63f59a..c0cbd72417e 100644 --- a/configs/socfpga_arria5_defconfig +++ b/configs/socfpga_arria5_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 108f195488e..45bed87b938 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_de0_nano_soc_defconfig b/configs/socfpga_de0_nano_soc_defconfig index dabdb97758f..f56e45e7275 100644 --- a/configs/socfpga_de0_nano_soc_defconfig +++ b/configs/socfpga_de0_nano_soc_defconfig @@ -40,6 +40,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_de10_nano_defconfig b/configs/socfpga_de10_nano_defconfig index 547eb3f4e99..2e7a6339fb8 100644 --- a/configs/socfpga_de10_nano_defconfig +++ b/configs/socfpga_de10_nano_defconfig @@ -38,6 +38,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_de1_soc_defconfig b/configs/socfpga_de1_soc_defconfig index b693ac1b98b..a121a07790d 100644 --- a/configs/socfpga_de1_soc_defconfig +++ b/configs/socfpga_de1_soc_defconfig @@ -39,6 +39,7 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_SPL_DM=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_is1_defconfig b/configs/socfpga_is1_defconfig index 371c6301e59..9b9b929e02d 100644 --- a/configs/socfpga_is1_defconfig +++ b/configs/socfpga_is1_defconfig @@ -35,6 +35,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_mcvevk_defconfig b/configs/socfpga_mcvevk_defconfig index 932c976f109..c7faa96f82d 100644 --- a/configs/socfpga_mcvevk_defconfig +++ b/configs/socfpga_mcvevk_defconfig @@ -39,6 +39,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_sockit_defconfig b/configs/socfpga_sockit_defconfig index 2918b6003be..493048e945b 100644 --- a/configs/socfpga_sockit_defconfig +++ b/configs/socfpga_sockit_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index 8bf61643be3..a26be88b8a5 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -42,6 +42,7 @@ CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_sr1500_defconfig b/configs/socfpga_sr1500_defconfig index a6ecfa3ff49..8ee049812f9 100644 --- a/configs/socfpga_sr1500_defconfig +++ b/configs/socfpga_sr1500_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_SYS_I2C_DW=y diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig index 8a49b8bf2f6..5f4c3025469 100644 --- a/configs/socfpga_vining_fpga_defconfig +++ b/configs/socfpga_vining_fpga_defconfig @@ -46,6 +46,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y +CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y CONFIG_LED_STATUS=y diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index ada88e76a24..4d079292b39 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -44,6 +44,7 @@ CONFIG_EFI_PARTITION=y # CONFIG_SPL_PARTITION_UUIDS is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_OF_TRANSLATE=y +CONFIG_FPGA_ALTERA=y CONFIG_DM_GPIO=y # CONFIG_MMC is not set CONFIG_SPI_FLASH=y diff --git a/configs/theadorable_defconfig b/configs/theadorable_defconfig index a9b5fabade5..d89d8601731 100644 --- a/configs/theadorable_defconfig +++ b/configs/theadorable_defconfig @@ -38,6 +38,7 @@ CONFIG_EFI_PARTITION=y # CONFIG_PARTITION_UUIDS is not set # CONFIG_SPL_PARTITION_UUIDS is not set CONFIG_SPL_OF_TRANSLATE=y +CONFIG_FPGA_ALTERA=y CONFIG_DM_GPIO=y # CONFIG_MMC is not set CONFIG_SPI_FLASH=y diff --git a/drivers/Makefile b/drivers/Makefile index 8624bd86f1c..e4a9cb41958 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA_SUPPORT) += ata/ scsi/ obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += block/ obj-$(CONFIG_SPL_MMC_SUPPORT) += block/ +obj-$(CONFIG_SPL_FPGA_SUPPORT) += fpga/ endif ifdef CONFIG_TPL_BUILD diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index a760944306b..6b2c866319c 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -13,6 +13,14 @@ config FPGA_ALTERA Enable Altera FPGA specific functions which includes bitstream (in BIT format), fpga and device validation. +config FPGA_SOCFPGA + bool "Enable Gen5 and Arria10 common FPGA drivers" + select FPGA_ALTERA + help + Say Y here to enable the Gen5 and Arria10 common FPGA driver + + This provides common functionality for Gen5 and Arria10 devices. + config FPGA_CYCLON2 bool "Enable Altera FPGA driver for Cyclone II" depends on FPGA_ALTERA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 777706f186d..08c9ff802fb 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -20,4 +20,6 @@ obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o +obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += socfpga_gen5.o +obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += socfpga_arria10.o endif diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c index f1b2f2c4da3..28fa16b9441 100644 --- a/drivers/fpga/socfpga.c +++ b/drivers/fpga/socfpga.c @@ -19,18 +19,8 @@ DECLARE_GLOBAL_DATA_PTR; static struct socfpga_fpga_manager *fpgamgr_regs = (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; -static struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; -/* Set CD ratio */ -static void fpgamgr_set_cd_ratio(unsigned long ratio) -{ - clrsetbits_le32(&fpgamgr_regs->ctrl, - 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB, - (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB); -} - -static int fpgamgr_dclkcnt_set(unsigned long cnt) +int fpgamgr_dclkcnt_set(unsigned long cnt) { unsigned long i; @@ -53,98 +43,8 @@ static int fpgamgr_dclkcnt_set(unsigned long cnt) return -ETIMEDOUT; } -/* Start the FPGA programming by initialize the FPGA Manager */ -static int fpgamgr_program_init(void) -{ - unsigned long msel, i; - - /* Get the MSEL value */ - msel = readl(&fpgamgr_regs->stat); - msel &= FPGAMGRREGS_STAT_MSEL_MASK; - msel >>= FPGAMGRREGS_STAT_MSEL_LSB; - - /* - * Set the cfg width - * If MSEL[3] = 1, cfg width = 32 bit - */ - if (msel & 0x8) { - setbits_le32(&fpgamgr_regs->ctrl, - FPGAMGRREGS_CTRL_CFGWDTH_MASK); - - /* To determine the CD ratio */ - /* MSEL[1:0] = 0, CD Ratio = 1 */ - if ((msel & 0x3) == 0x0) - fpgamgr_set_cd_ratio(CDRATIO_x1); - /* MSEL[1:0] = 1, CD Ratio = 4 */ - else if ((msel & 0x3) == 0x1) - fpgamgr_set_cd_ratio(CDRATIO_x4); - /* MSEL[1:0] = 2, CD Ratio = 8 */ - else if ((msel & 0x3) == 0x2) - fpgamgr_set_cd_ratio(CDRATIO_x8); - - } else { /* MSEL[3] = 0 */ - clrbits_le32(&fpgamgr_regs->ctrl, - FPGAMGRREGS_CTRL_CFGWDTH_MASK); - - /* To determine the CD ratio */ - /* MSEL[1:0] = 0, CD Ratio = 1 */ - if ((msel & 0x3) == 0x0) - fpgamgr_set_cd_ratio(CDRATIO_x1); - /* MSEL[1:0] = 1, CD Ratio = 2 */ - else if ((msel & 0x3) == 0x1) - fpgamgr_set_cd_ratio(CDRATIO_x2); - /* MSEL[1:0] = 2, CD Ratio = 4 */ - else if ((msel & 0x3) == 0x2) - fpgamgr_set_cd_ratio(CDRATIO_x4); - } - - /* To enable FPGA Manager configuration */ - clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK); - - /* To enable FPGA Manager drive over configuration line */ - setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); - - /* Put FPGA into reset phase */ - setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); - - /* (1) wait until FPGA enter reset phase */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE) - break; - } - - /* If not in reset state, return error */ - if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) { - puts("FPGA: Could not reset\n"); - return -1; - } - - /* Release FPGA from reset phase */ - clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); - - /* (2) wait until FPGA enter configuration phase */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE) - break; - } - - /* If not in configuration state, return error */ - if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) { - puts("FPGA: Could not configure\n"); - return -2; - } - - /* Clear all interrupts in CB Monitor */ - writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi); - - /* Enable AXI configuration */ - setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); - - return 0; -} - /* Write the RBF data to FPGA Manager */ -static void fpgamgr_program_write(const void *rbf_data, unsigned long rbf_size) +void fpgamgr_program_write(const void *rbf_data, size_t rbf_size) { uint32_t src = (uint32_t)rbf_data; uint32_t dst = SOCFPGA_FPGAMGRDATA_ADDRESS; @@ -171,134 +71,3 @@ static void fpgamgr_program_write(const void *rbf_data, unsigned long rbf_size) : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc"); } -/* Ensure the FPGA entering config done */ -static int fpgamgr_program_poll_cd(void) -{ - const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK | - FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK; - unsigned long reg, i; - - /* (3) wait until full config done */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - reg = readl(&fpgamgr_regs->gpio_ext_porta); - - /* Config error */ - if (!(reg & mask)) { - printf("FPGA: Configuration error.\n"); - return -3; - } - - /* Config done without error */ - if (reg & mask) - break; - } - - /* Timeout happened, return error */ - if (i == FPGA_TIMEOUT_CNT) { - printf("FPGA: Timeout waiting for program.\n"); - return -4; - } - - /* Disable AXI configuration */ - clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); - - return 0; -} - -/* Ensure the FPGA entering init phase */ -static int fpgamgr_program_poll_initphase(void) -{ - unsigned long i; - - /* Additional clocks for the CB to enter initialization phase */ - if (fpgamgr_dclkcnt_set(0x4)) - return -5; - - /* (4) wait until FPGA enter init phase or user mode */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE) - break; - if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) - break; - } - - /* If not in configuration state, return error */ - if (i == FPGA_TIMEOUT_CNT) - return -6; - - return 0; -} - -/* Ensure the FPGA entering user mode */ -static int fpgamgr_program_poll_usermode(void) -{ - unsigned long i; - - /* Additional clocks for the CB to exit initialization phase */ - if (fpgamgr_dclkcnt_set(0x5000)) - return -7; - - /* (5) wait until FPGA enter user mode */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) - break; - } - /* If not in configuration state, return error */ - if (i == FPGA_TIMEOUT_CNT) - return -8; - - /* To release FPGA Manager drive over configuration line */ - clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); - - return 0; -} - -/* - * FPGA Manager to program the FPGA. This is the interface used by FPGA driver. - * Return 0 for sucess, non-zero for error. - */ -int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) -{ - unsigned long status; - - if ((uint32_t)rbf_data & 0x3) { - puts("FPGA: Unaligned data, realign to 32bit boundary.\n"); - return -EINVAL; - } - - /* Prior programming the FPGA, all bridges need to be shut off */ - - /* Disable all signals from hps peripheral controller to fpga */ - writel(0, &sysmgr_regs->fpgaintfgrp_module); - - /* Disable all signals from FPGA to HPS SDRAM */ -#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080 - writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS); - - /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ - socfpga_bridges_reset(1); - - /* Unmap the bridges from NIC-301 */ - writel(0x1, SOCFPGA_L3REGS_ADDRESS); - - /* Initialize the FPGA Manager */ - status = fpgamgr_program_init(); - if (status) - return status; - - /* Write the RBF data to FPGA Manager */ - fpgamgr_program_write(rbf_data, rbf_size); - - /* Ensure the FPGA entering config done */ - status = fpgamgr_program_poll_cd(); - if (status) - return status; - - /* Ensure the FPGA entering init phase */ - status = fpgamgr_program_poll_initphase(); - if (status) - return status; - - /* Ensure the FPGA entering user mode */ - return fpgamgr_program_poll_usermode(); -} diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c new file mode 100644 index 00000000000..5c1a68a0099 --- /dev/null +++ b/drivers/fpga/socfpga_arria10.c @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2017 Intel Corporation <www.intel.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm/io.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/sdram.h> +#include <asm/arch/misc.h> +#include <altera.h> +#include <common.h> +#include <errno.h> +#include <wait_bit.h> +#include <watchdog.h> + +#define CFGWDTH_32 1 +#define MIN_BITSTREAM_SIZECHECK 230 +#define ENCRYPTION_OFFSET 69 +#define COMPRESSION_OFFSET 229 +#define FPGA_TIMEOUT_MSEC 1000 /* timeout in ms */ +#define FPGA_TIMEOUT_CNT 0x1000000 + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_fpga_manager *fpga_manager_base = + (void *)SOCFPGA_FPGAMGRREGS_ADDRESS; + +static const struct socfpga_system_manager *system_manager_base = + (void *)SOCFPGA_SYSMGR_ADDRESS; + +static void fpgamgr_set_cd_ratio(unsigned long ratio); + +static uint32_t fpgamgr_get_msel(void) +{ + u32 reg; + + reg = readl(&fpga_manager_base->imgcfg_stat); + reg = (reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SET_MSD) >> + ALT_FPGAMGR_IMGCFG_STAT_F2S_MSEL0_LSB; + + return reg; +} + +static void fpgamgr_set_cfgwdth(int width) +{ + if (width) + setbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SET_MSK); + else + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SET_MSK); +} + +int is_fpgamgr_user_mode(void) +{ + return (readl(&fpga_manager_base->imgcfg_stat) & + ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK) != 0; +} + +static int wait_for_user_mode(void) +{ + return wait_for_bit(__func__, + &fpga_manager_base->imgcfg_stat, + ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK, + 1, FPGA_TIMEOUT_MSEC, false); +} + +static int is_fpgamgr_early_user_mode(void) +{ + return (readl(&fpga_manager_base->imgcfg_stat) & + ALT_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE_SET_MSK) != 0; +} + +int fpgamgr_wait_early_user_mode(void) +{ + u32 sync_data = 0xffffffff; + u32 i = 0; + unsigned start = get_timer(0); + unsigned long cd_ratio; + + /* Getting existing CDRATIO */ + cd_ratio = (readl(&fpga_manager_base->imgcfg_ctrl_02) & + ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SET_MSK) >> + ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_LSB; + + /* Using CDRATIO_X1 for better compatibility */ + fpgamgr_set_cd_ratio(CDRATIO_x1); + + while (!is_fpgamgr_early_user_mode()) { + if (get_timer(start) > FPGA_TIMEOUT_MSEC) + return -ETIMEDOUT; + fpgamgr_program_write((const long unsigned int *)&sync_data, + sizeof(sync_data)); + udelay(FPGA_TIMEOUT_MSEC); + i++; + } + + debug("Additional %i sync word needed\n", i); + + /* restoring original CDRATIO */ + fpgamgr_set_cd_ratio(cd_ratio); + + return 0; +} + +/* Read f2s_nconfig_pin and f2s_nstatus_pin; loop until de-asserted */ +static int wait_for_nconfig_pin_and_nstatus_pin(void) +{ + unsigned long mask = ALT_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN_SET_MSK | + ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK; + + /* Poll until f2s_nconfig_pin and f2s_nstatus_pin; loop until de-asserted, + * timeout at 1000ms + */ + return wait_for_bit(__func__, + &fpga_manager_base->imgcfg_stat, + mask, + false, FPGA_TIMEOUT_MSEC, false); +} + +static int wait_for_f2s_nstatus_pin(unsigned long value) +{ + /* Poll until f2s to specific value, timeout at 1000ms */ + return wait_for_bit(__func__, + &fpga_manager_base->imgcfg_stat, + ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK, + value, FPGA_TIMEOUT_MSEC, false); +} + +/* set CD ratio */ +static void fpgamgr_set_cd_ratio(unsigned long ratio) +{ + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SET_MSK); + + setbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + (ratio << ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_LSB) & + ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SET_MSK); +} + +/* get the MSEL value, verify we are set for FPP configuration mode */ +static int fpgamgr_verify_msel(void) +{ + u32 msel = fpgamgr_get_msel(); + + if (msel & ~BIT(0)) { + printf("Fail: read msel=%d\n", msel); + return -EPERM; + } + + return 0; +} + +/* + * Write cdratio and cdwidth based on whether the bitstream is compressed + * and/or encoded + */ +static int fpgamgr_set_cdratio_cdwidth(unsigned int cfg_width, u32 *rbf_data, + size_t rbf_size) +{ + unsigned int cd_ratio; + bool encrypt, compress; + + /* + * According to the bitstream specification, + * both encryption and compression status are + * in location before offset 230 of the buffer. + */ + if (rbf_size < MIN_BITSTREAM_SIZECHECK) + return -EINVAL; + + encrypt = (rbf_data[ENCRYPTION_OFFSET] >> 2) & 3; + encrypt = encrypt != 0; + + compress = (rbf_data[COMPRESSION_OFFSET] >> 1) & 1; + compress = !compress; + + debug("header word %d = %08x\n", 69, rbf_data[69]); + debug("header word %d = %08x\n", 229, rbf_data[229]); + debug("read from rbf header: encrypt=%d compress=%d\n", encrypt, compress); + + /* + * from the register map description of cdratio in imgcfg_ctrl_02: + * Normal Configuration : 32bit Passive Parallel + * Partial Reconfiguration : 16bit Passive Parallel + */ + + /* + * cd ratio is dependent on cfg width and whether the bitstream + * is encrypted and/or compressed. + * + * | width | encr. | compr. | cd ratio | + * | 16 | 0 | 0 | 1 | + * | 16 | 0 | 1 | 4 | + * | 16 | 1 | 0 | 2 | + * | 16 | 1 | 1 | 4 | + * | 32 | 0 | 0 | 1 | + * | 32 | 0 | 1 | 8 | + * | 32 | 1 | 0 | 4 | + * | 32 | 1 | 1 | 8 | + */ + if (!compress && !encrypt) { + cd_ratio = CDRATIO_x1; + } else { + if (compress) + cd_ratio = CDRATIO_x4; + else + cd_ratio = CDRATIO_x2; + + /* if 32 bit, double the cd ratio (so register + field setting is incremented) */ + if (cfg_width == CFGWDTH_32) + cd_ratio += 1; + } + + fpgamgr_set_cfgwdth(cfg_width); + fpgamgr_set_cd_ratio(cd_ratio); + + return 0; +} + +static int fpgamgr_reset(void) +{ + unsigned long reg; + + /* S2F_NCONFIG = 0 */ + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG_SET_MSK); + + /* Wait for f2s_nstatus == 0 */ + if (wait_for_f2s_nstatus_pin(0)) + return -ETIME; + + /* S2F_NCONFIG = 1 */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG_SET_MSK); + + /* Wait for f2s_nstatus == 1 */ + if (wait_for_f2s_nstatus_pin(1)) + return -ETIME; + + /* read and confirm f2s_condone_pin = 0 and f2s_condone_oe = 1 */ + reg = readl(&fpga_manager_base->imgcfg_stat); + if ((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN_SET_MSK) != 0) + return -EPERM; + + if ((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_OE_SET_MSK) == 0) + return -EPERM; + + return 0; +} + +/* Start the FPGA programming by initialize the FPGA Manager */ +int fpgamgr_program_init(u32 * rbf_data, size_t rbf_size) +{ + int ret; + + /* Step 1 */ + if (fpgamgr_verify_msel()) + return -EPERM; + + /* Step 2 */ + if (fpgamgr_set_cdratio_cdwidth(CFGWDTH_32, rbf_data, rbf_size)) + return -EPERM; + + /* + * Step 3: + * Make sure no other external devices are trying to interfere with + * programming: + */ + if (wait_for_nconfig_pin_and_nstatus_pin()) + return -ETIME; + + /* + * Step 4: + * Deassert the signal drives from HPS + * + * S2F_NCE = 1 + * S2F_PR_REQUEST = 0 + * EN_CFG_CTRL = 0 + * EN_CFG_DATA = 0 + * S2F_NCONFIG = 1 + * S2F_NSTATUS_OE = 0 + * S2F_CONDONE_OE = 0 + */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NCE_SET_MSK); + + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST_SET_MSK); + + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA_SET_MSK | + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL_SET_MSK); + + setbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG_SET_MSK); + + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE_SET_MSK | + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE_SET_MSK); + + /* + * Step 5: + * Enable overrides + * S2F_NENABLE_CONFIG = 0 + * S2F_NENABLE_NCONFIG = 0 + */ + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG_SET_MSK); + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG_SET_MSK); + + /* + * Disable driving signals that HPS doesn't need to drive. + * S2F_NENABLE_NSTATUS = 1 + * S2F_NENABLE_CONDONE = 1 + */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS_SET_MSK | + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE_SET_MSK); + + /* + * Step 6: + * Drive chip select S2F_NCE = 0 + */ + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NCE_SET_MSK); + + /* Step 7 */ + if (wait_for_nconfig_pin_and_nstatus_pin()) + return -ETIME; + + /* Step 8 */ + ret = fpgamgr_reset(); + + if (ret) + return ret; + + /* + * Step 9: + * EN_CFG_CTRL and EN_CFG_DATA = 1 + */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA_SET_MSK | + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL_SET_MSK); + + return 0; +} + +/* Ensure the FPGA entering config done */ +static int fpgamgr_program_poll_cd(void) +{ + unsigned long reg, i; + + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + reg = readl(&fpga_manager_base->imgcfg_stat); + if (reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN_SET_MSK) + return 0; + + if ((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK) == 0) { + printf("nstatus == 0 while waiting for condone\n"); + return -EPERM; + } + } + + if (i == FPGA_TIMEOUT_CNT) + return -ETIME; + + return 0; +} + +/* Ensure the FPGA entering user mode */ +static int fpgamgr_program_poll_usermode(void) +{ + unsigned long reg; + int ret = 0; + + if (fpgamgr_dclkcnt_set(0xf)) + return -ETIME; + + ret = wait_for_user_mode(); + if (ret < 0) { + printf("%s: Failed to enter user mode with ", __func__); + printf("error code %d\n", ret); + return ret; + } + + /* + * Step 14: + * Stop DATA path and Dclk + * EN_CFG_CTRL and EN_CFG_DATA = 0 + */ + clrbits_le32(&fpga_manager_base->imgcfg_ctrl_02, + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA_SET_MSK | + ALT_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL_SET_MSK); + + /* + * Step 15: + * Disable overrides + * S2F_NENABLE_CONFIG = 1 + * S2F_NENABLE_NCONFIG = 1 + */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG_SET_MSK); + setbits_le32(&fpga_manager_base->imgcfg_ctrl_00, + ALT_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG_SET_MSK); + + /* Disable chip select S2F_NCE = 1 */ + setbits_le32(&fpga_manager_base->imgcfg_ctrl_01, + ALT_FPGAMGR_IMGCFG_CTL_01_S2F_NCE_SET_MSK); + + /* + * Step 16: + * Final check + */ + reg = readl(&fpga_manager_base->imgcfg_stat); + if (((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK) != + ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK) || + ((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN_SET_MSK) != + ALT_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN_SET_MSK) || + ((reg & ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK) != + ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK)) + return -EPERM; + + return 0; +} + +int fpgamgr_program_finish(void) +{ + /* Ensure the FPGA entering config done */ + int status = fpgamgr_program_poll_cd(); + + if (status) { + printf("FPGA: Poll CD failed with error code %d\n", status); + return -EPERM; + } + WATCHDOG_RESET(); + + /* Ensure the FPGA entering user mode */ + status = fpgamgr_program_poll_usermode(); + if (status) { + printf("FPGA: Poll usermode failed with error code %d\n", + status); + return -EPERM; + } + + printf("Full Configuration Succeeded.\n"); + + return 0; +} + +/* + * FPGA Manager to program the FPGA. This is the interface used by FPGA driver. + * Return 0 for sucess, non-zero for error. + */ +int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + unsigned long status; + + /* disable all signals from hps peripheral controller to fpga */ + writel(0, &system_manager_base->fpgaintf_en_global); + + /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ + socfpga_bridges_reset(); + + /* Initialize the FPGA Manager */ + status = fpgamgr_program_init((u32 *)rbf_data, rbf_size); + if (status) + return status; + + /* Write the RBF data to FPGA Manager */ + fpgamgr_program_write(rbf_data, rbf_size); + + return fpgamgr_program_finish(); +} diff --git a/drivers/fpga/socfpga_gen5.c b/drivers/fpga/socfpga_gen5.c new file mode 100644 index 00000000000..3dfb0303d36 --- /dev/null +++ b/drivers/fpga/socfpga_gen5.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common.h> +#include <asm/io.h> +#include <linux/errno.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define FPGA_TIMEOUT_CNT 0x1000000 + +static struct socfpga_fpga_manager *fpgamgr_regs = + (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* Set CD ratio */ +static void fpgamgr_set_cd_ratio(unsigned long ratio) +{ + clrsetbits_le32(&fpgamgr_regs->ctrl, + 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB, + (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB); +} + +/* Start the FPGA programming by initialize the FPGA Manager */ +static int fpgamgr_program_init(void) +{ + unsigned long msel, i; + + /* Get the MSEL value */ + msel = readl(&fpgamgr_regs->stat); + msel &= FPGAMGRREGS_STAT_MSEL_MASK; + msel >>= FPGAMGRREGS_STAT_MSEL_LSB; + + /* + * Set the cfg width + * If MSEL[3] = 1, cfg width = 32 bit + */ + if (msel & 0x8) { + setbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x4); + /* MSEL[1:0] = 2, CD Ratio = 8 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x8); + + } else { /* MSEL[3] = 0 */ + clrbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 2 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x2); + /* MSEL[1:0] = 2, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x4); + } + + /* To enable FPGA Manager configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK); + + /* To enable FPGA Manager drive over configuration line */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + /* Put FPGA into reset phase */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (1) wait until FPGA enter reset phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE) + break; + } + + /* If not in reset state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) { + puts("FPGA: Could not reset\n"); + return -1; + } + + /* Release FPGA from reset phase */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (2) wait until FPGA enter configuration phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE) + break; + } + + /* If not in configuration state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) { + puts("FPGA: Could not configure\n"); + return -2; + } + + /* Clear all interrupts in CB Monitor */ + writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi); + + /* Enable AXI configuration */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Ensure the FPGA entering config done */ +static int fpgamgr_program_poll_cd(void) +{ + const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK | + FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK; + unsigned long reg, i; + + /* (3) wait until full config done */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + reg = readl(&fpgamgr_regs->gpio_ext_porta); + + /* Config error */ + if (!(reg & mask)) { + printf("FPGA: Configuration error.\n"); + return -3; + } + + /* Config done without error */ + if (reg & mask) + break; + } + + /* Timeout happened, return error */ + if (i == FPGA_TIMEOUT_CNT) { + printf("FPGA: Timeout waiting for program.\n"); + return -4; + } + + /* Disable AXI configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Ensure the FPGA entering init phase */ +static int fpgamgr_program_poll_initphase(void) +{ + unsigned long i; + + /* Additional clocks for the CB to enter initialization phase */ + if (fpgamgr_dclkcnt_set(0x4)) + return -5; + + /* (4) wait until FPGA enter init phase or user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE) + break; + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -6; + + return 0; +} + +/* Ensure the FPGA entering user mode */ +static int fpgamgr_program_poll_usermode(void) +{ + unsigned long i; + + /* Additional clocks for the CB to exit initialization phase */ + if (fpgamgr_dclkcnt_set(0x5000)) + return -7; + + /* (5) wait until FPGA enter user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -8; + + /* To release FPGA Manager drive over configuration line */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + return 0; +} + +/* + * FPGA Manager to program the FPGA. This is the interface used by FPGA driver. + * Return 0 for sucess, non-zero for error. + */ +int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + unsigned long status; + + if ((uint32_t)rbf_data & 0x3) { + puts("FPGA: Unaligned data, realign to 32bit boundary.\n"); + return -EINVAL; + } + + /* Prior programming the FPGA, all bridges need to be shut off */ + + /* Disable all signals from hps peripheral controller to fpga */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + + /* Disable all signals from FPGA to HPS SDRAM */ +#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080 + writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS); + + /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ + socfpga_bridges_reset(1); + + /* Unmap the bridges from NIC-301 */ + writel(0x1, SOCFPGA_L3REGS_ADDRESS); + + /* Initialize the FPGA Manager */ + status = fpgamgr_program_init(); + if (status) + return status; + + /* Write the RBF data to FPGA Manager */ + fpgamgr_program_write(rbf_data, rbf_size); + + /* Ensure the FPGA entering config done */ + status = fpgamgr_program_poll_cd(); + if (status) + return status; + + /* Ensure the FPGA entering init phase */ + status = fpgamgr_program_poll_initphase(); + if (status) + return status; + + /* Ensure the FPGA entering user mode */ + return fpgamgr_program_poll_usermode(); +} diff --git a/include/configs/astro_mcf5373l.h b/include/configs/astro_mcf5373l.h index 723bc154b3b..7e373a2ca4d 100644 --- a/include/configs/astro_mcf5373l.h +++ b/include/configs/astro_mcf5373l.h @@ -192,10 +192,8 @@ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE #define CONFIG_FPGA_COUNT 1 -#define CONFIG_FPGA #define CONFIG_FPGA_XILINX #define CONFIG_FPGA_SPARTAN3 -#define CONFIG_FPGA_ALTERA #define CONFIG_FPGA_CYCLON2 #define CONFIG_SYS_FPGA_PROG_FEEDBACK #define CONFIG_SYS_FPGA_WAIT 1000 diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 7e63b558296..2c23ae50734 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -103,14 +103,10 @@ /* * FPGA Driver */ -#ifdef CONFIG_TARGET_SOCFPGA_GEN5 #ifdef CONFIG_CMD_FPGA -#define CONFIG_FPGA -#define CONFIG_FPGA_ALTERA -#define CONFIG_FPGA_SOCFPGA #define CONFIG_FPGA_COUNT 1 #endif -#endif + /* * L4 OSC1 Timer 0 */ diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h index 3f9b69aeda2..e5edd5e8fd0 100644 --- a/include/configs/theadorable.h +++ b/include/configs/theadorable.h @@ -86,8 +86,6 @@ #define CONFIG_SYS_MEM_TOP_HIDE 0x80000 /* FPGA programming support */ -#define CONFIG_FPGA -#define CONFIG_FPGA_ALTERA #define CONFIG_FPGA_STRATIX_V /* |