After power up, all SPI NAND's blocks are locked. Only read operations
are allowed, write and erase operations are forbidden.
The SPI NAND framework unlocks all the blocks during its initialization.
During a standby low power, the memory is powered down, losing its
configuration.
During the resume, the QSPI driver state is restored but the SPI NAND
framework does not reconfigured the memory.
This patch adds SPI-NAND MTD PM handlers for resume ops.
SPI NAND resume op re-initializes SPI NAND flash to its probed state.
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210602094913.26472-4-patrice.chotard@foss.st.com
In the raw NAND world, ECC engines increment ecc_stats and the final
caller is responsible for returning -EBADMSG if the verification
failed.
In the SPI-NAND world it was a bit different until now because there was
only one possible ECC engine: the on-die one. Indeed, the
spinand_mtd_read() call was incrementing the ecc_stats counters
depending on the outcome of spinand_check_ecc_status() directly.
So now let's split the logic like this:
- spinand_check_ecc_status() is specific to the SPI-NAND on-die engine
and is kept very simple: it just returns the ECC status (bonus point:
the content of this helper can be overloaded).
- spinand_ondie_ecc_finish_io_req() is the caller of
spinand_check_ecc_status() and will increment the counters and
eventually return -EBADMSG.
- spinand_mtd_read() is not tied to the on-die ECC implementation and
should be able to handle results coming from other ECC engines: it has
the responsibility of returning the maximum number of bitflips which
happened during the entire operation as this is the only helper that
is aware that several pages may be read in a row.
Fixes: 945845b54c ("mtd: spinand: Instantiate a SPI-NAND on-die ECC engine")
Reported-by: YouChing Lin <ycllin@mxic.com.tw>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Tested-by: YouChing Lin <ycllin@mxic.com.tw>
Link: https://lore.kernel.org/linux-mtd/20210527084345.208215-1-miquel.raynal@bootlin.com
Memory controller drivers for v5.14 - PL353
Bigger work around ARM Primecell PL35x SMC memory controller driver by
Miquel Raynal built on previous series from Naga Sureshkumar Relli.
This includes bindings cleanup and correction, converting these to
dtschema and several cleanyps in pl353-smc driver.
There is no point in having all these definitions at the SMC bus level,
these are extremely tight to the NAND controller driver implementation,
are not particularly generic, imply more boilerplate than needed, do
not really follow the device model by receiving no argument and some of
them are actually buggy.
Let's get rid of these right now as there is no current user and keep
this driver at a simple level: only the SMC bare initializations.
The NAND controller driver which I am going to introduce will take care
of redefining properly all these helpers and using them directly.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20210610082040.2075611-13-miquel.raynal@bootlin.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
These nodes are given as examples and are not described nor used
anywhere else. There is also no hardware of my knowledge compatible with
these yet. If we want to be backward compatible, then we should avoid
partially describing nodes and their content while there are no users.
Plus, the examples are wrong (the addresses should be updated) so
let's drop them before converting this file to yaml (only the NAND node,
which will be fixed in the example and described somewhere else is
kept).
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20210610082040.2075611-7-miquel.raynal@bootlin.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Make use of the cs-gpios DT property as well as the core helper to parse
it so that the Arasan controller driver can now assert many more chips
than natively.
The Arasan controller has an internal limitation: RB0 is tied to CS0 and
RB1 is tied to CS1. Hence, it is possible to use external GPIOs as long
as one or the other native CS is not used (or configured to be driven as
a GPIO) and that all additional CS are physically wired on its
corresponding RB line. Eg. CS0 is used as a native CS, CS1 is not used
as native CS and may be used as a GPIO CS, CS2 is an additional GPIO
CS. Then the target asserted by CS0 should also be wired to RB0, while
the targets asserted by CS1 and CS2 should be wired to RB1.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210526093242.183847-5-miquel.raynal@bootlin.com
The controller being always asserting one CS or the other, there is no
need to actually select the right target before doing a page read/write.
However, the anfc_select_target() helper actually also changes the
timing configuration and clock in the case were two different NAND chips
with different timing requirements would be used. In this situation, we
must ensure proper configuration of the controller by calling it.
As a consequence of this change, the anfc_select_target() helper is
being moved earlier in the driver.
Fixes: 88ffef1b65 ("mtd: rawnand: arasan: Support the hardware BCH ECC engine")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210526093242.183847-4-miquel.raynal@bootlin.com
New chips may feature a lot of CS because of their extended length. As
many controllers have been designed a decade ago, they usually only
feature just a couple. This does not mean that the entire range of
these chips cannot be accessed: it is just a matter of adding more
GPIO CS in the hardware design. A DT property has been added to
describe the CS array: cs-gpios.
Here is the code parsing it this new property, allocating what needs to
be, requesting the GPIOs and returning an array with the additional
available CS. The first entries of this array are left empty and are
reserved for native CS.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210526093242.183847-3-miquel.raynal@bootlin.com
To reach higher capacities, arrays of chips are now pretty common.
Unfortunately, most of the controllers have been designed a decade ago
and did not all anticipate the need for several chip-selects. The new
cs-gpios property allows to workaround this limitation by adding as many
GPIO chip-select as needed.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210510171800.27225-1-miquel.raynal@bootlin.com
As explained in the comment introduced above the fix, the Arasan
controller driver starts an operation when the prog register is being
written with a "type" specific to the action to perform.
The prog type used until now to perform a CHANGE READ COLUMN with an SDR
interface was the PAGE READ type (CMD + ADDR + CMD +
DATA). Unfortunately, for an unknown reason (let's call this a silicon
bug) any CHANGE READ COLUMN performed this way in NV-DDR mode will fail:
the data ready flag will never be triggered, nor will be the transfer
complete flag. Forcefully, this leads to a timeout situation which is
not easy to handle.
Fortunately, it was spotted that sending the same commands through a
different prog register "type", CHANGE READ COLUMN ENHANCED, would work
all the time (even though this particular command is not supported by
the core and is only available in a limited set of devices - we only
care about the controller configuration and not the actual command which
is sent to the device). So let's use this type instead when a CHANGE
READ COLUMN is requested.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-22-miquel.raynal@bootlin.com
Now that the necessary peaces to support the NV-DDR interface type have
been contributed, let's add the relevant logic to make use of it. In
particular, the core does not choose the best SDR timings anymore but
calls a more generic helper instead.
This helper checks if NV-DDR is supported by trying to find the best
NV-DDR supported mode through a logic very close to what is being done
for SDR timings. If no NV-DDR mode in common between the NAND controller
and the NAND chip is found, the core will fallback to SDR.
Side note: theoretically, the data clock speed in NV-DDR mode 0 is
slower than in SDR mode 5. In the situation where we would get a working
NV-DDR mode 0, we could also try if SDR mode 5 is supported and
eventually fallback to it in order to get the fastest possible
throughput. However, in the field, it looks like most of the devices
supporting NV-DDR avoid implementing the fastest SDR modes (like 4 and 5
EDO modes, which are a bit more complicated to handle than the other SDR
modes). So, we will stick to the simplest logic: try NV-DDR otherwise
fallback to SDR. If someone else experiences strong differences because
of that we may still implement the logic defined above.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-19-miquel.raynal@bootlin.com
Until now the parameter of the ADDR_TIMING_MODE feature was just the
ONFI timing mode (from 0 to 5) because we were only supporting the SDR
data interface. In the same byte, bits 4 and 5 indicate which data
interface is being configured so use them to set the right mode and also
read them back to ensure the right timing has been setup on the chip's
side.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-17-miquel.raynal@bootlin.com
As explained in chapter "NV-DDR / NV-DDR2 / NV-DDR3 and Repeat Bytes" of
the ONFI specification, with some commands (mainly the commands which do
not transfer actual data) the data bytes are repeated twice and it is
the responsibility of the receiver to discard them properly. The
concerned commands are: SET_FEATURES, READ_ID, GET_FEATURES,
READ_STATUS, READ_STATUS_ENHANCED, ODT_CONFIGURE. Hence, in the NAND
core we are only impacted by the implementation of READ_ID, GET_FEATURES
and READ_STATUS.
The logic is the same for all:
2/ Check if it is relevant to read all data bytes twice.
1/ Allocate a buffer with twice the requested size (may be done
statically).
2/ Update the instruction structure to read these extra bytes in the
allocated buffer.
3/ Copy the even bytes into the original buffer. The performance hit is
negligible on such small data transfers anyway and we don't really
care about performances at this stage anyway.
4/ Free the allocated buffer, if any.
Note: nand_data_read_op() is also impacted because it is theoretically
possible to run the command/address cycles first, and, as another
operation, do the data transfers. In this case we can easily identify
the impacted commands because the force_8bit flag will be set (due to
the same reason: their data does not go through the same pipeline).
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-15-miquel.raynal@bootlin.com
Most timings related to the bus timings are different between SDR and
NV-DDR. However, we identified 9 individual timings which are more
related to the NAND chip internals. These are common between the two
interface types. Fortunately, only these common timings are being shared
through the NAND core and its ->exec_op() interface, which allows the
writing of a simple macro checking the interface type and depending on
it, returning either the relevant SDR timing or the NV-DDR timing. This
is the purpose of the NAND_COMMON_TIMING_PS() macro.
As all this is evaluated at build time, one will immediately be notified
in case a non common timing is being accessed through this macro.
Two handy macros are also inserted at the same time, which use
PSEC_TO_NSEC or PSEC_TO_MSEC so that it is very easy to return timings
in milli-, nano- or pico-seconds, as usually requested by the internal
API.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-14-miquel.raynal@bootlin.com
Same logic as for the SDR path, let's create a
onfi_fill_nvddr_interface_config() helper to fill an interface
configuration structure with NV-DDR timings, given a specific ONFI mode.
There is one additional thing to do compared to SDR mode: tCAD timing
can be fast or slow and this depends on an ONFI parameter page bit. By
default the slow value is declared in the timings structure definition,
but this helper can shrink it down if necessary.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-12-miquel.raynal@bootlin.com
This helper actually fills the interface configuration with SDR data.
As part of the work to bring NV-DDR support, let's rename this helper
onfi_fill_sdr_interface_config() and add a generic indirection to it.
There are no functional changes here, but this will simplify a next
change which adds onfi_fill_nvddr_interface_config() support.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-11-miquel.raynal@bootlin.com
Both src_sync_timing_mode and src_ssync_features entries of the ONFI
parameter page have been updated and now are named nvddr_timing_modes,
nvddr2_timing_modes and nvddr_nvddr2_features, which is much more
understandable for someone which do not know the history of the ONFI
specification. Update the relevant structure with regard to these
changes.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210505213750.257417-8-miquel.raynal@bootlin.com