| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
06781a5026350 Fixes the calculation of the DEVICE_BUSY_TIMEOUT register
value from busy_timeout_cycles. busy_timeout_cycles is calculated wrong
though: It is calculated based on the maximum page read time, but the
timeout is also used for page write and block erase operations which
require orders of magnitude bigger timeouts.
Fix this by calculating busy_timeout_cycles from the maximum of
tBERS_max and tPROG_max.
This is for now the easiest and most obvious way to fix the driver.
There's room for improvements though: The NAND_OP_WAITRDY_INSTR tells us
the desired timeout for the current operation, so we could program the
timeout dynamically for each operation instead of setting a fixed
timeout. Also we could wire up the interrupt handler to actually detect
and forward timeouts occurred when waiting for the chip being ready.
As a sidenote I verified that the change in 06781a5026350 is really
correct. I wired up the interrupt handler in my tree and measured the
time between starting the operation and the timeout interrupt handler
coming in. The time increases 41us with each step in the timeout
register which corresponds to 4096 clock cycles with the 99MHz clock
that I have.
Fixes: 06781a5026350 ("mtd: rawnand: gpmi: Fix setting busy timeout setting")
Fixes: b1206122069aa ("mtd: rawniand: gpmi: use core timings instead of an empirical derivation")
Cc: stable@vger.kernel.org
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Han Xu <han.xu@nxp.com>
Tested-by: Tomasz Moń <tomasz.mon@camlingroup.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The DEVICE_BUSY_TIMEOUT value is described in the Reference Manual as:
| Timeout waiting for NAND Ready/Busy or ATA IRQ. Used in WAIT_FOR_READY
| mode. This value is the number of GPMI_CLK cycles multiplied by 4096.
So instead of multiplying the value in cycles with 4096, we have to
divide it by that value. Use DIV_ROUND_UP to make sure we are on the
safe side, especially when the calculated value in cycles is smaller
than 4096 as typically the case.
This bug likely never triggered because any timeout != 0 usually will
do. In my case the busy timeout in cycles was originally calculated as
2408, which multiplied with 4096 is 0x968000. The lower 16 bits were
taken for the 16 bit wide register field, so the register value was
0x8000. With 2970bf5a32f0 ("mtd: rawnand: gpmi: fix controller timings
setting") however the value in cycles became 2384, which multiplied
with 4096 is 0x950000. The lower 16 bit are 0x0 now resulting in an
intermediate timeout when reading from NAND.
Fixes: b1206122069aa ("mtd: rawnand: gpmi: use core timings instead of an empirical derivation")
Cc: stable@vger.kernel.org
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220614083138.3455683-1-s.hauer@pengutronix.de
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The code change proposes a new way to set bch geometry for large oob
NAND (oobsize > 1KB). In this case, previous implementation can NOT
guarantee the bad block mark always locates in data chunk, so we need a
new way to do it. The general idea is,
1.Try all ECC strength from the maximum ecc that controller can support
to minimum value required by NAND chip, any ECC strength makes the
BBM locate in data chunk can be eligible.
2.If none of them works, using separate ECC for meta, which will add
one extra ecc with the same ECC strength as other data chunks. This
extra ECC can guarantee BBM located in data chunk, also we need to
check if oob can afford it.
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220412025246.24269-6-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There is only one variable ecc_chunk_size in bch_geometry data
structure but two different field in BCH registers. The data0_size in
BCH_FLASH0LAYOUT0 and datan_size in BCH_FLASH0LAYOUT1 should have
dedicate variable since they might set to different values in some
cases. For instance, if need dedicate ecc for meta area, the data0_size
should be 0 rather than datan_size, but for all other cases, data0_size
still equals to datan_size and it won't bring any function change.
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220412025246.24269-5-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
| |
The gpmi_check_ecc() is not small after adding more strict ecc check,
uninline it.
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220412025246.24269-4-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
| |
Add nand_ecc_is_strong_enough() check in gpmi_check_ecc() function to
make sure ecc strength can meet chip requirement.
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220412025246.24269-3-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The code change refactor the bch geometry setting function, which
doesn't change the default behavior, while user may choose to use chips
required minimum ecc strength by DT flag "fsl,use-minimum-ecc".
The default way to set bch geometry need to set the data chunk
size(step_size) larger than oob size to make sure BBM locates in data
chunk, then set the maximum ecc strength oob can hold. It always use
unbalanced ECC layout, which ecc0 will cover both meta and data0 chunk.
But the default bch setting is deprecated for large oobsize NAND
(oobsize >1KB), so in the patch set, there is a split commit that
introduces a new way to set bch geometry for large oob size NAND.
For all other cases,set the bch geometry by chip required strength and
step size, which uses the minimum ecc strength chip required. It can be
explicitly enabled by DT flag "fsl,use-minimum-ecc", but need to be
en/disabled in both u-boot and kernel at the same time.
Signed-off-by: Han Xu <han.xu@nxp.com>
Tested-by: Sean Nyekjaer <sean@geanix.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220412025246.24269-2-han.xu@nxp.com
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Raw NAND core changes:
* Rework of_get_nand_bus_width()
* Remove of_get_nand_on_flash_bbt() wrapper
* Protect access to rawnand devices while in suspend
* bindings: Document the wp-gpios property
Rax NAND controller driver changes:
* atmel: Fix refcount issue in atmel_nand_controller_init
* nandsim:
- Add NS_PAGE_BYTE_SHIFT macro to replace the repeat pattern
- Merge repeat codes in ns_switch_state
- Replace overflow check with kzalloc to single kcalloc
* rockchip: Fix platform_get_irq.cocci warning
* stm32_fmc2: Add NAND Write Protect support
* pl353: Set the nand chip node as the flash node
* brcmnand: Fix sparse warnings in bcma_nand
* omap_elm: Remove redundant variable 'errors'
* gpmi:
- Support fast edo timings for mx28
- Validate controller clock rate
- Fix controller timings setting
* brcmnand:
- Add BCMA shim
- BCMA controller uses command shift of 0
- Allow platform data instantation
- Add platform data structure for BCMA
- Allow working without interrupts
- Move OF operations out of brcmnand_init_cs()
- Avoid pdev in brcmnand_init_cs()
- Allow SoC to provide I/O operations
- Assign soc as early as possible
Onenand changes:
* Check for error irq
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
In the i.MX28 manual (MCIMX28RM, Rev. 1, 2010) you can find an example
(15.2.4 High-Speed NAND Timing) of how to configure the GPMI controller
to manage High-Speed NAND devices, so it was wrong to assume that only
i.MX6 can achieve EDO timings.
This patch has been tested on a 2048/64 byte NAND (Micron MT29F2G08ABAEAH4).
Kernel mtd tests:
- mtd_nandbiterrs
- mtd_nandecctest
- mtd_oobtest
- mtd_pagetest
- mtd_readtest
- mtd_speedtest
- mtd_stresstest
- mtd_subpagetest
- mtd_torturetest [cycles_count = 10000000]
run without errors.
Before this patch (mode 0):
---------------------------
eraseblock write speed is 2098 KiB/s
eraseblock read speed is 2680 KiB/s
page write speed is 1689 KiB/s
page read speed is 2522 KiB/s
2 page write speed is 1899 KiB/s
2 page read speed is 2579 KiB/s
erase speed is 128000 KiB/s
2x multi-block erase speed is 73142 KiB/s
4x multi-block erase speed is 204800 KiB/s
8x multi-block erase speed is 256000 KiB/s
16x multi-block erase speed is 256000 KiB/s
32x multi-block erase speed is 256000 KiB/s
64x multi-block erase speed is 256000 KiB/s
After this patch (mode 5):
-------------------------
eraseblock write speed is 3390 KiB/s
eraseblock read speed is 5688 KiB/s
page write speed is 2680 KiB/s
page read speed is 4876 KiB/s
2 page write speed is 2909 KiB/s
2 page read speed is 5224 KiB/s
erase speed is 170666 KiB/s
2x multi-block erase speed is 204800 KiB/s
4x multi-block erase speed is 256000 KiB/s
8x multi-block erase speed is 256000 KiB/s
16x multi-block erase speed is 256000 KiB/s
32x multi-block erase speed is 256000 KiB/s
64x multi-block erase speed is 256000 KiB/s
Co-developed-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-5-dario.binacchi@amarulasolutions.com
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
What to do when the real rate of the gpmi clock is not equal to the
required one? The solutions proposed in [1] did not lead to a conclusion
on how to validate the clock rate, so, inspired by the document [2], I
consider the rate correct only if not lower or equal to the rate of the
previous edo mode. In fact, in chapter 4.16.2 (NV-DDR) of the document [2],
it is written that "If the host selects timing mode n, then its clock
period shall be faster than the clock period of timing mode n-1 and
slower than or equal to the clock period of timing mode n.". I thought
that it could therefore also be used in this case, without therefore
having to define the valid rate ranges empirically.
For example, suppose that gpmi_nfc_compute_timings() is called to set
edo mode 5 (100MHz) but the rate returned by clk_round_rate() is 80MHz
(edo mode 4). In this case gpmi_nfc_compute_timings() will return error,
and will be called again to set edo mode 4, which this time will be
successful.
[1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers@kernel.org
[2] http://www.onfi.org/-/media/client/onfi/specs/onfi_3_0_gold.pdf?la=en
Co-developed-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-4-dario.binacchi@amarulasolutions.com
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Set the controller registers according to the real clock rate. The
controller registers configuration (setup, hold, timeout, ... cycles)
depends on the clock rate of the GPMI. Using the real rate instead of
the ideal one, avoids that this inaccuracy (required_rate - real_rate)
affects the registers setting.
This patch has been tested on two custom boards with i.MX28 and i.MX6
SOCs:
- i.MX28:
required rate 100MHz, real rate 99.3MHz
- i.MX6
required rate 100MHz, real rate 99MHz
Fixes: b1206122069a ("mtd: rawnand: gpmi: use core timings instead of an empirical derivation")
Co-developed-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220118095434.35081-3-dario.binacchi@amarulasolutions.com
|
|/
|
|
|
|
|
|
|
|
|
|
| |
If gpmi_nfc_apply_timings() fails, the PM runtime usage counter must be
dropped.
Reported-by: Pavel Machek <pavel@denx.de>
Fixes: f53d4c109a66 ("mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings")
Signed-off-by: Christian Eggers <ceggers@arri.de>
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220125081619.6286-1-ceggers@arri.de
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
platform_get_resource_byname(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.
In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq_byname().
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20211221212609.31290-3-prabhakar.mahadev-lad.rj@bp.renesas.com
|
|
|
|
|
|
|
|
|
| |
Return status directly from function called.
Reported-by: Zeal Robot <zealci@zte.com.cn>
Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20211213112627.436745-1-chi.minghao@zte.com.cn
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
gpmi_io clock needs to be gated off when changing the parent/dividers of
enfc_clk_root (i.MX6Q/i.MX6UL) respectively qspi2_clk_root (i.MX6SX).
Otherwise this rate change can lead to an unresponsive GPMI core which
results in DMA timeouts and failed driver probe:
[ 4.072318] gpmi-nand 112000.gpmi-nand: DMA timeout, last DMA
...
[ 4.370355] gpmi-nand 112000.gpmi-nand: Chip: 0, Error -110
...
[ 4.375988] gpmi-nand 112000.gpmi-nand: Chip: 0, Error -22
[ 4.381524] gpmi-nand 112000.gpmi-nand: Error in ECC-based read: -22
[ 4.387988] gpmi-nand 112000.gpmi-nand: Chip: 0, Error -22
[ 4.393535] gpmi-nand 112000.gpmi-nand: Chip: 0, Error -22
...
Other than stated in i.MX 6 erratum ERR007117, it should be sufficient
to gate only gpmi_io because all other bch/nand clocks are derived from
different clock roots.
The i.MX6 reference manuals state that changing clock muxers can cause
glitches but are silent about changing dividers. But tests showed that
these glitches can definitely happen on i.MX6ULL. For i.MX7D/8MM in turn,
the manual guarantees that no glitches can happen when changing
dividers.
Co-developed-by: Stefan Riedmueller <s.riedmueller@phytec.de>
Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
Signed-off-by: Christian Eggers <ceggers@arri.de>
Cc: stable@vger.kernel.org
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20211102202022.15551-2-ceggers@arri.de
|
|
|
|
|
|
|
|
|
|
|
| |
There is no need to explicitly set the default gpmi clock rate during
boot for the i.MX 6 since this is done during nand_detect anyway.
Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
Cc: stable@vger.kernel.org
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20211102202022.15551-1-ceggers@arri.de
|
|
|
|
|
|
|
|
|
|
|
|
| |
devm_platform_ioremap_resource_byname()
Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately
Signed-off-by: Cai Huoqing <caihuoqing@baidu.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210901074130.9083-1-caihuoqing@baidu.com
|
|
|
|
|
|
|
|
|
|
| |
In particular, first ONFI specifications referred to SDR modes as
asynchronous modes, which is not the term we usually have in mind. The
spec has then been updated, so do the same here in the NAND subsystem to
avoid any possible confusion.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-7-miquel.raynal@bootlin.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the callee gpmi_alloc_dma_buffer() failed to alloc memory for
this->raw_buffer, gpmi_free_dma_buffer() will be called to free
this->auxiliary_virt. But this->auxiliary_virt is still a non-NULL
and valid ptr.
Then gpmi_alloc_dma_buffer() returns err and gpmi_free_dma_buffer()
is called again to free this->auxiliary_virt in err_out. This causes
a double free.
As gpmi_free_dma_buffer() has already called in gpmi_alloc_dma_buffer's
error path, so it should return err directly instead of releasing the dma
buffer again.
Fixes: 4d02423e9afe6 ("mtd: nand: gpmi: Fix gpmi_nand_init() error path")
Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210403060905.5251-1-lyl2019@mail.ustc.edu.cn
|
|
|
|
|
|
|
|
|
|
|
|
| |
Re-add the multiply by 8 to "step * eccsize" to correct the destination bit offset
when extracting the data payload in gpmi_ecc_read_page_raw().
Fixes: e5e5631cc889 ("mtd: rawnand: gpmi: Use nand_extract_bits()")
Cc: stable@vger.kernel.org
Reported-by: Martin Hundebøll <martin@geanix.com>
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201221100013.2715675-1-sean@geanix.com
|
|
|
|
|
|
|
|
|
| |
The .compatible and .data pairs can be stored in a single line, which
makes the code more concise.
Signed-off-by: Fabio Estevam <festevam@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201208221243.3255-1-festevam@gmail.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To get better performance, current gpmi driver collected and chained all
small DMA transfers in gpmi_nfc_exec_op, the whole chain triggered and
wait for complete at the end.
But some random DMA timeout found in this new driver, with the help of
ftrace, we found the root cause is as follows:
Take gpmi_ecc_read_page() as an example, gpmi_nfc_exec_op collected 6
DMA transfers and the DMA chain triggered at the end. It waits for bch
completion and check jiffies if it's timeout. The typical function graph
shown below,
63.216351 | 1) | gpmi_ecc_read_page() {
63.216352 | 1) 0.750 us | gpmi_bch_layout_std();
63.216354 | 1) | gpmi_nfc_exec_op() {
63.216355 | 1) | gpmi_chain_command() {
63.216356 | 1) | mxs_dma_prep_slave_sg() {
63.216357 | 1) | /* mxs chan ccw idx: 0 */
63.216358 | 1) 1.750 us | }
63.216359 | 1) | mxs_dma_prep_slave_sg() {
63.216360 | 1) | /* mxs chan ccw idx: 1 */
63.216361 | 1) 2.000 us | }
63.216361 | 1) 6.500 us | }
63.216362 | 1) | gpmi_chain_command() {
63.216363 | 1) | mxs_dma_prep_slave_sg() {
63.216364 | 1) | /* mxs chan ccw idx: 2 */
63.216365 | 1) 1.750 us | }
63.216366 | 1) | mxs_dma_prep_slave_sg() {
63.216367 | 1) | /* mxs chan ccw idx: 3 */
63.216367 | 1) 1.750 us | }
63.216368 | 1) 5.875 us | }
63.216369 | 1) | /* gpmi_chain_wait_ready */
63.216370 | 1) | mxs_dma_prep_slave_sg() {
63.216372 | 1) | /* mxs chan ccw idx: 4 */
63.216373 | 1) 3.000 us | }
63.216374 | 1) | /* gpmi_chain_data_read */
63.216376 | 1) | mxs_dma_prep_slave_sg() {
63.216377 | 1) | /* mxs chan ccw idx: 5 */
63.216378 | 1) 2.000 us | }
63.216379 | 1) 1.125 us | mxs_dma_tx_submit();
63.216381 | 1) 1.000 us | mxs_dma_enable_chan();
63.216712 | 0) 2.625 us | mxs_dma_int_handler();
63.216717 | 0) 4.250 us | bch_irq();
63.216723 | 0) 1.250 us | mxs_dma_tasklet();
63.216723 | 1) | /* jiffies left 250 */
63.216725 | 1) ! 372.000 us | }
63.216726 | 1) 2.625 us | gpmi_count_bitflips();
63.216730 | 1) ! 379.125 us | }
but it's not gurantee that bch irq handled always after dma irq handled,
sometimes bch_irq comes first and gpmi_nfc_exec_op won't wait anymore,
another gpmi_nfc_exec_op may get invoked before last DMA chain IRQ
handled, this messed up the next DMA chain and causes DMA timeout. Check
the trace log when issue happened.
63.218923 | 1) | gpmi_ecc_read_page() {
63.218924 | 1) 0.625 us | gpmi_bch_layout_std();
63.218926 | 1) | gpmi_nfc_exec_op() {
63.218927 | 1) | gpmi_chain_command() {
63.218928 | 1) | mxs_dma_prep_slave_sg() {
63.218929 | 1) | /* mxs chan ccw idx: 0 */
63.218929 | 1) 1.625 us | }
63.218931 | 1) | mxs_dma_prep_slave_sg() {
63.218931 | 1) | /* mxs chan ccw idx: 1 */
63.218932 | 1) 1.750 us | }
63.218933 | 1) 5.875 us | }
63.218934 | 1) | gpmi_chain_command() {
63.218934 | 1) | mxs_dma_prep_slave_sg() {
63.218935 | 1) | /* mxs chan ccw idx: 2 */
63.218936 | 1) 1.875 us | }
63.218937 | 1) | mxs_dma_prep_slave_sg() {
63.218938 | 1) | /* mxs chan ccw idx: 3 */
63.218939 | 1) 1.625 us | }
63.218939 | 1) 5.875 us | }
63.218940 | 1) | /* gpmi_chain_wait_ready */
63.218941 | 1) | mxs_dma_prep_slave_sg() {
63.218942 | 1) | /* mxs chan ccw idx: 4 */
63.218942 | 1) 1.625 us | }
63.218943 | 1) | /* gpmi_chain_data_read */
63.218944 | 1) | mxs_dma_prep_slave_sg() {
63.218945 | 1) | /* mxs chan ccw idx: 5 */
63.218947 | 1) 2.375 us | }
63.218948 | 1) 0.625 us | mxs_dma_tx_submit();
63.218949 | 1) 1.000 us | mxs_dma_enable_chan();
63.219276 | 0) 5.125 us | bch_irq(); <----
63.219283 | 1) | /* jiffies left 250 */
63.219285 | 1) ! 358.625 us | }
63.219286 | 1) 2.750 us | gpmi_count_bitflips();
63.219289 | 1) ! 366.000 us | }
63.219290 | 1) | gpmi_ecc_read_page() {
63.219291 | 1) 0.750 us | gpmi_bch_layout_std();
63.219293 | 1) | gpmi_nfc_exec_op() {
63.219294 | 1) | gpmi_chain_command() {
63.219295 | 1) | mxs_dma_prep_slave_sg() {
63.219295 | 0) 1.875 us | mxs_dma_int_handler(); <----
63.219296 | 1) | /* mxs chan ccw idx: 6 */
63.219297 | 1) 2.250 us | }
63.219298 | 1) | mxs_dma_prep_slave_sg() {
63.219298 | 0) 1.000 us | mxs_dma_tasklet();
63.219299 | 1) | /* mxs chan ccw idx: 0 */
63.219300 | 1) 1.625 us | }
63.219300 | 1) 6.375 us | }
63.219301 | 1) | gpmi_chain_command() {
63.219302 | 1) | mxs_dma_prep_slave_sg() {
63.219303 | 1) | /* mxs chan ccw idx: 1 */
63.219304 | 1) 1.625 us | }
63.219305 | 1) | mxs_dma_prep_slave_sg() {
63.219306 | 1) | /* mxs chan ccw idx: 2 */
63.219306 | 1) 1.875 us | }
63.219307 | 1) 6.000 us | }
63.219308 | 1) | /* gpmi_chain_wait_ready */
63.219308 | 1) | mxs_dma_prep_slave_sg() {
63.219309 | 1) | /* mxs chan ccw idx: 3 */
63.219310 | 1) 2.000 us | }
63.219311 | 1) | /* gpmi_chain_data_read */
63.219312 | 1) | mxs_dma_prep_slave_sg() {
63.219313 | 1) | /* mxs chan ccw idx: 4 */
63.219314 | 1) 1.750 us | }
63.219315 | 1) 0.625 us | mxs_dma_tx_submit();
63.219316 | 1) 0.875 us | mxs_dma_enable_chan();
64.224227 | 1) | /* jiffies left 0 */
In the first gpmi_nfc_exec_op, bch_irq comes first and gpmi_nfc_exec_op
exits, but DMA IRQ still not happened yet until the middle of following
gpmi_nfc_exec_op, the first DMA transfer index get messed and DMA get
timeout.
To fix the issue, when there is bch ops in DMA chain, the
gpmi_nfc_exec_op should wait for both completions rather than bch
completion only.
Fixes: ef347c0cfd61 ("mtd: rawnand: gpmi: Implement exec_op")
Signed-off-by: Han Xu <han.xu@nxp.com>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201209035104.22679-3-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Set the GPMI CTRL1 GANGED_RDYBUSY bit so driver can sense the R/B signal
from all CS.
For the NAND chip MT29F64G08AFAAAWP, only the first chip detected
without the patch.
[ 3.764118] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0x68
[ 3.770613] nand: Micron MT29F64G08AFAAAWP
[ 3.774752] nand: 4096 MiB, SLC, erase size: 1024 KiB, page size: 8192, OOB size: 448
[ 3.786421] Bad block table found at page 524160, version 0x01
[ 3.792730] Bad block table found at page 524032, version 0x01
After applying the patch
[ 3.764445] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0x68
[ 3.770941] nand: Micron MT29F64G08AFAAAWP
[ 3.775080] nand: 4096 MiB, SLC, erase size: 1024 KiB, page size: 8192, OOB size: 448
[ 3.784390] nand: 2 chips detected
[ 3.790900] Bad block table found at page 524160, version 0x01
[ 3.796776] Bad block table found at page 1048448, version 0x01
Signed-off-by: Han Xu <han.xu@nxp.com>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201209035104.22679-2-han.xu@nxp.com
|
|
|
|
|
|
|
|
|
|
|
| |
The retrieval of driver data via of_device_get_match_data() can make
the code simpler.
Use of_device_get_match_data() to simplify the code.
Signed-off-by: Fabio Estevam <festevam@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201126030946.2058-1-festevam@gmail.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
pm_runtime_get_sync() will increment pm usage at first and it
will resume the device later. If runtime of the device has
error or device is in inaccessible state(or other error state),
resume operation will fail. If we do not call put operation to
decrease the reference, it will result in reference leak in
the two functions(gpmi_init and gpmi_nfc_exec_op). Moreover,
this device cannot enter the idle state and always stay busy or
other non-idle state later. So we fixed it through adding
pm_runtime_put_noidle.
Fixes: 5bc6bb603b4d0 ("mtd: rawnand: gpmi: Fix suspend/resume problem")
Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201107110552.1568742-1-zhangqilong3@huawei.com
|
|
|
|
|
|
|
|
|
|
| |
The extra gpmi_nand.o object is not needed anymore since
commit 3045f8e36963 ("mtd: rawnand: gpmi: move all driver
code into single file").
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201007134533.31390-1-m.felsch@pengutronix.de
|
|
|
|
|
|
|
|
|
| |
Common pattern of handling deferred probe can be simplified with
dev_err_probe(). Less code and the error value gets printed.
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200901142535.12819-3-krzk@kernel.org
|
|
|
|
|
|
|
| |
Instead of accessing ->strength/step_size directly.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200827085208.16276-15-miquel.raynal@bootlin.com
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mechanical switch from the legacy "mode" enumeration to the new
"engine type" enumeration in drivers and board files.
The device tree parsing is also updated to return the new enumeration
from the old strings.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200827085208.16276-11-miquel.raynal@bootlin.com
|
|
|
|
|
|
|
|
|
|
| |
The name/suffix data_interface is a bit misleading in that the field
or functions actually represent a configuration that can be applied by
the controller/chip. Let's rename all fields/functions/hooks that are
worth renaming.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
| |
Drop the use of gpmi_copy_bits() in favor of the NAND helper
nand_extract_bits().
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200508171805.8627-1-miquel.raynal@bootlin.com
|
|
|
|
|
|
|
|
|
| |
There is no reason that the failure of __gpmi_enable_clk()
could lead to PM usage counter decrement.
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200522101713.24350-1-dinghao.liu@zju.edu.cn
|
|
|
|
|
|
|
|
|
|
| |
pm_runtime_get_sync() increments the runtime PM usage counter even
when it returns an error code. Thus a pairing decrement is needed on
the error handling path to keep the counter balanced.
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200522095139.19653-1-dinghao.liu@zju.edu.cn
|
|
|
|
|
|
|
|
|
|
|
|
| |
This helper is not very useful and very often people get confused:
they use nand_release() instead of nand_cleanup().
Let's stop using nand_release() by calling mtd_device_unregister() and
nand_cleanup() directly.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Han Xu <han.xu@nxp.com>
Link: https://lore.kernel.org/linux-mtd/20200519130035.1883-20-miquel.raynal@bootlin.com
|
|
|
|
|
|
|
|
|
|
|
|
| |
->exec_op() is passed a check_only argument that encodes when the
controller should just check whether the operation is supported or not
without executing it. Some controllers simply ignore this arguments,
others don't but keep modifying some of the registers before returning.
Let's fix all those drivers.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200418194217.1016060-1-boris.brezillon@collabora.com
|
|
|
|
|
|
|
|
|
|
|
| |
dma_request_slave_channel() is a wrapper on top of dma_request_chan()
eating up the error code.
Use using dma_request_chan() directly to return the real error code.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200227123749.24064-2-peter.ujfalusi@ti.com
|
|
|
|
|
|
|
|
|
|
|
|
| |
As we reset the GPMI block at resume, the timing parameters setup by a
previous exec_op is lost. Rewriting GPMI timing registers on first exec_op
after resume fixes the problem.
Fixes: ef347c0cfd61 ("mtd: rawnand: gpmi: Implement exec_op")
Cc: stable@vger.kernel.org
Signed-off-by: Esben Haabendal <esben@geanix.com>
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On system resume, the gpmi clock must be enabled before accessing gpmi
block. Without this, resume causes something like
[ 661.348790] gpmi_reset_block(5cbb0f7e): module reset timeout
[ 661.348889] gpmi-nand 1806000.gpmi-nand: Error setting GPMI : -110
[ 661.348928] PM: dpm_run_callback(): platform_pm_resume+0x0/0x44 returns -110
[ 661.348961] PM: Device 1806000.gpmi-nand failed to resume: error -110
Fixes: ef347c0cfd61 ("mtd: rawnand: gpmi: Implement exec_op")
Cc: stable@vger.kernel.org
Signed-off-by: Esben Haabendal <esben@geanix.com>
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
| |
The variable block_size is being assigned to itself and to
geo->ecc_chunk_size. Clean up the double assignment by removing
the assignment to itself.
Addresses-Coverity: ("Evaluation order violation")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The gpmi driver performance suffers from NAND operations being split
in multiple small DMA transfers. This has been forced by the NAND layer
in the former days, but now with exec_op we can use the controller as
intended.
With this patch gpmi_nfc_exec_op becomes the main entry point to NAND
operations. Here all instructions are collected and chained as separate
DMA transfers. In the end whole chain is fired and waited to be
finished. gpmi_nfc_exec_op only does the hardware operations, bad block
marker swapping and buffer scrambling is done by the callers. It's worth
noting that the nand_*_op functions always take the buffer lengths for
the data that the NAND chip actually transfers. When doing BCH we have
to calculate the net data size from the raw data size in some places.
This patch has been tested with 2048/64 and 2048/128 byte NAND on
i.MX6q. mtd_oobtest, mtd_subpagetest and mtd_speedtest run without
errors. nandbiterrs, nandpagetest and nandsubpagetest userspace tests
from mtdutils run without errors and UBIFS can successfully be mounted.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
| |
The mxs dma driver uses the flags parameter in dmaengine_prep_slave_sg() for
custom flags, but still uses the dmaengine specific names of the flags.
Do a little bit better and at least give the flag a custom name.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The mxs dma driver can do PIO transfers. A pointer to the PIO words
to transfer is passed in the struct scatterlist * argument of
dmaengine_prep_slave_sg(). It's quite ugly and non obvious to cast
u32 * to struct scatterlist * each time when calling
dmaengine_prep_slave_sg(), so add a static inline wrapper function
to be called by the user along with a description what is going on.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
| |
The DMA_PREP_INTERRUPT flag is no longer needed by the mxs DMA driver,
drop it.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
| |
The gpmi driver aggressively en/disables the clocks between operations
which has significant performance cost. Use runtime PM to get rid of
this bottleneck.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
| |
The i.MX23 specific option read code is called right after nand_scan. We
can rely on the NAND core having disabled the chipselect, so there's no
point in restoring the original chip select after NAND operations. Drop
it.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
| |
gpmi_ecc_read_page_data uses the page parameter only for a debug printf,
so we can drop the parameter and the debug printf. Moving the oob
delivery from gpmi_ecc_read_page_data to gpmi_ecc_read_page makes the
oob_required parameter unnecessary aswell.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
| |
The driver calls nand_read_page_op without a buffer passed and then
calls chip->legacy.read_buf to read the buffer afterwards which is
the same as passing the buffer nand_read_page_op in the first place.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
| |
this->page_buffer_virt and this->payload_virt are always set to the same
value, so drop the former and just use the latter. Same for
this->page_buffer_virt and this->payload_virt.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
| |
The "private" member of struct gpmi_nand_data isn't used anywhere.
Remove it.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This moves the whole driver into a single C file. The filename gpmi-lib
implies that it implements library functions, but in fact there are
several cases where functions in gpmi-lib.c call back into functions in
gpmi-nand.c. With this one has to constantly jump between those two
files, so moving it into a single file improves readability, even when
the file gets quite large.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|