]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mtd: spi-nor-core: Rework spansion_read_any_reg() to support Octal DTR mode
authorTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Fri, 22 Dec 2023 05:46:00 +0000 (14:46 +0900)
committerJagan Teki <jagan@edgeble.ai>
Mon, 29 Jan 2024 14:04:17 +0000 (19:34 +0530)
In Infineon multi-die package parts, we need to use Read Any Register op
to read status register in 2nd or further die. Infineon S28HS02GT is
dual-die package and supports Octal DTR interface. To support this,
spansion_read_any_reg() needs to be reworked. Implementation is similar
to existing read_sr() that already supports Octal DTR mode.

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/mtd/spi/spi-nor-core.c

index eed3459ba825a4268126a9ce1f45a226584d7040..f24b96926b7269327647375c4ac94aa5bd933daf 100644 (file)
@@ -331,12 +331,36 @@ static int spansion_read_any_reg(struct spi_nor *nor, u32 addr, u8 dummy,
                                 u8 *val)
 {
        struct spi_mem_op op =
-               SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
-                          SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1),
-                          SPI_MEM_OP_DUMMY(dummy / 8, 1),
-                          SPI_MEM_OP_DATA_IN(1, NULL, 1));
+               SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0),
+                          SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 0),
+                          SPI_MEM_OP_DUMMY(dummy, 0),
+                          SPI_MEM_OP_DATA_IN(1, NULL, 0));
+       u8 buf[2];
+       int ret;
+
+       spi_nor_setup_op(nor, &op, nor->reg_proto);
+
+       /*
+        * In Octal DTR mode, the number of address bytes is always 4 regardless
+        * of addressing mode setting.
+        */
+       if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR)
+               op.addr.nbytes = 4;
+
+       /*
+        * We don't want to read only one byte in DTR mode. So, read 2 and then
+        * discard the second byte.
+        */
+       if (spi_nor_protocol_is_dtr(nor->reg_proto))
+               op.data.nbytes = 2;
 
-       return spi_nor_read_write_reg(nor, &op, val);
+       ret = spi_nor_read_write_reg(nor, &op, buf);
+       if (ret)
+               return ret;
+
+       *val = buf[0];
+
+       return 0;
 }
 
 static int spansion_write_any_reg(struct spi_nor *nor, u32 addr, u8 val)