/* Position of second command byte for TDI_TDO packet */
#define TDI_TDO_HEADER_SECOND_BYTE_SHIFT 8
-/*
- * Maximum polling loop to wait for IO scan chain engine
- * becomes idle to prevent infinite loop
- */
-#define SCAN_MAX_DELAY 100
-
-#define SCANMGR_STAT_ACTIVE_GET(x) (((x) & 0x80000000) >> 31)
-#define SCANMGR_STAT_WFIFOCNT_GET(x) (((x) & 0x70000000) >> 28)
-
int scan_mgr_configure_iocsr(void);
int iocsr_get_config_table(const unsigned int chain_id,
const unsigned long **table,
*/
#include <common.h>
+#include <errno.h>
#include <asm/io.h>
#include <asm/arch/freeze_controller.h>
#include <asm/arch/scan_manager.h>
+/*
+ * Maximum polling loop to wait for IO scan chain engine becomes idle
+ * to prevent infinite loop. It is important that this is NOT changed
+ * to delay using timer functions, since at the time this function is
+ * called, timer might not yet be inited.
+ */
+#define SCANMGR_MAX_DELAY 100
+
+#define SCANMGR_STAT_ACTIVE (1 << 31)
+#define SCANMGR_STAT_WFIFOCNT_MASK 0x70000000
+
DECLARE_GLOBAL_DATA_PTR;
static const struct socfpga_scan_manager *scan_manager_base =
static const struct socfpga_freeze_controller *freeze_controller_base =
(void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
-/*
+/**
+ * scan_chain_engine_is_idle() - Check if the JTAG scan chain is idle
+ * @max_iter: Maximum number of iterations to wait for idle
+ *
* Function to check IO scan chain engine status and wait if the engine is
* is active. Poll the IO scan chain engine till maximum iteration reached.
*/
-static inline uint32_t scan_chain_engine_is_idle(uint32_t max_iter)
+static u32 scan_chain_engine_is_idle(u32 max_iter)
{
- uint32_t scanmgr_status;
-
- scanmgr_status = readl(&scan_manager_base->stat);
+ const u32 mask = SCANMGR_STAT_ACTIVE | SCANMGR_STAT_WFIFOCNT_MASK;
+ u32 status;
- /* Poll the engine until the scan engine is inactive */
- while (SCANMGR_STAT_ACTIVE_GET(scanmgr_status) ||
- (SCANMGR_STAT_WFIFOCNT_GET(scanmgr_status) > 0)) {
- max_iter--;
- if (max_iter > 0)
- scanmgr_status = readl(&scan_manager_base->stat);
- else
+ /* Poll the engine until the scan engine is inactive. */
+ do {
+ status = readl(&scan_manager_base->stat);
+ if (!(status & mask))
return 0;
- }
- return 1;
+ } while (max_iter--);
+
+ return -ETIMEDOUT;
}
/**
* Check if the scan chain engine is inactive and the
* WFIFO is empty before enabling the IO scan chain
*/
- if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
- return 1;
+ ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
+ if (ret)
+ return ret;
/*
* Enable IO Scan chain based on scan chain id
* Check if the scan chain engine has completed the
* IO scan chain data shifting
*/
- if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
+ ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
+ if (ret)
goto error;
}
* Check if the scan chain engine has completed the
* IO scan chain data shifting
*/
- if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
+ ret = scan_chain_engine_is_idle(SCANMGR_MAX_DELAY);
+ if (ret)
goto error;
}
error:
/* Disable IO Scan chain when error detected */
clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
- return 1;
+ return ret;
}
int scan_mgr_configure_iocsr(void)