Linux-mtd Archive mirror
 help / color / mirror / Atom feed
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 2/3] mtd: nand: mxc_nand: implement exec_op
Date: Mon, 13 May 2024 14:55:36 +0200	[thread overview]
Message-ID: <20240513145536.71145b65@xps-13> (raw)
In-Reply-To: <ZkHYo6-8SC4RMlsG@pengutronix.de>

Hi Sascha,

> > > > +	for (i = 0; i < op->ninstrs; i++) {
> > > > +		instr = &op->instrs[i];
> > > > +
> > > > +		nand_op_trace("  ", instr);
> > > > +
> > > > +		switch (instr->type) {
> > > > +		case NAND_OP_WAITRDY_INSTR:
> > > > +			/*
> > > > +			 * NFC handles R/B internally. Therefore, this function
> > > > +			 * always returns status as ready.    
> > > 
> > > This is no longer a standalone function, maybe:
> > > 
> > > "The controller handles the R/B pin internally, therefore there is
> > > nothing to do here."  
> > 
> > And this is actually very wrong.
> > 
> > You should call wait_op_done() instead.
> >   
> > >   
> > > > +			 */
> > > > +			break;
> > > > +		case NAND_OP_CMD_INSTR:
> > > > +			if (instr->ctx.cmd.opcode == NAND_CMD_PAGEPROG)
> > > > +				host->devtype_data->send_page(mtd, NFC_INPUT);  
> > 
> > Actually this is not the right place. You should trigger the transfer
> > from controller SRAM to NAND (and the other way around) in the
> > NAND_OP_DATA_OUT_INSTR case.
> > 
> > Here you should just call ->send_cmd.  
> 
> I tried to get away here with using the standard nand_write_page_raw()
> function. This does multiple NAND_OP_DATA_OUT_INSTR ops before finally
> sending a NAND_CMD_PAGEPROG command. With software BCH ECC I collect all
> data being written in memory and copy it to the controller SRAM en bloc.
> I have to do this after the final NAND_OP_DATA_OUT_INSTR op. During a
> NAND_OP_DATA_OUT_INSTR I don't know if this is going to be the last one
> or if other NAND_OP_DATA_OUT_INSTR ops follow, so I do the copy to SRAM
> right before a NAND_CMD_PAGEPROG.

I fully understand the mindset, but we had too many issues with this
this using ->cmdfunc() and ->cmd_ctrl(), so we introduced ->exec_op()
exactly for this purpose: controller drivers shall not try to guess
what the core wants. The core now provides the full operation and also a
way to check if the operation is supported.

So if something is unsupported, just report it is unsupported.

> I could move the ->send_page() call to NAND_OP_DATA_OUT_INSTR, but then
> I have to overwrite the ecc->write_page_raw() hook.

I guess your issue is the core trying to write the in-band data
and later the oob data. I totally get why you're doing that now, makes
sense, but this is not how ->exec_op() should be implemented, let me
explain (and propose a solution).

In general, it is preferred to have a clean ->exec_op()
implementation (in case we later extend the core) that is capable of
doing the ops correctly and *just* what has been requested. Drivers
should refuse the operations they don't support instead of trying
to work-arouding them. So here the correct way is probably to provide a
->write_page_raw() hook to simply avoid the unsupported ops. In your
case you just need to reference nand_monolithic_write_page_raw() and
you're done.

Also please check the cases you don't support and refuse them in
->exec_op() (both in the normal *and* in the check_only path). This is
also part of ->exec_op()'s design and is very important. I believe you
should take inspiration from the pl35x-nand-controller.c driver which
typically covers all the known-to-be-working cases with just three
patterns filled in a parser structure (true/false means the instruction
is mandatory or can be skipped, please have a look to
pl35x_nandc_op_parser). You will notice all cases in the parser
reference the same function in the end (you can do the same). This way
you know only supported patterns will be used and the core can easily
check whether something "new" is supported or not. Right now the
current mxc ->exec_op() implementation says it supports all
instructions, which is of course a lie.

Side note: Core helpers were initially written with the more flexible
approach, ie. splitting the operations in smaller pieces. This
typically does not work with some controllers such as yours. What I
want is the driver telling the core it should not try to split the ops
if that's the case. I know the core is a bit flacky regarding these
checks. There is currently only the data_only_read supported_op check
that is used for early discovery (see nand_onfi_detect()), but in case
you have issues with this type of situation, let me know, we (I) can
improve the core.

> Also it must be
> clear that the NAND core will never do multiple NAND_OP_DATA_OUT_INSTR
> when programming a page.

That's typically something that could happen (in practice I don't have
any plans for that, this is theoretically speaking), hence using the
nand_op_parser structure will ensure if we ever extend the core, the
driver won't break.

> Side note: I decided to collect the page data in a memory buffer rather
> than in the controller SRAM directly because it seemed too complicated
> and error prone to find the correct offset in SRAM for random column
> addresses. Also the SRAM can only do word and halfword accesses, so I
> additionally would have to emulate byte accesses with read-modify-write
> halfword accesses. While certainly doable I'd like to defer this to a
> future optimisation exercise.

Oh yeah, totally agreed. I saw the implementation and I agree we should
aim for a working driver. Then if you want to improve it for
performance reasons, changes will be welcome.

Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2024-05-13 12:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-08 11:08 [PATCH v2 0/3] mtd: nand: mxc_nand: Convert to exec_op Sascha Hauer
2024-05-08 11:08 ` [PATCH v2 1/3] mtd: nand: mxc_nand: separate page read from ecc calc Sascha Hauer
2024-05-08 11:08 ` [PATCH v2 2/3] mtd: nand: mxc_nand: implement exec_op Sascha Hauer
2024-05-13  7:19   ` Miquel Raynal
2024-05-13  7:32     ` Miquel Raynal
2024-05-13  9:08       ` Sascha Hauer
2024-05-13 12:55         ` Miquel Raynal [this message]
2024-05-14  9:18       ` Sascha Hauer
2024-05-14 10:16         ` Miquel Raynal
2024-05-08 11:08 ` [PATCH v2 3/3] mtd: nand: mxc_nand: support software ECC Sascha Hauer
2024-05-13  7:42   ` Miquel Raynal
2024-05-13  9:19     ` Sascha Hauer

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=20240513145536.71145b65@xps-13 \
    --to=miquel.raynal@bootlin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    --cc=s.hauer@pengutronix.de \
    --cc=vigneshr@ti.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).