All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Vasut <marex@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/2] mtd: cqspi: Simplify indirect write code
Date: Tue, 03 May 2016 12:46:22 +0200	[thread overview]
Message-ID: <5728817E.7050507@denx.de> (raw)
In-Reply-To: <20160503104250.GD6917@amd>

On 05/03/2016 12:42 PM, Pavel Machek wrote:
> Hi!
> 
>> This patch replaces the whole unmaintainable indirect write implementation
>> with the one from upcoming Linux CQSPI driver, which went through multiple
>> rounds of thorough review and testing. While this makes the patch look
>> terrifying and violates all best-practices of software development,
>> all
> 
> Could we get something less terifying and less violating? :-).
> 
>> the patch does is it plucks out duplicate ad-hoc code distributed across
>> the driver and replaces it with more compact code doing exactly the same
>> thing.
> 
> So this one is just a cleanup, and no behaviour change yet?

Apparently Stefan discovered one behavior change, which I need to look
into. Apparently, u-boot can pass unaligned buffer to the driver, which
can cause problems.

> 								Pavel
> 
>> ---
>>  drivers/spi/cadence_qspi_apb.c | 122 +++++++++--------------------------------
>>  1 file changed, 26 insertions(+), 96 deletions(-)
>>
>> diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
>> index 7786dd6..00a50cb 100644
>> --- a/drivers/spi/cadence_qspi_apb.c
>> +++ b/drivers/spi/cadence_qspi_apb.c
>> @@ -28,6 +28,7 @@
>>  #include <common.h>
>>  #include <asm/io.h>
>>  #include <asm/errno.h>
>> +#include <wait_bit.h>
>>  #include "cadence_qspi.h"
>>  
>>  #define CQSPI_REG_POLL_US			(1) /* 1us */
>> @@ -214,32 +215,6 @@ static void cadence_qspi_apb_read_fifo_data(void *dest,
>>  	return;
>>  }
>>  
>> -static void cadence_qspi_apb_write_fifo_data(const void *dest_ahb_addr,
>> -	const void *src, unsigned int bytes)
>> -{
>> -	unsigned int temp = 0;
>> -	int i;
>> -	int remaining = bytes;
>> -	unsigned int *dest_ptr = (unsigned int *)dest_ahb_addr;
>> -	unsigned int *src_ptr = (unsigned int *)src;
>> -
>> -	while (remaining >= CQSPI_FIFO_WIDTH) {
>> -		for (i = CQSPI_FIFO_WIDTH/sizeof(src_ptr) - 1; i >= 0; i--)
>> -			writel(*(src_ptr+i), dest_ptr+i);
>> -		src_ptr += CQSPI_FIFO_WIDTH/sizeof(src_ptr);
>> -		remaining -= CQSPI_FIFO_WIDTH;
>> -	}
>> -	if (remaining) {
>> -		/* dangling bytes */
>> -		i = remaining/sizeof(dest_ptr);
>> -		memcpy(&temp, src_ptr+i, remaining % sizeof(dest_ptr));
>> -		writel(temp, dest_ptr+i);
>> -		for (--i; i >= 0; i--)
>> -			writel(*(src_ptr+i), dest_ptr+i);
>> -	}
>> -	return;
>> -}
>> -
>>  /* Read from SRAM FIFO with polling SRAM fill level. */
>>  static int qspi_read_sram_fifo_poll(const void *reg_base, void *dest_addr,
>>  			const void *src_addr,  unsigned int num_bytes)
>> @@ -276,44 +251,6 @@ static int qspi_read_sram_fifo_poll(const void *reg_base, void *dest_addr,
>>  	return 0;
>>  }
>>  
>> -/* Write to SRAM FIFO with polling SRAM fill level. */
>> -static int qpsi_write_sram_fifo_push(struct cadence_spi_platdata *plat,
>> -				const void *src_addr, unsigned int num_bytes)
>> -{
>> -	const void *reg_base = plat->regbase;
>> -	void *dest_addr = plat->ahbbase;
>> -	unsigned int retry = CQSPI_REG_RETRY;
>> -	unsigned int sram_level;
>> -	unsigned int wr_bytes;
>> -	unsigned char *src = (unsigned char *)src_addr;
>> -	int remaining = num_bytes;
>> -	unsigned int page_size = plat->page_size;
>> -	unsigned int sram_threshold_words = CQSPI_REG_SRAM_THRESHOLD_WORDS;
>> -
>> -	while (remaining > 0) {
>> -		retry = CQSPI_REG_RETRY;
>> -		while (retry--) {
>> -			sram_level = CQSPI_GET_WR_SRAM_LEVEL(reg_base);
>> -			if (sram_level <= sram_threshold_words)
>> -				break;
>> -		}
>> -		if (!retry) {
>> -			printf("QSPI: SRAM fill level (0x%08x) not hit lower expected level (0x%08x)",
>> -			       sram_level, sram_threshold_words);
>> -			return -1;
>> -		}
>> -		/* Write a page or remaining bytes. */
>> -		wr_bytes = (remaining > page_size) ?
>> -					page_size : remaining;
>> -
>> -		cadence_qspi_apb_write_fifo_data(dest_addr, src, wr_bytes);
>> -		src += wr_bytes;
>> -		remaining -= wr_bytes;
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>>  void cadence_qspi_apb_controller_enable(void *reg_base)
>>  {
>>  	unsigned int reg;
>> @@ -810,48 +747,41 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
>>  }
>>  
>>  int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
>> -	unsigned int txlen, const u8 *txbuf)
>> +	unsigned int n_tx, const u8 *txbuf)
>>  {
>> -	unsigned int reg = 0;
>> -	unsigned int retry;
>> +	unsigned int page_size = plat->page_size;
>> +	unsigned int remaining = n_tx;
>> +	unsigned int write_bytes;
>> +	int ret;
>>  
>>  	/* Configure the indirect read transfer bytes */
>> -	writel(txlen, plat->regbase + CQSPI_REG_INDIRECTWRBYTES);
>> +	writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES);
>>  
>>  	/* Start the indirect write transfer */
>>  	writel(CQSPI_REG_INDIRECTWR_START_MASK,
>>  	       plat->regbase + CQSPI_REG_INDIRECTWR);
>>  
>> -	if (qpsi_write_sram_fifo_push(plat, (const void *)txbuf, txlen))
>> -		goto failwr;
>> -
>> -	/* Wait until last write is completed (FIFO empty) */
>> -	retry = CQSPI_REG_RETRY;
>> -	while (retry--) {
>> -		reg = CQSPI_GET_WR_SRAM_LEVEL(plat->regbase);
>> -		if (reg == 0)
>> -			break;
>> -
>> -		udelay(1);
>> -	}
>> -
>> -	if (reg != 0) {
>> -		printf("QSPI: timeout for indirect write\n");
>> -		goto failwr;
>> -	}
>> +	while (remaining > 0) {
>> +		write_bytes = remaining > page_size ? page_size : remaining;
>> +		writesl(plat->ahbbase, txbuf, DIV_ROUND_UP(write_bytes, 4));
>> +
>> +		ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL,
>> +				   CQSPI_REG_SDRAMLEVEL_WR_MASK <<
>> +				   CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
>> +		if (ret) {
>> +			printf("Indirect write timed out (%i)\n", ret);
>> +			goto failwr;
>> +		}
>>  
>> -	/* Check flash indirect controller status */
>> -	retry = CQSPI_REG_RETRY;
>> -	while (retry--) {
>> -		reg = readl(plat->regbase + CQSPI_REG_INDIRECTWR);
>> -		if (reg & CQSPI_REG_INDIRECTWR_DONE_MASK)
>> -			break;
>> -		udelay(1);
>> +		txbuf += write_bytes;
>> +		remaining -= write_bytes;
>>  	}
>>  
>> -	if (!(reg & CQSPI_REG_INDIRECTWR_DONE_MASK)) {
>> -		printf("QSPI: indirect completion status error with reg 0x%08x\n",
>> -		       reg);
>> +	/* Check indirect done status */
>> +	ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTWR,
>> +			   CQSPI_REG_INDIRECTWR_DONE_MASK, 1, 10, 0);
>> +	if (ret) {
>> +		printf("Indirect write completion error (%i)\n", ret);
>>  		goto failwr;
>>  	}
>>  
>> @@ -864,7 +794,7 @@ failwr:
>>  	/* Cancel the indirect write */
>>  	writel(CQSPI_REG_INDIRECTWR_CANCEL_MASK,
>>  	       plat->regbase + CQSPI_REG_INDIRECTWR);
>> -	return -1;
>> +	return ret;
>>  }
>>  
>>  void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy)
> 


-- 
Best regards,
Marek Vasut

      reply	other threads:[~2016-05-03 10:46 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-27 22:36 [U-Boot] [PATCH 1/2] mtd: cqspi: Simplify indirect write code Marek Vasut
2016-04-27 22:36 ` [U-Boot] [PATCH 2/2] mtd: cqspi: Simplify indirect read code Marek Vasut
2016-04-29  6:03 ` [U-Boot] [PATCH 1/2] mtd: cqspi: Simplify indirect write code Vignesh R
2016-04-29  9:35 ` Stefan Roese
2016-04-29 10:13   ` Marek Vasut
2016-05-02 15:20     ` Stefan Roese
2016-05-03 16:53       ` Marek Vasut
2016-05-03 17:00         ` Stefan Roese
2016-05-03 17:18           ` Marek Vasut
2016-05-04  8:59             ` Stefan Roese
2016-05-03 10:42 ` Pavel Machek
2016-05-03 10:46   ` Marek Vasut [this message]

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=5728817E.7050507@denx.de \
    --to=marex@denx.de \
    --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.