socfpga: arria10: Wait for fifo empty after writing bitstream
authorPaweł Anikiel <pan@semihalf.com>
Fri, 17 Jun 2022 10:47:25 +0000 (12:47 +0200)
committerTien Fong Chee <tien.fong.chee@intel.com>
Fri, 1 Jul 2022 06:57:14 +0000 (14:57 +0800)
For some reason, on the Mercury+ AA1 module, calling
fpgamgr_wait_early_user_mode immediately after writing the peripheral
bitstream leaves the fpga in a broken state (ddr calibration hangs).
Adding a delay before the first sync word is written seems to fix this.
Inspecting the fpgamgr registers before and after the delay,
imgcfg_FifoEmpty is the only bit that changes. Waiting for this bit
(instead of a hardcoded delay) also fixes the issue.

Signed-off-by: Paweł Anikiel <pan@semihalf.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/fpga/socfpga_arria10.c

index 07bfe30..d808912 100644 (file)
@@ -80,6 +80,13 @@ static int wait_for_user_mode(void)
                1, FPGA_TIMEOUT_MSEC, false);
 }
 
+static int wait_for_fifo_empty(void)
+{
+       return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
+               ALT_FPGAMGR_IMGCFG_STAT_F2S_IMGCFG_FIFOEMPTY_SET_MSK,
+               1, FPGA_TIMEOUT_MSEC, false);
+}
+
 int is_fpgamgr_early_user_mode(void)
 {
        return (readl(&fpga_manager_base->imgcfg_stat) &
@@ -874,6 +881,7 @@ int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, size_t bsize,
 
                WATCHDOG_RESET();
        }
+       wait_for_fifo_empty();
 
        if (fpga_loadfs.rbfinfo.section == periph_section) {
                if (fpgamgr_wait_early_user_mode() != -ETIMEDOUT) {