All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Roese <sr@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/2] mtd: cqspi: Simplify indirect write code
Date: Mon, 2 May 2016 17:20:06 +0200	[thread overview]
Message-ID: <57277026.9010105@denx.de> (raw)
In-Reply-To: <572333C6.1060801@denx.de>

On 29.04.2016 12:13, Marek Vasut wrote:
>> On 28.04.2016 00:36, Marek Vasut wrote:
>>> The indirect write code is buggy pile of nastiness which fails horribly
>>> when the system runs fast enough to saturate the controller. The failure
>>> results in some pages (256B) not being written to the flash. This can be
>>> observed on systems which run with Dcache enabled and L2 cache enabled,
>>> like the Altera SoCFPGA.
>>>
>>> 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
>>> 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.
>>>
>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>> Cc: Anatolij Gustschin <agust@denx.de>
>>> Cc: Chin Liang See <clsee@altera.com>
>>> Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
>>> Cc: Jagan Teki <jteki@openedev.com>
>>> Cc: Pavel Machek <pavel@denx.de>
>>> Cc: Stefan Roese <sr@denx.de>
>>> Cc: Vignesh R <vigneshr@ti.com>
>>
>> I've applied both patches and tested them on SR1500 (SPI-NOR used
>> for booting and redundant environment). This is what I get upon
>> "saveeenv":
>>
>> => saveenv
>> Saving Environment to SPI Flash...
>> SF: Detected N25Q128 with page size 256 Bytes, erase size 64 KiB, total 16 MiB
>> Erasing SPI flash...Writing to SPI flash...data abort
>> pc : [<3ff8368a>]          lr : [<3ff8301b>]
>> reloc pc : [<010216ca>]    lr : [<0102105b>]
>> sp : 3bf54eb8  ip : 3ff82f69     fp : 00000002
>> r10: 00000000  r9 : 3bf5dee8     r8 : ffff0000
>> r7 : 00000001  r6 : 3bf54f9b     r5 : 00000001  r4 : 3bf5e520
>> r3 : 00000000  r2 : 3bf54f9b     r1 : 00000001  r0 : ffa00000
>> Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
>> Resetting CPU ...
>>
>> resetting ...
>>
>> U-Boot SPL 2016.05-rc3-00009-ge1bf9b8 (Apr 29 2016 - 11:25:46)
>>
>>
>> Any idea, what might be going wrong here?
> 
> Does it work without the patch ?

Yes, of course. I wouldn't have posted as a reply to this patch
if this is not the root cause. The board is using SPI NOR
for env storage from the beginning.

 Where does your PC point to at the time
> of the crash ,which function is it ?

Its in cadence_qspi_apb_indirect_write_execute().

I debugged this issue a bit and found the following problem
in cadence_qspi_apb_indirect_write_execute():

saveenv issues a 1-byte SPI write transfer with a non 4-byte
aligned txbuf. This causes the data-abort here. Here my small
patch that fixes the problem:

diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index ac47c6f..021a3e8 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -745,7 +745,15 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
 
        while (remaining > 0) {
                write_bytes = remaining > page_size ? page_size : remaining;
-               writesl(plat->ahbbase, txbuf, DIV_ROUND_UP(write_bytes, 4));
+
+               /*
+                * Handle non 4-byte aligned access differently to avoid
+                * data-aborts
+                */
+               if (((u32)txbuf % 4) || (write_bytes % 4))
+                       writesb(plat->ahbbase, txbuf, write_bytes);
+               else
+                       writesl(plat->ahbbase, txbuf, write_bytes >> 2);
 
                ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL,
                                   CQSPI_REG_SDRAMLEVEL_WR_MASK <<


Please fell free to use this patch as-is and squash it into
your patches or enhance it while doing this. The read function
is also missing this unaligned handling. And of course the
Linux driver version as well.

Thanks,
Stefan

  reply	other threads:[~2016-05-02 15:20 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 [this message]
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

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=57277026.9010105@denx.de \
    --to=sr@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.