Re: [PATCH v16 14/15] mtd: spi-nor: spansion: add support for Cypress Semper flash

2020-11-09 Thread Tudor.Ambarus
On 11/7/20 9:58 AM, Vignesh Raghavendra wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> content is safe
> 
> Hi,
> 
> [...]
> 
> On 10/5/20 9:01 PM, Pratyush Yadav wrote:
>> +static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool 
>> enable)
>> +{
>> + struct spi_mem_op op;
>> + u8 *buf = nor->bouncebuf;
>> + int ret;
>> +
>> + if (enable) {
>> + /* Use 24 dummy cycles for memory array reads. */
>> + ret = spi_nor_write_enable(nor);
>> + if (ret)
>> + return ret;
>> +
>> + *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
>> + op = (struct spi_mem_op)
>> + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
>> +SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR2V,
>> +1),
>> +SPI_MEM_OP_NO_DUMMY,
>> +SPI_MEM_OP_DATA_OUT(1, buf, 1));
>> +
>> + ret = spi_mem_exec_op(nor->spimem, );
>> + if (ret)
>> + return ret;
>> +
>> + ret = spi_nor_wait_till_ready(nor);
>> + if (ret)
>> + return ret;
>> +
>> + nor->read_dummy = 24;
>> + }
>> +
>> + /* Set/unset the octal and DTR enable bits. */
>> + ret = spi_nor_write_enable(nor);
>> + if (ret)
>> + return ret;
>> +
>> + if (enable)
>> + *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
>> + else
>> + *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
>> +
>> + op = (struct spi_mem_op)
>> + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
>> +SPI_MEM_OP_ADDR(enable ? 3 : 4,
>> +SPINOR_REG_CYPRESS_CFR5V,
>> +1),
>> +SPI_MEM_OP_NO_DUMMY,
>> +SPI_MEM_OP_DATA_OUT(1, buf, 1));
>> +
>> + if (!enable)
>> + spi_nor_spimem_setup_op(nor, , SNOR_PROTO_8_8_8_DTR);
>> +
>> + ret = spi_mem_exec_op(nor->spimem, );
>> + if (ret)
>> + return ret;
>> +
>> + /* Give some time for the mode change to take place. */
>> + usleep_range(1000, 1500);
>> +
> 
> This delay is no longer needed right? I can drop it while applying, if
> you confirm.
> 
> Tudor: Could you provide your R-by?

with usleep_range dropped one can add:

Reviewed-by: Tudor Ambarus 

Cheers,
ta


Re: [PATCH v16 14/15] mtd: spi-nor: spansion: add support for Cypress Semper flash

2020-11-09 Thread Pratyush Yadav
On 07/11/20 01:28PM, Vignesh Raghavendra wrote:
> Hi,
> 
> [...]
> 
> On 10/5/20 9:01 PM, Pratyush Yadav wrote:
> > +static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool 
> > enable)
> > +{
> > +   struct spi_mem_op op;
> > +   u8 *buf = nor->bouncebuf;
> > +   int ret;
> > +
> > +   if (enable) {
> > +   /* Use 24 dummy cycles for memory array reads. */
> > +   ret = spi_nor_write_enable(nor);
> > +   if (ret)
> > +   return ret;
> > +
> > +   *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
> > +   op = (struct spi_mem_op)
> > +   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
> > +  SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR2V,
> > +  1),
> > +  SPI_MEM_OP_NO_DUMMY,
> > +  SPI_MEM_OP_DATA_OUT(1, buf, 1));
> > +
> > +   ret = spi_mem_exec_op(nor->spimem, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_nor_wait_till_ready(nor);
> > +   if (ret)
> > +   return ret;
> > +
> > +   nor->read_dummy = 24;
> > +   }
> > +
> > +   /* Set/unset the octal and DTR enable bits. */
> > +   ret = spi_nor_write_enable(nor);
> > +   if (ret)
> > +   return ret;
> > +
> > +   if (enable)
> > +   *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
> > +   else
> > +   *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
> > +
> > +   op = (struct spi_mem_op)
> > +   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
> > +  SPI_MEM_OP_ADDR(enable ? 3 : 4,
> > +  SPINOR_REG_CYPRESS_CFR5V,
> > +  1),
> > +  SPI_MEM_OP_NO_DUMMY,
> > +  SPI_MEM_OP_DATA_OUT(1, buf, 1));
> > +
> > +   if (!enable)
> > +   spi_nor_spimem_setup_op(nor, , SNOR_PROTO_8_8_8_DTR);
> > +
> > +   ret = spi_mem_exec_op(nor->spimem, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   /* Give some time for the mode change to take place. */
> > +   usleep_range(1000, 1500);
> > +
> 
> This delay is no longer needed right? I can drop it while applying, if
> you confirm.

Yes, this delay is not needed. Please drop it while applying.
 
> Tudor: Could you provide your R-by?
> 
> Regards
> Vignesh

-- 
Regards,
Pratyush Yadav
Texas Instruments India


Re: [PATCH v16 14/15] mtd: spi-nor: spansion: add support for Cypress Semper flash

2020-11-06 Thread Vignesh Raghavendra
Hi,

[...]

On 10/5/20 9:01 PM, Pratyush Yadav wrote:
> +static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable)
> +{
> + struct spi_mem_op op;
> + u8 *buf = nor->bouncebuf;
> + int ret;
> +
> + if (enable) {
> + /* Use 24 dummy cycles for memory array reads. */
> + ret = spi_nor_write_enable(nor);
> + if (ret)
> + return ret;
> +
> + *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
> + op = (struct spi_mem_op)
> + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
> +SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR2V,
> +1),
> +SPI_MEM_OP_NO_DUMMY,
> +SPI_MEM_OP_DATA_OUT(1, buf, 1));
> +
> + ret = spi_mem_exec_op(nor->spimem, );
> + if (ret)
> + return ret;
> +
> + ret = spi_nor_wait_till_ready(nor);
> + if (ret)
> + return ret;
> +
> + nor->read_dummy = 24;
> + }
> +
> + /* Set/unset the octal and DTR enable bits. */
> + ret = spi_nor_write_enable(nor);
> + if (ret)
> + return ret;
> +
> + if (enable)
> + *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
> + else
> + *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
> +
> + op = (struct spi_mem_op)
> + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
> +SPI_MEM_OP_ADDR(enable ? 3 : 4,
> +SPINOR_REG_CYPRESS_CFR5V,
> +1),
> +SPI_MEM_OP_NO_DUMMY,
> +SPI_MEM_OP_DATA_OUT(1, buf, 1));
> +
> + if (!enable)
> + spi_nor_spimem_setup_op(nor, , SNOR_PROTO_8_8_8_DTR);
> +
> + ret = spi_mem_exec_op(nor->spimem, );
> + if (ret)
> + return ret;
> +
> + /* Give some time for the mode change to take place. */
> + usleep_range(1000, 1500);
> +

This delay is no longer needed right? I can drop it while applying, if
you confirm.

Tudor: Could you provide your R-by?

Regards
Vignesh


[PATCH v16 14/15] mtd: spi-nor: spansion: add support for Cypress Semper flash

2020-10-05 Thread Pratyush Yadav
The Cypress Semper flash is an xSPI compliant octal DTR flash. Add
support for using it in octal DTR mode.

The flash by default boots in a hybrid sector mode. But the sector map
table on the part I had was programmed incorrectly and the SMPT values
on the flash don't match the public datasheet. Specifically, in some
places erase type 3 was used instead of 4. In addition, the region sizes
were incorrect in some places. So, for testing I set CFR3N[3] to enable
uniform sector sizes. Since the uniform sector mode bit is a
non-volatile bit, this series does not change it to avoid making any
permanent changes to the flash configuration. The correct data to
implement a fixup is not available right now and will be done in a
follow-up patch if needed.

Signed-off-by: Pratyush Yadav 
---
 drivers/mtd/spi-nor/spansion.c | 174 +
 1 file changed, 174 insertions(+)

diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index 8429b4af999a..2c5c0f69dc5c 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -8,6 +8,175 @@
 
 #include "core.h"
 
+#define SPINOR_OP_RD_ANY_REG   0x65/* Read any register */
+#define SPINOR_OP_WR_ANY_REG   0x71/* Write any register */
+#define SPINOR_REG_CYPRESS_CFR2V   0x0083
+#define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24  0xb
+#define SPINOR_REG_CYPRESS_CFR3V   0x0084
+#define SPINOR_REG_CYPRESS_CFR3V_PGSZ  BIT(4) /* Page size. */
+#define SPINOR_REG_CYPRESS_CFR5V   0x0086
+#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN0x3
+#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS0
+#define SPINOR_OP_CYPRESS_RD_FAST  0xee
+
+/**
+ * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
+ * @nor:   pointer to a 'struct spi_nor'
+ * @enable:  whether to enable or disable Octal DTR
+ *
+ * This also sets the memory access latency cycles to 24 to allow the flash to
+ * run at up to 200MHz.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable)
+{
+   struct spi_mem_op op;
+   u8 *buf = nor->bouncebuf;
+   int ret;
+
+   if (enable) {
+   /* Use 24 dummy cycles for memory array reads. */
+   ret = spi_nor_write_enable(nor);
+   if (ret)
+   return ret;
+
+   *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
+   op = (struct spi_mem_op)
+   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
+  SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR2V,
+  1),
+  SPI_MEM_OP_NO_DUMMY,
+  SPI_MEM_OP_DATA_OUT(1, buf, 1));
+
+   ret = spi_mem_exec_op(nor->spimem, );
+   if (ret)
+   return ret;
+
+   ret = spi_nor_wait_till_ready(nor);
+   if (ret)
+   return ret;
+
+   nor->read_dummy = 24;
+   }
+
+   /* Set/unset the octal and DTR enable bits. */
+   ret = spi_nor_write_enable(nor);
+   if (ret)
+   return ret;
+
+   if (enable)
+   *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
+   else
+   *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
+
+   op = (struct spi_mem_op)
+   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
+  SPI_MEM_OP_ADDR(enable ? 3 : 4,
+  SPINOR_REG_CYPRESS_CFR5V,
+  1),
+  SPI_MEM_OP_NO_DUMMY,
+  SPI_MEM_OP_DATA_OUT(1, buf, 1));
+
+   if (!enable)
+   spi_nor_spimem_setup_op(nor, , SNOR_PROTO_8_8_8_DTR);
+
+   ret = spi_mem_exec_op(nor->spimem, );
+   if (ret)
+   return ret;
+
+   /* Give some time for the mode change to take place. */
+   usleep_range(1000, 1500);
+
+   /* Read flash ID to make sure the switch was successful. */
+   op = (struct spi_mem_op)
+   SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
+  SPI_MEM_OP_ADDR(enable ? 4 : 0, 0, 1),
+  SPI_MEM_OP_DUMMY(enable ? 3 : 0, 1),
+  SPI_MEM_OP_DATA_IN(round_up(nor->info->id_len, 2),
+ buf, 1));
+
+   if (enable)
+   spi_nor_spimem_setup_op(nor, , SNOR_PROTO_8_8_8_DTR);
+
+   ret = spi_mem_exec_op(nor->spimem, );
+   if (ret)
+   return ret;
+
+   if (memcmp(buf, nor->info->id, nor->info->id_len))
+   return -EINVAL;
+
+   return 0;
+}
+
+static void s28hs512t_default_init(struct spi_nor *nor)
+{
+   nor->params->octal_dtr_enable