diff mbox series

[U-Boot,4/5] fpga: virtex2: Add additional clock cycles after DONE assertion

Message ID 1560872836-21456-5-git-send-email-hancock@sedsystems.ca
State Accepted
Commit a0549f7390d33ec522de3a53e6031189d46a9ce7
Delegated to: Michal Simek
Headers show
Series Virtex2 FPGA enhancements | expand

Commit Message

Robert Hancock June 18, 2019, 3:47 p.m. UTC
Some Xilinx FPGA configuration options can result in the startup
sequence extending past the end of the FPGA bitstream. Continue applying
CCLK clock cycles for 8 cycles after DONE is asserted in order to ensure
the startup sequence is complete, as recommended by Xilinx.

Signed-off-by: Robert Hancock <hancock@sedsystems.ca>
---
 drivers/fpga/virtex2.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

Comments

Michal Simek June 19, 2019, 12:11 p.m. UTC | #1
On 18. 06. 19 17:47, Robert Hancock wrote:
> Some Xilinx FPGA configuration options can result in the startup
> sequence extending past the end of the FPGA bitstream. Continue applying
> CCLK clock cycles for 8 cycles after DONE is asserted in order to ensure
> the startup sequence is complete, as recommended by Xilinx.
> 
> Signed-off-by: Robert Hancock <hancock@sedsystems.ca>
> ---
>  drivers/fpga/virtex2.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c
> index 2383c69..5028244 100644
> --- a/drivers/fpga/virtex2.c
> +++ b/drivers/fpga/virtex2.c
> @@ -247,6 +247,7 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
>  			      int cookie)
>  {
>  	int ret_val = FPGA_SUCCESS;
> +	int num_done = 0;
>  	unsigned long ts;
>  
>  	/*
> @@ -264,12 +265,18 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
>  
>  	/*
>  	 * Check for successful configuration.  FPGA INIT_B and DONE
> -	 * should both be high upon successful configuration.
> +	 * should both be high upon successful configuration. Continue pulsing
> +	 * clock with data set to all ones until DONE is asserted and for 8
> +	 * clock cycles afterwards.
>  	 */
>  	ts = get_timer(0);
> -	ret_val = FPGA_SUCCESS;
> -	while (((*fn->done)(cookie) == FPGA_FAIL) ||
> -	       (*fn->init)(cookie)) {
> +	while (true) {
> +		if ((*fn->done)(cookie) == FPGA_SUCCESS &&
> +		    !((*fn->init)(cookie))) {
> +			if (num_done++ >= 8)
> +				break;
> +		}
> +
>  		if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
>  			printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n",
>  			       __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
> @@ -277,6 +284,11 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
>  			ret_val = FPGA_FAIL;
>  			break;
>  		}
> +		(*fn->wdata) (0xff, true, cookie);
> +		CONFIG_FPGA_DELAY();
> +		(*fn->clk) (false, true, cookie);
> +		CONFIG_FPGA_DELAY();
> +		(*fn->clk) (true, true, cookie);


There are some functions which check if function is present before it is
called. I think that the whole driver should be sync in this to make
sure that functions are really implemented if code expects them or fail.

But this can be done on the top of this series.

Thanks,
Michal
diff mbox series

Patch

diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c
index 2383c69..5028244 100644
--- a/drivers/fpga/virtex2.c
+++ b/drivers/fpga/virtex2.c
@@ -247,6 +247,7 @@  static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
 			      int cookie)
 {
 	int ret_val = FPGA_SUCCESS;
+	int num_done = 0;
 	unsigned long ts;
 
 	/*
@@ -264,12 +265,18 @@  static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
 
 	/*
 	 * Check for successful configuration.  FPGA INIT_B and DONE
-	 * should both be high upon successful configuration.
+	 * should both be high upon successful configuration. Continue pulsing
+	 * clock with data set to all ones until DONE is asserted and for 8
+	 * clock cycles afterwards.
 	 */
 	ts = get_timer(0);
-	ret_val = FPGA_SUCCESS;
-	while (((*fn->done)(cookie) == FPGA_FAIL) ||
-	       (*fn->init)(cookie)) {
+	while (true) {
+		if ((*fn->done)(cookie) == FPGA_SUCCESS &&
+		    !((*fn->init)(cookie))) {
+			if (num_done++ >= 8)
+				break;
+		}
+
 		if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) {
 			printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n",
 			       __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG);
@@ -277,6 +284,11 @@  static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
 			ret_val = FPGA_FAIL;
 			break;
 		}
+		(*fn->wdata) (0xff, true, cookie);
+		CONFIG_FPGA_DELAY();
+		(*fn->clk) (false, true, cookie);
+		CONFIG_FPGA_DELAY();
+		(*fn->clk) (true, true, cookie);
 	}
 
 	if (ret_val == FPGA_SUCCESS) {