All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Simek <monstr@monstr.eu>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v7] socfpga: Adding Scan Manager driver
Date: Wed, 12 Mar 2014 15:57:12 +0100	[thread overview]
Message-ID: <532075C8.70205@monstr.eu> (raw)
In-Reply-To: <1394035559-3378-1-git-send-email-clsee@altera.com>

On 03/05/2014 05:05 PM, Chin Liang See 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>
> ---
> Changes for v7
> - Enhance the function scan_chain_engine_is_idle
> Changes for v6
> - Fixed various coding style issue
> Changes for v5
> - Removal of additional blank line
> - Added comment for magic number
> Changes for v4
> - avoid code duplication by add goto error
> - include underscore to variables name
> Changes for v3
> - merge the handoff file and driver into single patch
> Changes for v2
> - rebase with latest v2014.01-rc1
> ---
>  arch/arm/cpu/armv7/socfpga/Makefile                |    2 +-
>  arch/arm/cpu/armv7/socfpga/scan_manager.c          |  209 +++++++
>  arch/arm/cpu/armv7/socfpga/spl.c                   |    4 +
>  arch/arm/include/asm/arch-socfpga/scan_manager.h   |   90 +++
>  .../include/asm/arch-socfpga/socfpga_base_addrs.h  |    1 +
>  board/altera/socfpga/iocsr_config.c                |  657 ++++++++++++++++++++
>  board/altera/socfpga/iocsr_config.h                |   17 +
>  include/configs/socfpga_cyclone5.h                 |    1 +
>  8 files changed, 980 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
>  create mode 100644 board/altera/socfpga/iocsr_config.c
>  create mode 100644 board/altera/socfpga/iocsr_config.h
> 
> diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile
> index cbe1d40..eb33f2c 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 clock_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..a820b1b
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/socfpga/scan_manager.c
> @@ -0,0 +1,209 @@
> +/*
> + *  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_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 0;
> +	}
> +	return 1;
> +}
> +
> +/* 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. In
> +	 * this, its the chain 3.
> +	 */
> +	if (io_scan_chain_id == 3)
> +		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_chain_engine_is_idle(SCAN_MAX_DELAY))
> +		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->fifo_double_byte);
> +
> +		/* calculate array index. Multiply by 4 as write 4 x 32bits */
> +		index = i * 4;
> +
> +		/* write 4 successive 32-bit IO scan chain data into WFIFO */
> +		writel(iocsr_scan_chain[index],
> +		       &scan_manager_base->fifo_quad_byte);
> +		writel(iocsr_scan_chain[index + 1],
> +		       &scan_manager_base->fifo_quad_byte);
> +		writel(iocsr_scan_chain[index + 2],
> +		       &scan_manager_base->fifo_quad_byte);
> +		writel(iocsr_scan_chain[index + 3],
> +		       &scan_manager_base->fifo_quad_byte);
> +
> +		/*
> +		 * Check if the scan chain engine has completed the
> +		 * IO scan chain data shifting
> +		 */
> +		if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
> +			goto error;
> +	}
> +
> +	/* Calculate array index for final TDI_TDO packet */
> +	index = io_program_iter * 4;
> +
> +	/* Final TDI_TDO packet if any */
> +	if (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->fifo_double_byte);
> +
> +		for (i = 0; i < io_program_iter; i++) {
> +			/*
> +			 * write remaining scan chain data into scan
> +			 * manager WFIFO with 4 bytes write
> +			*/

Wrong indentation here.


> +			writel(iocsr_scan_chain[index + i],
> +			       &scan_manager_base->fifo_quad_byte);
> +		}
> +
> +		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->fifo_quad_byte);
> +		} 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->fifo_single_byte);
> +			}
> +		}
> +
> +		/*
> +		 * Check if the scan chain engine has completed the
> +		 * IO scan chain data shifting
> +		 */
> +		if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY))
> +			goto error;
> +	}
> +
> +	/* Disable IO Scan chain when configuration done*/

<space>*/ here.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140312/c1ceb712/attachment.pgp>

  parent reply	other threads:[~2014-03-12 14:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-05 16:05 [U-Boot] [PATCH v7] socfpga: Adding Scan Manager driver Chin Liang See
2014-03-12 14:45 ` Chin Liang See
2014-03-12 14:54   ` Michal Simek
2014-03-24 15:21     ` Chin Liang See
2014-03-25  6:20       ` Michal Simek
2014-04-01  8:46         ` Pavel Machek
2014-04-01  9:07           ` Michal Simek
2014-04-01 11:17             ` Steffen Trumtrar
2014-04-03  9:35               ` Pavel Machek
2014-04-03 10:05                 ` Michal Simek
2014-03-12 14:57 ` Michal Simek [this message]
2014-03-24 15:25   ` Chin Liang See

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=532075C8.70205@monstr.eu \
    --to=monstr@monstr.eu \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.