Skip to contentSkip to conversation

ASPEED SPI driver support for dual IO mode

PATCH Applied Robert Lippert 3 participants 12 messages Jan 10, 2017 – Jan 14, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover ASPEED SPI driver support for dual IO mode

Adds support for dual IO SPI mode. This speeds up SPI accesses, dropping time to dump an entire 64MB Macronix chip from ~12s to ~6s using:
dd if=/dev/mtdblock0 bs=64MB count=1 of=/dev/null

The dual IO bit mode should not depend on any board-specific properties as it uses the same IO lines as single bit mode. Only issue could be if a board used a one-way level tranlator or mux on the MOSI line but that seems unlikely to me.

Tested on Zaius board with AST2500 chip, not tested on AST2400 but I expect it to work since registers are identical.

Note dropped TODO about quad mode since ASPEED SPI controller does not support quad mode.

Changes in v2:
- Cleanups suggested by Cedric.

Robert Lippert (3):
mtd: spi-nor: add SPI_NOR_DUAL_READ to mx66l51235l
mtd: spi-nor: aspeed: add support for SPI dual IO read mode
mtd: spi-nor: aspeed: fix DMA access on AST2500

 drivers/mtd/spi-nor/aspeed-smc.c | 32 ++++++++++++++++++++++++--------
 drivers/mtd/spi-nor/spi-nor.c    |  2 +-
 2 files changed, 25 insertions(+), 9 deletions(-)
Signature · 1 line
2.11.0.390.gc69c2f50cf-goog
#1 lore raw

PATCH v2 1/3 mtd: spi-nor: add SPI_NOR_DUAL_READ to mx66l51235l

---

Changes in v2: None

 drivers/mtd/spi-nor/spi-nor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/spi-nor.c +1 -1
index a68073afe8a8..e508c25a47f7 100644
@@ -857,7 +857,7 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "mx66l1g45g",  INFO(0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_QUAD_READ) },
 	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
 
Signature · 1 line
2.11.0.390.gc69c2f50cf-goog
maintainer
#2 lore raw

Re: [PATCH linux v2 1/3] mtd: spi-nor: add SPI_NOR_DUAL_READ to mx66l51235l

Hi Rob,

Quoted 1 line · Robert Lippert

Feel free add Cedric's Reviewed-by to this patch in subsequent versions when there are no changes.

I added it for you and applied to dev-4.7 as 6860079bb7a6.

Cheers,

Joel

Quoted 27 lines

---

Changes in v2: None

 drivers/mtd/spi-nor/spi-nor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/spi-nor.c +1 -2
index a68073afe8a8..e508c25a47f7 100644
@@ -857,7 +857,7 @@ static const struct flash_info spi_nor_ids[] = {
        { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
+       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
        { "mx66l1g45g",  INFO(0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_QUAD_READ) },
        { "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
 
--

2.11.0.390.gc69c2f50cf-goog

_______________________________________________
openbmc mailing list
[email protected]
https://lists.ozlabs.org/listinfo/openbmc

#3 lore raw

PATCH v2 2/3 mtd: spi-nor: aspeed: add support for SPI dual IO read mode

In reply to Robert Lippert

Implements support for the dual IO read mode on aspeed SMC/FMC controllers which uses both MISO and MOSI lines for data during a read to double the read bandwidth.

---

Changes in v2: None

 drivers/mtd/spi-nor/aspeed-smc.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)
drivers/mtd/spi-nor/aspeed-smc.c +23 -7
index d3bed34f5aa0..3c8e897048c6 100644
@@ -540,6 +540,9 @@ static int aspeed_smc_read_user(struct spi_nor *nor, loff_t from, size_t len,
 {
 	struct aspeed_smc_chip *chip = nor->priv;
 	int ret;
+	u32 ctl;
+	int i;
+	u8 dummy = 0xFF;
 
 	mutex_lock(&chip->controller->mutex);
 
@@ -557,6 +560,18 @@ static int aspeed_smc_read_user(struct spi_nor *nor, loff_t from, size_t len,
 
 	aspeed_smc_start_user(nor);
 	aspeed_smc_send_cmd_addr(nor, nor->read_opcode, from);
+
+	/* Send dummy bytes */
+	for (i = 0; i < chip->nor.read_dummy / 8; ++i)
+		aspeed_smc_write_to_ahb(chip->base, &dummy, 1);
+
+	if (chip->nor.flash_read == SPI_NOR_DUAL) {
+		/* Switch to dual I/O mode for data cycle */
+		ctl = readl(chip->ctl) & ~CONTROL_SPI_IO_MODE_MASK;
+		ctl |= CONTROL_SPI_IO_DUAL_DATA;
+		writel(ctl, chip->ctl);
+	}
+
 	aspeed_smc_read_from_ahb(read_buf, chip->base, len);
 	aspeed_smc_stop_user(nor);
 
@@ -870,16 +885,21 @@ static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
 	case SPI_NOR_FAST:
 		cmd = CONTROL_SPI_COMMAND_MODE_FREAD;
 		break;
+	case SPI_NOR_DUAL:
+		cmd = CONTROL_SPI_COMMAND_MODE_FREAD |
+			CONTROL_SPI_IO_DUAL_DATA;
+		break;
 	default:
 		dev_err(chip->nor.dev, "unsupported SPI read mode\n");
 		return -EINVAL;
 	}
 
 	chip->ctl_val[smc_read] |= cmd |
+		spi_control_fill_opcode(chip->nor.read_opcode) |
 		CONTROL_SPI_IO_DUMMY_CYCLES_SET(chip->nor.read_dummy / 8);
 
-	dev_dbg(controller->dev, "base control register: %08x\n",
-		 chip->ctl_val[smc_read]);
+	dev_dbg(controller->dev, "read control register: %08x\n",
+		chip->ctl_val[smc_read]);
 	return 0;
 }
 
@@ -980,11 +1000,7 @@ static int aspeed_smc_probe(struct platform_device *pdev)
 		if (err)
 			continue;
 
-		/*
-		 * XXX Add support for SPI_NOR_QUAD and SPI_NOR_DUAL attach
-		 * when board support is present as determined by of property.
-		 */
-		err = spi_nor_scan(&chip->nor, NULL, SPI_NOR_NORMAL);
+		err = spi_nor_scan(&chip->nor, NULL, SPI_NOR_DUAL);
 		if (err)
 			continue;
 
Signature · 1 line
2.11.0.390.gc69c2f50cf-goog
maintainer Applied
#5 lore raw

Re: [PATCH linux v2 2/3] mtd: spi-nor: aspeed: add support for SPI dual IO read mode

Quoted 6 lines · Cédric Le Goater
Quoted 5 lines · Robert Lippert

Implements support for the dual IO read mode on aspeed SMC/FMC controllers which uses both MISO and MOSI lines for data during a read to double the read bandwidth.

Applied to dev-4.7 as db7536c39879.

Cheers,

Joel

Quoted 12 lines

Thanks,

C.

_______________________________________________
openbmc mailing list
[email protected]
https://lists.ozlabs.org/listinfo/openbmc

#6 lore raw

PATCH v2 3/3 mtd: spi-nor: aspeed: fix DMA access on AST2500

In reply to Robert Lippert

AST2500 has additional bits in the dma_addr field. Its easier to just write the full address into the register as the hardware will handle the masking properly.

---

Changes in v2:
- Cleanups suggested by Cedric.

 drivers/mtd/spi-nor/aspeed-smc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/aspeed-smc.c +1 -1
index 3c8e897048c6..cd8a43238660 100644
@@ -349,7 +349,7 @@ static int aspeed_smc_dma_wait(struct aspeed_smc_chip *chip)
 }
 
 #define DMA_LENGTH(x) (((x) - 4) & ~0xFE000003)
-#define DMA_ADDR(x) ((x) & ~0xE0000003)
+#define DMA_ADDR(x) ((x) & ~0x00000003)
 
 static inline void aspeed_smc_chip_configure(struct aspeed_smc_chip *chip,
 					     u32 ctl)
Signature · 1 line
2.11.0.390.gc69c2f50cf-goog
maintainer Applied
#7 lore raw

Re: [PATCH linux v2 3/3] mtd: spi-nor: aspeed: fix DMA access on AST2500

Quoted 5 lines · Robert Lippert

AST2500 has additional bits in the dma_addr field. Its easier to just write the full address into the register as the hardware will handle the masking properly.

Applied to dev-4.7 as db7536c39879.

Cheers,

Quoted 28 lines

---

Changes in v2:
- Cleanups suggested by Cedric.

 drivers/mtd/spi-nor/aspeed-smc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/aspeed-smc.c +1 -2
index 3c8e897048c6..cd8a43238660 100644
@@ -349,7 +349,7 @@ static int aspeed_smc_dma_wait(struct aspeed_smc_chip *chip)
 }
 
 #define DMA_LENGTH(x) (((x) - 4) & ~0xFE000003)
-#define DMA_ADDR(x) ((x) & ~0xE0000003)
+#define DMA_ADDR(x) ((x) & ~0x00000003)
 
 static inline void aspeed_smc_chip_configure(struct aspeed_smc_chip *chip,
                                             u32 ctl)
--

2.11.0.390.gc69c2f50cf-goog

_______________________________________________
openbmc mailing list
[email protected]
https://lists.ozlabs.org/listinfo/openbmc

#8 lore raw
In reply to Robert Lippert

Hello Robert,

Quoted 10 lines · Robert Lippert

Adds support for dual IO SPI mode. This speeds up SPI accesses, dropping time to dump an entire 64MB Macronix chip from ~12s to ~6s using:
dd if=/dev/mtdblock0 bs=64MB count=1 of=/dev/null

The dual IO bit mode should not depend on any board-specific properties as it uses the same IO lines as single bit mode. Only issue could be if a board used a one-way level tranlator or mux on the MOSI line but that seems unlikely to me.

Quoted 8 lines

Tested on Zaius board with AST2500 chip, not tested on AST2400 but I expect it to work since registers are identical.

Note dropped TODO about quad mode since ASPEED SPI controller does not support quad mode.

Changes in v2:
- Cleanups suggested by Cedric.

could you please give a quick try to this kernel :

https://github.com/legoater/linux/commits/openbmc-4.7

This is an openbmc 4.7 kernel with a backport of the mainline smc driver, dma support, fastread support and your dual io support.

I have tested it on a palmetto and an ast2500 evb but I don't have the HW you use.

Thanks,

C.

#9 lore raw
Quoted 24 lines · Cédric Le Goater

Hello Robert,

Quoted 10 lines · Robert Lippert

Adds support for dual IO SPI mode. This speeds up SPI accesses, dropping time to dump an entire 64MB Macronix chip from ~12s to ~6s using:
dd if=/dev/mtdblock0 bs=64MB count=1 of=/dev/null

The dual IO bit mode should not depend on any board-specific properties as it uses the same IO lines as single bit mode. Only issue could be if a board used a one-way level tranlator or mux on the MOSI line but that seems unlikely to me.

Quoted 8 lines

Tested on Zaius board with AST2500 chip, not tested on AST2400 but I expect it to work since registers are identical.

Note dropped TODO about quad mode since ASPEED SPI controller does not support quad mode.

Changes in v2:
- Cleanups suggested by Cedric.

could you please give a quick try to this kernel :

Quoted 7 lines

https://github.com/legoater/linux/commits/openbmc-4.7

This is an openbmc 4.7 kernel with a backport of the mainline smc driver, dma support, fastread support and your dual io support.

I have tested it on a palmetto and an ast2500 evb but I don't have the HW you use.

Tested it after fixing a compilation error for s/CONTROL_SPI_IO/CONTROL_IO/ and it works on Zaius board.

But it seems to be a bit slower, about half as fast as I saw before. I think it is due to your branch missing this commit from the openbmc tree:

423ac0dc0117f411244c38b7a351664a4c30c19a mtd: spi-nor: aspeed: rework io routines

Thanks,
-Rob

#10 lore raw
Quoted 33 lines · Rob Lippert
Quoted 24 lines · Cédric Le Goater

Hello Robert,

Quoted 10 lines · Robert Lippert

Adds support for dual IO SPI mode. This speeds up SPI accesses, dropping time to dump an entire 64MB Macronix chip from ~12s to ~6s using:
dd if=/dev/mtdblock0 bs=64MB count=1 of=/dev/null

The dual IO bit mode should not depend on any board-specific properties as it uses the same IO lines as single bit mode. Only issue could be if a board used a one-way level tranlator or mux on the MOSI line but that seems unlikely to me.

Quoted 8 lines

Tested on Zaius board with AST2500 chip, not tested on AST2400 but I expect it to work since registers are identical.

Note dropped TODO about quad mode since ASPEED SPI controller does not support quad mode.

Changes in v2:
- Cleanups suggested by Cedric.

could you please give a quick try to this kernel :

Quoted 7 lines

https://github.com/legoater/linux/commits/openbmc-4.7

This is an openbmc 4.7 kernel with a backport of the mainline smc driver, dma support, fastread support and your dual io support.

I have tested it on a palmetto and an ast2500 evb but I don't have the HW you use.

Quoted 6 lines

Tested it after fixing a compilation error for s/CONTROL_SPI_IO/CONTROL_IO/ and it works on Zaius board.

But it seems to be a bit slower, about half as fast as I saw before. I think it is due to your branch missing this commit from the openbmc tree:

Scratch that, speed is the same between the openbmc tree and upstream tree after retesting. I was just misremembering the timing...

-Rob

Quoted 3 lines

423ac0dc0117f411244c38b7a351664a4c30c19a mtd: spi-nor: aspeed: rework io routines

#11 lore raw
In reply to Rob Lippert
Quoted 4 lines
Quoted 4 lines

could you please give a quick try to this kernel :

https://github.com/legoater/linux/commits/openbmc-4.7

Quoted 8 lines
Quoted 5 lines

This is an openbmc 4.7 kernel with a backport of the mainline smc driver, dma support, fastread support and your dual io support.

I have tested it on a palmetto and an ast2500 evb but I don't have the HW you use.

Tested it after fixing a compilation error for s/CONTROL_SPI_IO/CONTROL_IO/ and it works on Zaius board.

ah. my bad. Thanks for fixing. I will update the tree.

Quoted 6 lines

But it seems to be a bit slower, about half as fast as I saw before. I think it is due to your branch missing this commit from the openbmc tree:

423ac0dc0117f411244c38b7a351664a4c30c19a mtd: spi-nor: aspeed: rework io routines

hmm, mainline asked for a rewrite of these. I will take a closer look.

Thanks,

C.