Thread (41 messages) 41 messages, 6 authors, 2018-06-11

Re: [PATCH v3 4/6] mtd: rawnand: add NVIDIA Tegra NAND Flash controller driver

From: Stefan Agner <stefan@agner.ch>
Date: 2018-06-09 06:51:50
Also in: linux-tegra, lkml

On 09.06.2018 08:41, Boris Brezillon wrote:
On Sat, 09 Jun 2018 08:23:51 +0200
Stefan Agner [off-list ref] wrote:
quoted
On 09.06.2018 07:52, Boris Brezillon wrote:
quoted
On Fri, 08 Jun 2018 23:51:01 +0200
Stefan Agner [off-list ref] wrote:

quoted
quoted
void tegra_nand_controller_reset(struct tegra_nand_controller *ctrl)
{
	int err;

	disable_irq(ctrl->irq);

	err = reset_control_reset(ctrl->rst);
	if (err) {
		dev_err(ctrl->dev, "Failed to reset HW: %d\n", err);
		msleep(HW_TIMEOUT);
	}

	writel_relaxed(NAND_CMD_STATUS, ctrl->regs + HWSTATUS_CMD);
	writel_relaxed(HWSTATUS_MASK, ctrl->regs + HWSTATUS_MASK);
	writel_relaxed(INT_MASK, ctrl->regs + ISR);
If we do a controller reset, there is much more state than that which
needs to be restored. A lot of it is not readily available currently
(timing, ECC settings...)
This is actually a good test to detect what is not properly initialized
by the driver. Timings should be configured correctly through
->setup_data_interface(). ECC engine should be disabled by default and
only enabled when ->{read,write}_page() is called.
Is setup_data_interface guaranteed to be called after a failed
->exec_op()/{read,write}_page()?
No. Maybe I misunderstood when tegra_nand_controller_reset() was
supposed to be called. That's something I would call only once, early
in the probe function, so that the controller is placed in a well-known
state before we start using it. Definitely not something you should
call after each error.
Dmitry suggests to make use of it in the error handling path in case the
command/DMA  timed out.

Which makes sense in general I guess, just to make sure that the state
is properly set. It just isn't entirely trivial to do, since state is
setup during probe, chip detect and timing setup...
quoted
quoted
quoted
That seems a lot of work for a code path I do not intend to ever use :-)
Not so sure it's a lot of work. If ECC and timing settings are the
only thing you need to initialize then it should work just fine.
Try with a controller reset and you'll know if you miss something ;-).
Currently the setting gets written directly to the registers. Only the
enable flag is set in the HW ECC {read,write}_page() functions. So I
will have to store the complete register in the chip structure and write
them on every {read,write}_page()?
Well, your solution works as long as you only have one chip connected
to the controller. What we usually set the ECC config in
->select_chip() (or at least make sure the current setting matches the
one we expect) and then enable the engine in read/write_page() (as you
seem to already do).
I did not plan to make the driver multi chip capable, as I am not aware
of any real hardware using it.

But to properly reset state, we would have to have all the chip settings
stored somewhere...

--
Stefan
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help