diff options
author | Tom Rini <trini@konsulko.com> | 2017-07-29 11:44:08 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-07-29 11:44:08 -0400 |
commit | 19d1f1a2f3ccfbf85125150f7876ce22714b38bd (patch) | |
tree | c356513a5bc27efa0ebf5c98026d7ebe2d675a8d /drivers/fpga/socfpga.c | |
parent | 211aaf309cde193918f9a19b0b010acebfd80a82 (diff) | |
parent | 9af91b7c4041a455de5f3e3da4e36644768bff68 (diff) | |
download | u-boot-19d1f1a2f3ccfbf85125150f7876ce22714b38bd.tar.gz |
Merge git://git.denx.de/u-boot-socfpga
Diffstat (limited to 'drivers/fpga/socfpga.c')
-rw-r--r-- | drivers/fpga/socfpga.c | 235 |
1 files changed, 2 insertions, 233 deletions
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c index f1b2f2c4da..28fa16b944 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(); -} |