diff mbox

[U-Boot,1/2] socfpga: Adding Scan Manager driver

Message ID 1384364050-6823-1-git-send-email-clsee@altera.com
State Superseded
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Chin Liang See Nov. 13, 2013, 5:34 p.m. UTC
Scan Manager driver will be called to configure the IOCSR
scan chain. This configuration will setup the IO buffer settings

Signed-off-by: Chin Liang See <clsee@altera.com>
Cc: Dinh Nguyen <dinguyen@altera.com>
Cc: Wolfgang Denk <wd@denx.de>
CC: Pavel Machek <pavel@denx.de>
Cc: Tom Rini <trini@ti.com>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
---
 arch/arm/cpu/armv7/socfpga/Makefile                |    2 +-
 arch/arm/cpu/armv7/socfpga/scan_manager.c          |  231 ++++++++++++++++++++
 arch/arm/cpu/armv7/socfpga/spl.c                   |    4 +
 arch/arm/include/asm/arch-socfpga/scan_manager.h   |   97 ++++++++
 .../include/asm/arch-socfpga/socfpga_base_addrs.h  |    1 +
 include/configs/socfpga_cyclone5.h                 |    1 +
 6 files changed, 335 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/socfpga/scan_manager.c
 create mode 100644 arch/arm/include/asm/arch-socfpga/scan_manager.h

Comments

Albert ARIBAUD Jan. 13, 2014, 8:34 a.m. UTC | #1
On Wed, 13 Nov 2013 11:34:10 -0600, Chin Liang See <clsee@altera.com>
wrote:

> Scan Manager driver will be called to configure the IOCSR
> scan chain. This configuration will setup the IO buffer settings
> 
> Signed-off-by: Chin Liang See <clsee@altera.com>
> Cc: Dinh Nguyen <dinguyen@altera.com>
> Cc: Wolfgang Denk <wd@denx.de>
> CC: Pavel Machek <pavel@denx.de>
> Cc: Tom Rini <trini@ti.com>
> Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> ---

Not sure what the point is of these CC:s in the commit message. Do I
miss some use of these? Can I, should I, should I not remove them
from the commit when applying to my tree?

Amicalement,
Chin Liang See Jan. 13, 2014, 2:34 p.m. UTC | #2
Dear Albert,

On Mon, 2014-01-13 at 09:34 +0100, ZY - albert.u.boot wrote:
> On Wed, 13 Nov 2013 11:34:10 -0600, Chin Liang See <clsee@altera.com>
> wrote:
> 
> > Scan Manager driver will be called to configure the IOCSR
> > scan chain. This configuration will setup the IO buffer settings
> > 
> > Signed-off-by: Chin Liang See <clsee@altera.com>
> > Cc: Dinh Nguyen <dinguyen@altera.com>
> > Cc: Wolfgang Denk <wd@denx.de>
> > CC: Pavel Machek <pavel@denx.de>
> > Cc: Tom Rini <trini@ti.com>
> > Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> > ---
> 
> Not sure what the point is of these CC:s in the commit message. Do I
> miss some use of these? Can I, should I, should I not remove them
> from the commit when applying to my tree?
> 

Actually these Cc will be helpful when using git send-email. It will
auto cc to these mailing list when the patch is send out for review
(instead entering the names manually every time). Thanks

Chin Liang


> Amicalement,
Albert ARIBAUD Jan. 13, 2014, 4:39 p.m. UTC | #3
Hi Chin,

On Mon, 13 Jan 2014 08:34:36 -0600, Chin Liang See <clsee@altera.com>
wrote:

> Dear Albert,
> 
> On Mon, 2014-01-13 at 09:34 +0100, ZY - albert.u.boot wrote:
> > On Wed, 13 Nov 2013 11:34:10 -0600, Chin Liang See <clsee@altera.com>
> > wrote:
> > 
> > > Scan Manager driver will be called to configure the IOCSR
> > > scan chain. This configuration will setup the IO buffer settings
> > > 
> > > Signed-off-by: Chin Liang See <clsee@altera.com>
> > > Cc: Dinh Nguyen <dinguyen@altera.com>
> > > Cc: Wolfgang Denk <wd@denx.de>
> > > CC: Pavel Machek <pavel@denx.de>
> > > Cc: Tom Rini <trini@ti.com>
> > > Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> > > ---
> > 
> > Not sure what the point is of these CC:s in the commit message. Do I
> > miss some use of these? Can I, should I, should I not remove them
> > from the commit when applying to my tree?
> > 
> 
> Actually these Cc will be helpful when using git send-email. It will
> auto cc to these mailing list when the patch is send out for review
> (instead entering the names manually every time). Thanks

That is useful to the sender, but useless to anyone else.

Aren't patman's Series-CC tags fulfilling the same function without
cluttering the commit message on the receiving/applying end?

> Chin Liang

Amicalement,
Chin Liang See Jan. 13, 2014, 5:41 p.m. UTC | #4
Hi Albert,

On Mon, 2014-01-13 at 17:39 +0100, ZY - albert.u.boot wrote:
> Hi Chin,
> 
> On Mon, 13 Jan 2014 08:34:36 -0600, Chin Liang See <clsee@altera.com>
> wrote:
> 
> > Dear Albert,
> > 
> > On Mon, 2014-01-13 at 09:34 +0100, ZY - albert.u.boot wrote:
> > > On Wed, 13 Nov 2013 11:34:10 -0600, Chin Liang See <clsee@altera.com>
> > > wrote:
> > > 
> > > > Scan Manager driver will be called to configure the IOCSR
> > > > scan chain. This configuration will setup the IO buffer settings
> > > > 
> > > > Signed-off-by: Chin Liang See <clsee@altera.com>
> > > > Cc: Dinh Nguyen <dinguyen@altera.com>
> > > > Cc: Wolfgang Denk <wd@denx.de>
> > > > CC: Pavel Machek <pavel@denx.de>
> > > > Cc: Tom Rini <trini@ti.com>
> > > > Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> > > > ---
> > > 
> > > Not sure what the point is of these CC:s in the commit message. Do I
> > > miss some use of these? Can I, should I, should I not remove them
> > > from the commit when applying to my tree?
> > > 
> > 
> > Actually these Cc will be helpful when using git send-email. It will
> > auto cc to these mailing list when the patch is send out for review
> > (instead entering the names manually every time). Thanks
> 
> That is useful to the sender, but useless to anyone else.
> 
> Aren't patman's Series-CC tags fulfilling the same function without
> cluttering the commit message on the receiving/applying end?


The patman script looks cool. Let me learn up this and using this when
submitting future patches. At same time, sorry for the hassle as I am
not aware the git send-email method not helpful for maintainer. For this
patch, wonder is it ok for you to manually remove the Ccs? Thanks and
appreciate again for your helps.

Chin Liang

> 
> > Chin Liang
> 
> Amicalement,
Wolfgang Denk Jan. 13, 2014, 9:08 p.m. UTC | #5
Dear Albert,

In message <20140113173924.684ce548@lilith> you wrote:
> 
> > Actually these Cc will be helpful when using git send-email. It will
> > auto cc to these mailing list when the patch is send out for review
> > (instead entering the names manually every time). Thanks
> 
> That is useful to the sender, but useless to anyone else.

This is not correct.  It is also an indicatioin who was explicitly
addressed when the patch was submitted, so you can later still see
from the commit message who was invited to commend and refrained from
doing so.  This may help a lot in discussions like "but I never had a
chance to see this patch".

Please keep these.  The are really useful.

Best regards,

Wolfgang Denk
Wolfgang Denk Jan. 13, 2014, 9:09 p.m. UTC | #6
Dear Chin Liang See,

In message <1389634896.9425.4.camel@clsee-VirtualBox.altera.com> you wrote:
> 
> The patman script looks cool. Let me learn up this and using this when
> submitting future patches. At same time, sorry for the hassle as I am
> not aware the git send-email method not helpful for maintainer. For this
> patch, wonder is it ok for you to manually remove the Ccs? Thanks and
> appreciate again for your helps.

Patman and the Cc: in the commit message may overlap, but they may
also include different lists of addresses.  For documentation
purposes, the Cc in the commit message are useful and should be kept.
Just my $ 0.02 ...

Best regards,

Wolfgang Denk
dinguyen@altera.com Jan. 13, 2014, 9:14 p.m. UTC | #7
Hi Wolfgang,

On Mon, 2014-01-13 at 22:08 +0100, ZY - wd wrote:
> Dear Albert,
> 
> In message <20140113173924.684ce548@lilith> you wrote:
> > 
> > > Actually these Cc will be helpful when using git send-email. It will
> > > auto cc to these mailing list when the patch is send out for review
> > > (instead entering the names manually every time). Thanks
> > 
> > That is useful to the sender, but useless to anyone else.
> 
> This is not correct.  It is also an indicatioin who was explicitly
> addressed when the patch was submitted, so you can later still see
> from the commit message who was invited to commend and refrained from
> doing so.  This may help a lot in discussions like "but I never had a
> chance to see this patch".
> 
> Please keep these.  The are really useful.

I'm glad you weighed in on this. I have done this CC: field many times
in patches sent to kernel.org, and have not received any feedbacks to
remove it. Some patches can include quite a few entries. So I was kinda
surprised to see a comment about it here on the u-boot list.

Dinh
> 
> Best regards,
> 
> Wolfgang Denk
>
Albert ARIBAUD Jan. 13, 2014, 10:07 p.m. UTC | #8
Hi Wolfgang,

On Mon, 13 Jan 2014 22:08:15 +0100, Wolfgang Denk <wd@denx.de> wrote:

> Dear Albert,
> 
> In message <20140113173924.684ce548@lilith> you wrote:
> > 
> > > Actually these Cc will be helpful when using git send-email. It will
> > > auto cc to these mailing list when the patch is send out for review
> > > (instead entering the names manually every time). Thanks
> > 
> > That is useful to the sender, but useless to anyone else.
> 
> This is not correct.  It is also an indicatioin who was explicitly
> addressed when the patch was submitted, so you can later still see
> from the commit message who was invited to commend and refrained from
> doing so.  This may help a lot in discussions like "but I never had a
> chance to see this patch".
> 
> Please keep these.  The are really useful.

Thanks Wolfgang. I hadn't considered this 'traceability' aspect -- I
haven't been involved in enough such discussions, obviously.

Chin Liang See: apologies for the noise.

> Best regards,
> 
> Wolfgang Denk

Amicalement,
Chin Liang See Jan. 13, 2014, 10:20 p.m. UTC | #9
Dear Wolfgang,

On Mon, 2014-01-13 at 22:09 +0100, ZY - wd wrote:
> Dear Chin Liang See,
> 
> In message <1389634896.9425.4.camel@clsee-VirtualBox.altera.com> you wrote:
> > 
> > The patman script looks cool. Let me learn up this and using this when
> > submitting future patches. At same time, sorry for the hassle as I am
> > not aware the git send-email method not helpful for maintainer. For this
> > patch, wonder is it ok for you to manually remove the Ccs? Thanks and
> > appreciate again for your helps.
> 
> Patman and the Cc: in the commit message may overlap, but they may
> also include different lists of addresses.  For documentation
> purposes, the Cc in the commit message are useful and should be kept.
> Just my $ 0.02 ...
> 

Thanks for the explanation. It definitely worth more than 2 cents. :)

Chin Liang

> Best regards,
> 
> Wolfgang Denk
>
Chin Liang See Jan. 13, 2014, 10:20 p.m. UTC | #10
Dear Albert,

On Mon, 2014-01-13 at 23:07 +0100, ZY - albert.u.boot wrote:
> Hi Wolfgang,
> 
> On Mon, 13 Jan 2014 22:08:15 +0100, Wolfgang Denk <wd@denx.de> wrote:
> 
> > Dear Albert,
> > 
> > In message <20140113173924.684ce548@lilith> you wrote:
> > > 
> > > > Actually these Cc will be helpful when using git send-email. It will
> > > > auto cc to these mailing list when the patch is send out for review
> > > > (instead entering the names manually every time). Thanks
> > > 
> > > That is useful to the sender, but useless to anyone else.
> > 
> > This is not correct.  It is also an indicatioin who was explicitly
> > addressed when the patch was submitted, so you can later still see
> > from the commit message who was invited to commend and refrained from
> > doing so.  This may help a lot in discussions like "but I never had a
> > chance to see this patch".
> > 
> > Please keep these.  The are really useful.
> 
> Thanks Wolfgang. I hadn't considered this 'traceability' aspect -- I
> haven't been involved in enough such discussions, obviously.
> 
> Chin Liang See: apologies for the noise.

No worries. We learned something today :)

Chin Liang

> 
> > Best regards,
> > 
> > Wolfgang Denk
> 
> Amicalement,
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile
index 3e84a0c..4edc5d4 100644
--- a/arch/arm/cpu/armv7/socfpga/Makefile
+++ b/arch/arm/cpu/armv7/socfpga/Makefile
@@ -9,4 +9,4 @@ 
 
 obj-y	:= lowlevel_init.o
 obj-y	+= misc.o timer.o reset_manager.o system_manager.o
-obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o
+obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o
diff --git a/arch/arm/cpu/armv7/socfpga/scan_manager.c b/arch/arm/cpu/armv7/socfpga/scan_manager.c
new file mode 100644
index 0000000..30cbb8b
--- /dev/null
+++ b/arch/arm/cpu/armv7/socfpga/scan_manager.c
@@ -0,0 +1,231 @@ 
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/freeze_controller.h>
+#include <asm/arch/scan_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+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);
+
+/*
+ * 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_mgr_io_scan_chain_engine_is_idle(uint32_t max_iter)
+{
+	uint32_t scanmgr_status;
+
+	scanmgr_status = readl(&scan_manager_base->stat);
+
+	/* 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
+			return SCAN_MGR_IO_SCAN_ENGINE_STATUS_ACTIVE;
+	}
+	return SCAN_MGR_IO_SCAN_ENGINE_STATUS_IDLE;
+}
+
+
+
+/* Program HPS IO Scan Chain */
+uint32_t scan_mgr_io_scan_chain_prg(
+	uint32_t io_scan_chain_id,
+	uint32_t io_scan_chain_len_in_bits,
+	const uint32_t *iocsr_scan_chain)
+{
+
+	uint16_t tdi_tdo_header;
+	uint32_t io_program_iter;
+	uint32_t io_scan_chain_data_residual;
+	uint32_t residual;
+	uint32_t i;
+	uint32_t index = 0;
+
+	/* De-assert reinit if the IO scan chain is intended for HIO */
+	if (3 == io_scan_chain_id)
+		clrbits_le32(&freeze_controller_base->hioctrl,
+			SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
+
+	/*
+	 * Check if the scan chain engine is inactive and the
+	 * WFIFO is empty before enabling the IO scan chain
+	 */
+	if (SCAN_MGR_IO_SCAN_ENGINE_STATUS_IDLE
+		!= scan_mgr_io_scan_chain_engine_is_idle(
+		MAX_WAITING_DELAY_IO_SCAN_ENGINE)) {
+		return 1;
+	}
+
+	/*
+	 * Enable IO Scan chain based on scan chain id
+	 * Note: only one chain can be enabled at a time
+	 */
+	setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id);
+
+	/*
+	 * Calculate number of iteration needed for full 128-bit (4 x32-bits)
+	 * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits
+	 */
+	io_program_iter	= io_scan_chain_len_in_bits >>
+		IO_SCAN_CHAIN_128BIT_SHIFT;
+	io_scan_chain_data_residual = io_scan_chain_len_in_bits &
+		IO_SCAN_CHAIN_128BIT_MASK;
+
+	/* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */
+	tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | (TDI_TDO_MAX_PAYLOAD <<
+		TDI_TDO_HEADER_SECOND_BYTE_SHIFT);
+
+	/* Program IO scan chain in 128-bit iteration */
+	for (i = 0; i < io_program_iter; i++) {
+
+		/* write TDI_TDO packet header to scan manager */
+		writel(tdi_tdo_header,	&scan_manager_base->fifodoublebyte);
+
+		/* calculate array index */
+		index = i * 4;
+
+		/* write 4 successive 32-bit IO scan chain data into WFIFO */
+		writel(iocsr_scan_chain[index],
+			&scan_manager_base->fifoquadbyte);
+		writel(iocsr_scan_chain[index + 1],
+			&scan_manager_base->fifoquadbyte);
+		writel(iocsr_scan_chain[index + 2],
+			&scan_manager_base->fifoquadbyte);
+		writel(iocsr_scan_chain[index + 3],
+			&scan_manager_base->fifoquadbyte);
+
+		/*
+		 * Check if the scan chain engine has completed the
+		 * IO scan chain data shifting
+		 */
+		if (SCAN_MGR_IO_SCAN_ENGINE_STATUS_IDLE
+			!= scan_mgr_io_scan_chain_engine_is_idle(
+			MAX_WAITING_DELAY_IO_SCAN_ENGINE)) {
+			/* Disable IO Scan chain when error detected */
+			clrbits_le32(&scan_manager_base->en,
+				1 << io_scan_chain_id);
+			return 1;
+		}
+	}
+
+	/* Calculate array index for final TDI_TDO packet */
+	index = io_program_iter * 4;
+
+	/* Final TDI_TDO packet if any */
+	if (0 != io_scan_chain_data_residual) {
+
+		/*
+		 * Calculate number of quad bytes FIFO write
+		 * needed for the final TDI_TDO packet
+		 */
+		io_program_iter	= io_scan_chain_data_residual >>
+			IO_SCAN_CHAIN_32BIT_SHIFT;
+
+		/*
+		 * Construct TDI_TDO packet for remaining IO
+		 * scan chain (2 bytes)
+		 */
+		tdi_tdo_header	= TDI_TDO_HEADER_FIRST_BYTE |
+			((io_scan_chain_data_residual - 1)
+			<< TDI_TDO_HEADER_SECOND_BYTE_SHIFT);
+
+		/*
+		 * Program the last part of IO scan chain write TDI_TDO packet
+		 * header (2 bytes) to scan manager
+		 */
+		writel(tdi_tdo_header, &scan_manager_base->fifodoublebyte);
+
+		for (i = 0; i < io_program_iter; i++) {
+			/*
+			 * write remaining scan chain data into scan
+			 * manager WFIFO with 4 bytes write
+			*/
+			writel(iocsr_scan_chain[index + i],
+				&scan_manager_base->fifoquadbyte);
+		}
+
+		index += io_program_iter;
+		residual = io_scan_chain_data_residual &
+			IO_SCAN_CHAIN_32BIT_MASK;
+
+		if (IO_SCAN_CHAIN_PAYLOAD_24BIT < residual) {
+			/*
+			 * write the last 4B scan chain data
+			 * into scan manager WFIFO
+			 */
+			writel(iocsr_scan_chain[index],
+				&scan_manager_base->fifoquadbyte);
+
+		} else {
+			/*
+			 * write the remaining 1 - 3 bytes scan chain
+			 * data into scan manager WFIFO byte by byte
+			 * to prevent JTAG engine shifting unused data
+			 * from the FIFO and mistaken the data as a
+			 * valid command (even though unused bits are
+			 * set to 0, but just to prevent hardware
+			 * glitch)
+			 */
+			for (i = 0; i < residual; i += 8) {
+				writel(((iocsr_scan_chain[index] >> i)
+					& IO_SCAN_CHAIN_BYTE_MASK),
+					&scan_manager_base->fifosinglebyte);
+
+			}
+		}
+
+		/*
+		 * Check if the scan chain engine has completed the
+		 * IO scan chain data shifting
+		 */
+		if (SCAN_MGR_IO_SCAN_ENGINE_STATUS_IDLE
+			!=  scan_mgr_io_scan_chain_engine_is_idle(
+			MAX_WAITING_DELAY_IO_SCAN_ENGINE)) {
+			/* Disable IO Scan chain when error detected */
+			clrbits_le32(&scan_manager_base->en,
+				1 << io_scan_chain_id);
+			return 1;
+		}
+	} /* if (io_scan_chain_data_residual) */
+
+	/* Disable IO Scan chain when configuration done*/
+	clrbits_le32(&scan_manager_base->en,
+		1 << io_scan_chain_id);
+
+	return 0;
+}
+
+int scan_mgr_configure_iocsr(void)
+{
+	int status = 0;
+
+	/* configure the IOCSR through scan chain */
+	status |= scan_mgr_io_scan_chain_prg(0,
+		CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH, iocsr_scan_chain0_table);
+	status |= scan_mgr_io_scan_chain_prg(1,
+		CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH, iocsr_scan_chain1_table);
+	status |= scan_mgr_io_scan_chain_prg(2,
+		CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH, iocsr_scan_chain2_table);
+	status |= scan_mgr_io_scan_chain_prg(3,
+		CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH, iocsr_scan_chain3_table);
+	return status;
+}
+
+
+
diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c
index 36a00c3..8a49a1a 100644
--- a/arch/arm/cpu/armv7/socfpga/spl.c
+++ b/arch/arm/cpu/armv7/socfpga/spl.c
@@ -32,6 +32,10 @@  void spl_board_init(void)
 	/* freeze all IO banks */
 	sys_mgr_frzctrl_freeze_req();
 
+	/* configure the IOCSR / IO buffer settings */
+	if (scan_mgr_configure_iocsr())
+		hang();
+
 	/* configure the pin muxing through system manager */
 	sysmgr_pinmux_init();
 #endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */
diff --git a/arch/arm/include/asm/arch-socfpga/scan_manager.h b/arch/arm/include/asm/arch-socfpga/scan_manager.h
new file mode 100644
index 0000000..dfbfade
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/scan_manager.h
@@ -0,0 +1,97 @@ 
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef	_SCAN_MANAGER_H_
+#define	_SCAN_MANAGER_H_
+
+struct socfpga_scan_manager {
+	u32	stat;
+	u32	en;
+	u32	padding[2];
+	u32	fifosinglebyte;
+	u32	fifodoublebyte;
+	u32	fifoquadbyte;
+};
+
+/*
+ * Shift count to get number of IO scan chain data in granularity
+ * of 128-bit ( N / 128 )
+ */
+#define IO_SCAN_CHAIN_128BIT_SHIFT		(7)
+
+/*
+ * Mask to get residual IO scan chain data in
+ * granularity of 128-bit ( N mod 128 )
+ */
+#define IO_SCAN_CHAIN_128BIT_MASK		(0x7F)
+
+/*
+ * Shift count to get number of IO scan chain
+ * data in granularity of 32-bit ( N / 32 )
+ */
+#define IO_SCAN_CHAIN_32BIT_SHIFT		(5)
+
+/*
+ * Mask to get residual IO scan chain data in
+ * granularity of 32-bit ( N mod 32 )
+ */
+#define IO_SCAN_CHAIN_32BIT_MASK		(0x1F)
+
+/* Byte mask */
+#define IO_SCAN_CHAIN_BYTE_MASK			(0xFF)
+
+/* 24-bits (3 bytes) IO scan chain payload definition */
+#define IO_SCAN_CHAIN_PAYLOAD_24BIT		(24)
+
+/*
+ * Maximum length of TDI_TDO packet payload is 128 bits,
+ * represented by (length - 1) in TDI_TDO header
+ */
+#define TDI_TDO_MAX_PAYLOAD			(127)
+
+/* TDI_TDO packet header for IO scan chain program */
+#define TDI_TDO_HEADER_FIRST_BYTE		(0x80)
+
+/* Position of second command byte for TDI_TDO packet */
+#define TDI_TDO_HEADER_SECOND_BYTE_SHIFT	(8)
+
+/* IO scan chain engine is idle */
+#define SCAN_MGR_IO_SCAN_ENGINE_STATUS_IDLE	(0)
+
+/* IO scan chain engine is active */
+#define SCAN_MGR_IO_SCAN_ENGINE_STATUS_ACTIVE	(1)
+
+/*
+ * Maximum polling loop to wait for IO scan chain engine
+ * becomes idle to prevent infinite loop
+ */
+#define MAX_WAITING_DELAY_IO_SCAN_ENGINE	(100)
+
+#define SCANMGR_STAT_ACTIVE_GET(x) (((x) & 0x80000000) >> 31)
+#define SCANMGR_STAT_WFIFOCNT_GET(x) (((x) & 0x70000000) >> 28)
+
+/*
+ * Program HPS IO Scan Chain
+ * io_scan_chain_id - IO scan chain ID
+ * io_scan_chain_len_in_bits - IO scan chain length in bits
+ * iocsr_scan_chain - IO scan chain table
+ */
+uint32_t scan_mgr_io_scan_chain_prg(
+	uint32_t io_scan_chain_id,
+	uint32_t io_scan_chain_len_in_bits,
+	const uint32_t *iocsr_scan_chain);
+
+
+extern const uint32_t iocsr_scan_chain0_table[
+	((CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH / 32) + 1)];
+extern const uint32_t iocsr_scan_chain1_table[
+	((CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH / 32) + 1)];
+extern const uint32_t iocsr_scan_chain2_table[
+	((CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH / 32) + 1)];
+extern const uint32_t iocsr_scan_chain3_table[
+	((CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH / 32) + 1)];
+
+#endif /* _SCAN_MANAGER_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
index 50c4ebd..8d329cf 100644
--- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
+++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
@@ -13,5 +13,6 @@ 
 #define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000
 #define SOCFPGA_RSTMGR_ADDRESS 0xffd05000
 #define SOCFPGA_SYSMGR_ADDRESS 0xffd08000
+#define SOCFPGA_SCANMGR_ADDRESS 0xfff02000
 
 #endif /* _SOCFPGA_BASE_ADDRS_H_ */
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index 980636c..981a26b 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -8,6 +8,7 @@ 
 
 #include <asm/arch/socfpga_base_addrs.h>
 #include "../../board/altera/socfpga/pinmux_config.h"
+#include "../../board/altera/socfpga/iocsr_config.h"
 
 /*
  * High level configuration