]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
mtd: rawnand: onfi: Adapt the parameter page read to constraint controllers
authorMiquel Raynal <miquel.raynal@bootlin.com>
Thu, 7 May 2020 10:52:37 +0000 (12:52 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Mon, 11 May 2020 07:51:43 +0000 (09:51 +0200)
We already know that there are controllers not able to read the three
copies of the parameter page in one go. The workaround was to first
request the controller to assert command and address cycles on the
NAND bus to trigger a parameter page read, and then do a simple read
operation for each page.

But there are also controllers which are not able to split the
parameter page read between the command/address cycles and the actual
data operation.

Let's use a regular PARAMETER PAGE READ operation for the first
iteration and use either a CHANGE READ COLUMN or a simple DATA READ
operation for the following copies, depending on what the controller
supports. The default behavior for non-exec-op compliant drivers
remains the same: DATA READ.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200507105241.14299-10-miquel.raynal@bootlin.com
drivers/mtd/nand/raw/nand_onfi.c

index e6ffbe8c9a0cc8c40e2b1a95f029c384a9613471..be3456627288fad7760328e08844f475837f77e6 100644 (file)
@@ -143,6 +143,7 @@ int nand_onfi_detect(struct nand_chip *chip)
        struct nand_memory_organization *memorg;
        struct nand_onfi_params *p = NULL, *pbuf;
        struct onfi_params *onfi;
+       bool use_datain = false;
        int onfi_version = 0;
        char id[4];
        int i, ret, val;
@@ -160,15 +161,21 @@ int nand_onfi_detect(struct nand_chip *chip)
        if (!pbuf)
                return -ENOMEM;
 
-       ret = nand_read_param_page_op(chip, 0, NULL, 0);
-       if (ret) {
-               ret = 0;
-               goto free_onfi_param_page;
-       }
+       if (!nand_has_exec_op(chip) ||
+           !nand_read_data_op(chip, &pbuf[0], sizeof(*pbuf), true, true))
+               use_datain = true;
 
        for (i = 0; i < ONFI_PARAM_PAGES; i++) {
-               ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf), true,
-                                       false);
+               if (!i)
+                       ret = nand_read_param_page_op(chip, 0, &pbuf[i],
+                                                     sizeof(*pbuf));
+               else if (use_datain)
+                       ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf),
+                                               true, false);
+               else
+                       ret = nand_change_read_column_op(chip, sizeof(*pbuf) * i,
+                                                        &pbuf[i], sizeof(*pbuf),
+                                                        true);
                if (ret) {
                        ret = 0;
                        goto free_onfi_param_page;