123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- From a714a2af12d0de527be168b821373f29f4343cb7 Mon Sep 17 00:00:00 2001
- From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
- Date: Fri, 8 Jan 2016 17:02:22 +0100
- Subject: [PATCH 25/33] mtd: spi-nor: configure the number of dummy clock
- cycles on Macronix memories
- The spi-nor framework currently expects all Fast Read operations to use 8
- dummy clock cycles. Especially some drivers like m25p80 can only support
- multiple of 8 dummy clock cycles.
- On Macronix memories, the number of dummy clock cycles to be used by Fast
- Read commands can be safely set to 8 by updating the DC0 and DC1 volatile
- bits inside the Configuration Register.
- According to the mx66l1g45g datasheet from Macronix, using 8 dummy clock
- cycles should be enough to set the SPI bus clock frequency up to:
- - 133 MHz for Fast Read 1-1-1, 1-1-2, 1-1-4 and 1-2-2 commands in Single
- Transfer Rate (STR)
- - 104 MHz for Fast Read 1-4-4 (or 4-4-4 in QPI mode) commands (STR)
- Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
- ---
- drivers/mtd/spi-nor/spi-nor.c | 155 +++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 147 insertions(+), 8 deletions(-)
- diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
- index 5232984..55a1d74 100644
- --- a/drivers/mtd/spi-nor/spi-nor.c
- +++ b/drivers/mtd/spi-nor/spi-nor.c
- @@ -1182,6 +1182,136 @@ static int winbond_quad_enable(struct spi_nor *nor)
- return 0;
- }
-
- +static int macronix_dummy2code(u8 read_opcode, u8 read_dummy, u8 *dc)
- +{
- + switch (read_opcode) {
- + case SPINOR_OP_READ:
- + case SPINOR_OP_READ4:
- + *dc = 0;
- + break;
- +
- + case SPINOR_OP_READ_FAST:
- + case SPINOR_OP_READ_1_1_2:
- + case SPINOR_OP_READ_1_1_4:
- + case SPINOR_OP_READ4_FAST:
- + case SPINOR_OP_READ4_1_1_2:
- + case SPINOR_OP_READ4_1_1_4:
- + switch (read_dummy) {
- + case 6:
- + *dc = 1;
- + break;
- + case 8:
- + *dc = 0;
- + break;
- + case 10:
- + *dc = 3;
- + break;
- + default:
- + return -EINVAL;
- + }
- + break;
- +
- + case SPINOR_OP_READ_1_2_2:
- + case SPINOR_OP_READ4_1_2_2:
- + switch (read_dummy) {
- + case 4:
- + *dc = 0;
- + break;
- + case 6:
- + *dc = 1;
- + break;
- + case 8:
- + *dc = 2;
- + break;
- + case 10:
- + *dc = 3;
- + default:
- + return -EINVAL;
- + }
- + break;
- +
- + case SPINOR_OP_READ_1_4_4:
- + case SPINOR_OP_READ4_1_4_4:
- + switch (read_dummy) {
- + case 4:
- + *dc = 1;
- + break;
- + case 6:
- + *dc = 0;
- + break;
- + case 8:
- + *dc = 2;
- + break;
- + case 10:
- + *dc = 3;
- + default:
- + return -EINVAL;
- + }
- + break;
- +
- + default:
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static int macronix_set_dummy_cycles(struct spi_nor *nor, u8 read_dummy)
- +{
- + int ret, sr, cr, mask, val;
- + u16 sr_cr;
- + u8 dc;
- +
- + /* Convert the number of dummy cycles into Macronix DC volatile bits */
- + ret = macronix_dummy2code(nor->read_opcode, read_dummy, &dc);
- + if (ret)
- + return ret;
- +
- + mask = GENMASK(7, 6);
- + val = (dc << 6) & mask;
- +
- + cr = read_cr(nor);
- + if (cr < 0) {
- + dev_err(nor->dev, "error while reading the config register\n");
- + return cr;
- + }
- +
- + if ((cr & mask) == val) {
- + nor->read_dummy = read_dummy;
- + return 0;
- + }
- +
- + sr = read_sr(nor);
- + if (sr < 0) {
- + dev_err(nor->dev, "error while reading the status register\n");
- + return sr;
- + }
- +
- + cr = (cr & ~mask) | val;
- + sr_cr = (sr & 0xff) | ((cr & 0xff) << 8);
- + write_enable(nor);
- + ret = write_sr_cr(nor, sr_cr);
- + if (ret) {
- + dev_err(nor->dev,
- + "error while writing the SR and CR registers\n");
- + return ret;
- + }
- +
- + ret = spi_nor_wait_till_ready(nor);
- + if (ret)
- + return ret;
- +
- + cr = read_cr(nor);
- + if (cr < 0 || (cr & mask) != val) {
- + dev_err(nor->dev, "Macronix Dummy Cycle bits not updated\n");
- + return -EINVAL;
- + }
- +
- + /* Save the number of dummy cycles to use with Fast Read commands */
- + nor->read_dummy = read_dummy;
- + return 0;
- +}
- +
- static int macronix_set_quad_mode(struct spi_nor *nor)
- {
- int status;
- @@ -1199,8 +1329,7 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
- * read (performance enhance) mode by mistake!
- */
- nor->read_opcode = SPINOR_OP_READ_1_4_4;
- - nor->read_dummy = 8;
- - return 0;
- + return macronix_set_dummy_cycles(nor, 8);
- }
-
- /*
- @@ -1213,6 +1342,9 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
- * entering the continuous read mode by mistake if some
- * performance enhance toggling bits P0-P7 were written during
- * dummy/mode cycles.
- + *
- + * Use the Fast Read Quad Output 1-1-4 (0x6b) command with 8 dummy
- + * cycles (up to 133MHz for STR and 66MHz for DTR).
- */
- status = macronix_quad_enable(nor);
- if (status) {
- @@ -1221,8 +1353,7 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
- }
- nor->read_proto = SNOR_PROTO_1_1_4;
- nor->read_opcode = SPINOR_OP_READ_1_1_4;
- - nor->read_dummy = 8;
- - return 0;
- + return macronix_set_dummy_cycles(nor, 8);
- }
-
- /*
- @@ -1233,16 +1364,25 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
-
- static int macronix_set_dual_mode(struct spi_nor *nor)
- {
- + /*
- + * Use the Fast Read Dual Output 1-1-2 (0x3b) command with 8 dummy
- + * cycles (up to 133MHz for STR and 66MHz for DTR).
- + */
- nor->read_proto = SNOR_PROTO_1_1_2;
- nor->read_opcode = SPINOR_OP_READ_1_1_2;
- - nor->read_dummy = 8;
- - return 0;
- + return macronix_set_dummy_cycles(nor, 8);
- }
-
- static int macronix_set_single_mode(struct spi_nor *nor)
- {
- u8 read_dummy;
-
- + /*
- + * Configure 8 dummy cycles for Fast Read 1-1-1 (0x0b) command (up to
- + * 133MHz for STR and 66MHz for DTR). The Read 1-1-1 (0x03) command
- + * expects no dummy cycle.
- + * read_opcode should not be overridden here!
- + */
- switch (nor->read_opcode) {
- case SPINOR_OP_READ:
- case SPINOR_OP_READ4:
- @@ -1255,8 +1395,7 @@ static int macronix_set_single_mode(struct spi_nor *nor)
- }
-
- nor->read_proto = SNOR_PROTO_1_1_1;
- - nor->read_dummy = read_dummy;
- - return 0;
- + return macronix_set_dummy_cycles(nor, read_dummy);
- }
-
- static int winbond_set_quad_mode(struct spi_nor *nor)
- --
- 2.8.1
|