From bd0f5a91f30c0ff2d355bb7b9858f8b6fb7f5430 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 31 Jul 2015 11:06:50 -0500 Subject: [PATCH] arm: socfpga: scan: Add code to get FPGA ID Add code to get the FPGA type for Altera's SoCFPGA family of FPGA. The code uses the scan manager to send jtag pulses that will return the FPGA ID. Signed-off-by: Dinh Nguyen --- .../mach-socfpga/include/mach/scan_manager.h | 1 + arch/arm/mach-socfpga/scan_manager.c | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/arch/arm/mach-socfpga/include/mach/scan_manager.h b/arch/arm/mach-socfpga/include/mach/scan_manager.h index 3b55e370f2..5ca6843557 100644 --- a/arch/arm/mach-socfpga/include/mach/scan_manager.h +++ b/arch/arm/mach-socfpga/include/mach/scan_manager.h @@ -18,6 +18,7 @@ struct socfpga_scan_manager { }; int scan_mgr_configure_iocsr(void); +u32 scan_mgr_get_fpga_id(void); int iocsr_get_config_table(const unsigned int chain_id, const unsigned long **table, unsigned int *table_len); diff --git a/arch/arm/mach-socfpga/scan_manager.c b/arch/arm/mach-socfpga/scan_manager.c index e3c4684989..566b33f2b6 100644 --- a/arch/arm/mach-socfpga/scan_manager.c +++ b/arch/arm/mach-socfpga/scan_manager.c @@ -9,6 +9,7 @@ #include #include #include +#include /* * Maximum polling loop to wait for IO scan chain engine becomes idle @@ -33,6 +34,8 @@ static const struct socfpga_scan_manager *scan_manager_base = (void *)(SOCFPGA_SCANMGR_ADDRESS); static const struct socfpga_freeze_controller *freeze_controller_base = (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); +static struct socfpga_system_manager *sys_mgr_base = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; /** * scan_chain_engine_is_idle() - Check if the JTAG scan chain is idle @@ -205,3 +208,55 @@ int scan_mgr_configure_iocsr(void) status |= scan_mgr_io_scan_chain_prg(3); return status; } + +/** + * scan_mgr_get_fpga_id() - Obtain FPGA JTAG ID + * + * This function obtains JTAG ID from the FPGA TAP controller. + */ +u32 scan_mgr_get_fpga_id(void) +{ + const unsigned long data = 0; + u32 id = 0xffffffff; + int ret; + + /* Enable HPS to talk to JTAG in the FPGA through the System Manager */ + writel(0x1, &sys_mgr_base->scanmgrgrp_ctrl); + + /* Enable port 7 */ + writel(0x80, &scan_manager_base->en); + /* write to CSW to make s2f_ntrst reset */ + writel(0x02, &scan_manager_base->stat); + + /* Add a pause */ + mdelay(1); + + /* write 0x00 to CSW to clear the s2f_ntrst */ + writel(0, &scan_manager_base->stat); + + /* + * Go to Test-Logic-Reset state. + * This sets TAP controller into IDCODE mode. + */ + scan_mgr_jtag_io(JTAG_BP_INSN | JTAG_BP_TMS, 0x1f | (1 << 5), 0x0); + + /* Go to Run-Test/Idle -> DR-Scan -> Capture-DR -> Shift-DR state. */ + scan_mgr_jtag_io(JTAG_BP_INSN | JTAG_BP_TMS, 0x02 | (1 << 4), 0x0); + + /* + * Push 4 bytes of data through TDI->DR->TDO. + * + * Length of TDI data is 32bits (length - 1) and they are only + * zeroes as we care only for TDO data. + */ + ret = scan_mgr_jtag_insn_data(0x4, &data, 32); + /* Read 32 bit from captured JTAG data. */ + if (!ret) + id = readl(&scan_manager_base->fifo_quad_byte); + + /* Disable all port */ + writel(0, &scan_manager_base->en); + writel(0, &sys_mgr_base->scanmgrgrp_ctrl); + + return id; +} -- 2.30.2