From: Dinh Nguyen <dingu...@opensource.altera.com>

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 <dingu...@opensource.altera.com>
Signed-off-by: Marek Vasut <ma...@denx.de>
---
 arch/arm/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 3b55e37..5ca6843 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 4f2c4b5..d78e91d 100644
--- a/arch/arm/mach-socfpga/scan_manager.c
+++ b/arch/arm/mach-socfpga/scan_manager.c
@@ -9,6 +9,7 @@
 #include <asm/io.h>
 #include <asm/arch/freeze_controller.h>
 #include <asm/arch/scan_manager.h>
+#include <asm/arch/system_manager.h>
 
 /*
  * 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.1.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to