/* 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; }
/* Check whether FPGA is ready to be accessed */ int fpgamgr_test_fpga_ready(void) { /* Check for init done signal */ if (!is_fpgamgr_initdone_high()) return 0; /* Check again to avoid false glitches */ if (!is_fpgamgr_initdone_high()) return 0; if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) return 0; return 1; }
/* 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; }
/* 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; }