summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTien Fong Chee <tien.fong.chee@intel.com>2018-10-23 13:49:34 +0800
committerTien Fong Chee <tien.fong.chee@intel.com>2018-10-23 13:49:34 +0800
commitd902069ce831d74d8db57720dd75449e32310322 (patch)
tree65d9e90b779c0b69fa2b168d1bfc4b22ebabfd8c
parent3d79f8aaf8930da2c118a52ef831739e6d855295 (diff)
downloadu-boot-socfpga-d902069ce831d74d8db57720dd75449e32310322.tar.gz
FogBugz #604090-1: Adding FPGA manager HPS JTAG driver
HPS JTAG driver supports simple function for reading the FPGA JTAG ID code. The main purpose of this driver is for showing the capability of Arria 10 to run JTAG from HPS instead of FPGA. Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com> --- v2- Using #define MACRO for constant value. Disabled reading JTAG ID code by default.
-rwxr-xr-xarch/arm/cpu/armv7/socfpga_arria10/fpga_manager.c103
-rwxr-xr-xarch/arm/include/asm/arch-socfpga_arria10/fpga_manager.h33
-rwxr-xr-xinclude/configs/socfpga_arria10.h8
3 files changed, 141 insertions, 3 deletions
diff --git a/arch/arm/cpu/armv7/socfpga_arria10/fpga_manager.c b/arch/arm/cpu/armv7/socfpga_arria10/fpga_manager.c
index 1538081828..7b447a36cc 100755
--- a/arch/arm/cpu/armv7/socfpga_arria10/fpga_manager.c
+++ b/arch/arm/cpu/armv7/socfpga_arria10/fpga_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2016 Altera Corporation <www.altera.com>
+ * Copyright (C) 2014-2018 Altera Corporation <www.altera.com>
*
* SPDX-License-Identifier: GPL-2.0
*/
@@ -473,6 +473,107 @@ int fpgamgr_program_fini(void)
return 0;
}
+#ifdef CONFIG_FPGAMGR_HPS_JTAG
+static void change_tsm_tdi(u32 tsm_tdi)
+{
+ writel(tsm_tdi, &fpga_manager_base->jtag_data_w);
+
+ /* Start Transfer Session */
+ writel(ALT_FPGAMGR_JTAG_KICK_STARTSESSION_SET_MSK,
+ &fpga_manager_base->jtag_kick);
+
+ /* Ensure there is no ongoing transfer */
+ while (ALT_FPGAMGR_JTAG_STAT_SESSIONSTAT_GET
+ (fpga_manager_base->jtag_status)) {
+ WATCHDOG_RESET();
+ }
+
+ return;
+}
+
+int fpgamgr_jtag_get_idcode(void)
+{
+ u32 reg;
+
+ /* Idle->Select_DR->Select_IR->...->Update_IR->Idle(next) */
+ change_tsm_tdi(0x60030060);
+
+ /* Idle-> elect_DR->Capture_DR->Shift_DR(next) */
+ change_tsm_tdi(0x10000000);
+
+ /* Clear both RX & TX FIFO (Reading register would cause system hang) */
+ writel(ALT_FPGAMGR_JTAG_KICK_CLEAR_RXTX_FIFO_SET_MSK,
+ &fpga_manager_base->jtag_kick);
+
+ /* SHift_DR(Reading low 16 bits)->...->Shift_DR(next) */
+ change_tsm_tdi(0);
+
+ reg = readl(&fpga_manager_base->jtag_data_r);
+
+ /* SHift_DR(Reading high 16 bits)->...->Exit_DR->Update_DR(next) */
+ change_tsm_tdi(0xc0000000);
+ reg |= readl(&fpga_manager_base->jtag_data_r) << 16;
+
+ /* Update_DR -> Idle(next) */
+ change_tsm_tdi(0);
+
+ return reg;
+}
+
+void fpgamgr_jtag_enable(void)
+{
+ /* Clear JTAG config register */
+ writel(0, &fpga_manager_base->jtag_config);
+
+ /*
+ * Write JTagHostEn=1,JTagPortEn=0
+ * TDI,TMS,TCK will be driven to 0
+ * JTAG_EN will be driven to 1
+ */
+ setbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_JTAGHOSTEN_SET_MSK);
+
+ clrbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_JTAGPORTEN_SET_MSK);
+
+ /*
+ * JTagPortEn=1
+ * connects the TDI/TCK/TMS
+ */
+ setbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_JTAGPORTEN_SET_MSK);
+}
+
+void fpgamgr_jtag_disable(void)
+{
+ clrbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_JTAGHOSTEN_SET_MSK);
+
+ clrbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_JTAGPORTEN_SET_MSK);
+}
+
+void fpgamgr_jtag_init(void)
+{
+ /* Write the 16(TX Bits + 1) of TX bits */
+ setbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_TXSIZE_SET(15));
+
+ /* TCK divide ratio (14.30Mhz) TCK */
+ setbits_le32(&fpga_manager_base->jtag_config,
+ ALT_FPGAMGR_JTAG_CFG_TCKRATIO_SET(7));
+
+ /* Reset -> Idle */
+ change_tsm_tdi(0x1f0000);
+
+ /* Clear both RX & TX FIFO */
+ writel(ALT_FPGAMGR_JTAG_KICK_CLEAR_RXTX_FIFO_SET_MSK,
+ &fpga_manager_base->jtag_kick);
+
+ return;
+}
+#endif
+
/* Write the RBF data to FPGA Manager */
void fpgamgr_program_write(const unsigned long *rbf_data,
unsigned long rbf_size)
diff --git a/arch/arm/include/asm/arch-socfpga_arria10/fpga_manager.h b/arch/arm/include/asm/arch-socfpga_arria10/fpga_manager.h
index 29a693e26b..c9fff63180 100755
--- a/arch/arm/include/asm/arch-socfpga_arria10/fpga_manager.h
+++ b/arch/arm/include/asm/arch-socfpga_arria10/fpga_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2016 Altera Corporation <www.altera.com>
+ * Copyright (C) 2014-2018 Altera Corporation <www.altera.com>
*
* SPDX-License-Identifier: GPL-2.0
*/
@@ -88,6 +88,31 @@ struct socfpga_fpga_manager {
#define ALT_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SET_MSK 0x01000000
#define ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_LSB 16
+#define ALT_SECMGR_JTAG_DBG_EN_SET_MSK 0x00000001
+#define ALT_FPGAMGR_JTAG_CFG_JTAGHOSTEN_SET_MSK 0x00000001
+#define ALT_FPGAMGR_JTAG_CFG_JTAGPORTEN_SET_MSK 0x00000002
+#define ALT_FPGAMGR_JTAG_CFG_TRSTEN_SET_MSK 0x00000010
+#define ALT_FPGAMGR_JTAG_CFG_LOOPBACKEN_SET_MSK 0x00000004
+#define ALT_FPGAMGR_JTAG_STATUS_CONF_DONE_MSK 0x4
+#define ALT_FPGAMGR_JTAG_CFG_TXSIZE_SET(value) (((value) << 16) & 0xffff0000)
+#define ALT_FPGAMGR_JTAG_CFG_TCKRATIO_SET(value) (((value) << 8) & 0x0000ff00)
+#define ALT_FPGAMGR_JTAG_STAT_TXFIFODONESZ_GET(value) \
+ (((value) & 0xffff0000) >> 16)
+#define ALT_FPGAMGR_JTAG_STAT_TXFIFOFULL_GET(value) \
+ (((value) & 0x200) >> 9)
+#define ALT_FPGAMGR_JTAG_STAT_TXFIFOLEVEL_GET(value) \
+ (((value) & 0x0000000f))
+#define ALT_FPGAMGR_JTAG_STAT_SESSIONSTAT_GET(value) \
+ (((value) & 0x8000) >> 15)
+#define ALT_FPGAMGR_JTAG_KICK_CLEAR_RXTX_FIFO_SET_MSK 0x0000000C
+#define ALT_FPGAMGR_JTAG_KICK_STARTSESSION_SET_MSK 0x00000001
+#define ALT_FPGAMGR_JTAG_KICK_STOPSESSION_SET_MSK 0x00000002
+#define ALT_FPGAMGR_JTAG_KICK_STARTSESSION_CLR_MSK 0xfffffffe
+
+#define ALT_FPGA_SECOPT1_OPT_ADDRESS 0xffd0206C
+#define ALT_FPGA_SECOPT1_OPT_EXTJTAG_BYPASS_SET_MSK 0X400
+#define ALT_FPGA_SECOPT1_OPT_HPSJTAG_BYPASS_SET_MSK 0x1000
+
/* Timeout counter */
#define FPGA_TIMEOUT_CNT 0x1000000
#define FPGA_TIMEOUT_MSEC 1000 /* timeout in ms */
@@ -121,6 +146,12 @@ void fpgamgr_axi_write(const unsigned long *rbf_data,
const unsigned long fpgamgr_data_addr, unsigned long rbf_size);
int fpgamgr_wait_early_user_mode(void);
int is_fpgamgr_early_user_mode(void);
+#ifdef CONFIG_FPGAMGR_HPS_JTAG
+void fpgamgr_jtag_enable(void);
+void fpgamgr_jtag_disable(void);
+void fpgamgr_jtag_init(void);
+int fpgamgr_jtag_get_idcode(void);
+#endif
#endif /* __ASSEMBLY__ */
#endif /* _SOCFPGA_FPGA_MANAGER_H_ */
diff --git a/include/configs/socfpga_arria10.h b/include/configs/socfpga_arria10.h
index 2bfb4fc486..363830c873 100755
--- a/include/configs/socfpga_arria10.h
+++ b/include/configs/socfpga_arria10.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 Intel Corporation <www.intel.com>
+ * Copyright (C) 2014-2018 Intel Corporation <www.intel.com>
*
* SPDX-License-Identifier: GPL-2.0
*/
@@ -650,6 +650,12 @@ CONFIG_NAND_DENALI is also defined.
#endif /* CONFIG_FPGA */
/*
+ * FPGA MANAGER HPS JTAG support
+ * Enable it if reading JTAG ID code is required
+ */
+#undef CONFIG_FPGAMGR_HPS_JTAG
+
+/*
* Memory allocation (MALLOC)
*/