Skip to contentSkip to conversation

Tegra210: add QSPI driver

PATCH New Tom Warren 2 participants 4 messages Oct 9, 2015 – Oct 12, 2015

Subsystems (2)
lore
Share & tools
lore

Tom Warren

author
#0 lore raw

PATCH 1/1 Tegra210: add QSPI driver

From: Yen Lin <[email protected]>

Tested on P2571 board with Winbond SPI ROM.
sf probe 2:0 to see SPI chip. Flashed U-Boot image to SPI, rebooted, read back data to RAM with sf read, then verified crc against original binary file.

Author: Yen Lin <[email protected]>

---
 board/nvidia/p2571/pinmux-config-p2571.h |  14 +-
 configs/p2571_defconfig                  |   1 +
 drivers/spi/Kconfig                      |   5 +
 drivers/spi/Makefile                     |   1 +
 drivers/spi/tegra210_qspi.c              | 424 +++++++++++++++++++++++++++++++
 5 files changed, 439 insertions(+), 6 deletions(-)
 create mode 100644 drivers/spi/tegra210_qspi.c
board/nvidia/p2571/pinmux-config-p2571.h +8 -6
index d323301..83b4b99 100644
@@ -210,12 +210,14 @@ static const struct pmux_pingrp_config p2571_pingrps[] = {
 	PINCFG(DP_HPD0_PCC6,         RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(PCC7,                 RSVD0,    DOWN,   TRISTATE, OUTPUT,  DISABLE, NORMAL),
 	PINCFG(SPI2_CS1_PDD0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_SCK_PEE0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_CS_N_PEE1,       RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO0_PEE2,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO1_PEE3,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO2_PEE4,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO3_PEE5,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
+	PINCFG(QSPI_SCK_PEE0,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_CS_N_PEE1,       QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO0_PEE2,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO1_PEE3,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO2_PEE4,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(QSPI_IO3_PEE5,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
 	PINCFG(CORE_PWR_REQ,         CORE,     NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(CPU_PWR_REQ,          CPU,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(PWR_INT_N,            PMI,      UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
configs/p2571_defconfig +1 -0
index 5a592e9..7c19428 100644
@@ -12,5 +12,6 @@ CONFIG_SYS_PROMPT="Tegra210 (P2571) # "
 # CONFIG_CMD_NFS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_TEGRA114_SPI=y
+CONFIG_TEGRA210_QSPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
drivers/spi/Kconfig +5 -0
index 8e04fce..168f31d 100644
@@ -115,6 +115,11 @@ config TEGRA20_SLINK
 	  be used to access the SPI NOR flash on platforms embedding this
 	  nVidia Tegra20/Tegra30 IP cores.
 
+config TEGRA210_QSPI
+	bool "nVidia Tegra210 QSPI driver"
+	help
+	  Enable the Tegra Quad-SPI (QSPI) driver for T210.
+
 config XILINX_SPI
 	bool "Xilinx SPI driver"
 	help
drivers/spi/Makefile +1 -0
index de241be..209a41e 100644
@@ -46,6 +46,7 @@ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
 obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
 obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
 obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+obj-$(CONFIG_TEGRA210_QSPI) += tegra210_qspi.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
drivers/spi/tegra210_qspi.c new file +424 -0

424 lines not on this page · raw message

Signature · 1 line
1.8.2.1.610.g562af5b
author
#1 lore raw

PATCH 1/1 Tegra210: add QSPI driver

Forgot Jagan

-----Original Message-----
From: Tom Warren
Sent: Friday, October 09, 2015 11:16 AM
To: u-boot at lists.denx.de
Cc: Stephen Warren <[email protected]>; tomcwarren3959 at gmail.com; Yen Lin <[email protected]>; Tom Warren <[email protected]>
Subject: [PATCH] Tegra210: add QSPI driver

From: Yen Lin <[email protected]>

Tested on P2571 board with Winbond SPI ROM.
sf probe 2:0 to see SPI chip. Flashed U-Boot image to SPI, rebooted, read back data to RAM with sf read, then verified crc against original binary file.

Author: Yen Lin <[email protected]>

---
 board/nvidia/p2571/pinmux-config-p2571.h |  14 +-
 configs/p2571_defconfig                  |   1 +
 drivers/spi/Kconfig                      |   5 +
 drivers/spi/Makefile                     |   1 +
 drivers/spi/tegra210_qspi.c              | 424 +++++++++++++++++++++++++++++++
 5 files changed, 439 insertions(+), 6 deletions(-)  create mode 100644 drivers/spi/tegra210_qspi.c
board/nvidia/p2571/pinmux-config-p2571.h +8 -6
index d323301..83b4b99 100644
@@ -210,12 +210,14 @@ static const struct pmux_pingrp_config p2571_pingrps[] = {
 	PINCFG(DP_HPD0_PCC6,         RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(PCC7,                 RSVD0,    DOWN,   TRISTATE, OUTPUT,  DISABLE, NORMAL),
 	PINCFG(SPI2_CS1_PDD0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_SCK_PEE0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_CS_N_PEE1,       RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO0_PEE2,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO1_PEE3,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO2_PEE4,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO3_PEE5,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
+	PINCFG(QSPI_SCK_PEE0,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_CS_N_PEE1,       QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO0_PEE2,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO1_PEE3,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO2_PEE4,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(QSPI_IO3_PEE5,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
 	PINCFG(CORE_PWR_REQ,         CORE,     NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(CPU_PWR_REQ,          CPU,      NORMAL, NORMAL,   OUTPUT,  DISABLE, DEFAULT),
 	PINCFG(PWR_INT_N,            PMI,      UP,     NORMAL,   INPUT,   DISABLE, DEFAULT),
configs/p2571_defconfig +1 -0
@@ -12,5 +12,6 @@ CONFIG_SYS_PROMPT="Tegra210 (P2571) # "
 # CONFIG_CMD_NFS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_TEGRA114_SPI=y
+CONFIG_TEGRA210_QSPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
drivers/spi/Kconfig +5 -0
@@ -115,6 +115,11 @@ config TEGRA20_SLINK
 	  be used to access the SPI NOR flash on platforms embedding this
 	  nVidia Tegra20/Tegra30 IP cores.
 
+config TEGRA210_QSPI
+	bool "nVidia Tegra210 QSPI driver"
+	help
+	  Enable the Tegra Quad-SPI (QSPI) driver for T210.
+
 config XILINX_SPI
 	bool "Xilinx SPI driver"
 	help
drivers/spi/Makefile +1 -0
@@ -46,6 +46,7 @@ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
 obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
 obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
 obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+obj-$(CONFIG_TEGRA210_QSPI) += tegra210_qspi.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
drivers/spi/tegra210_qspi.c new file +416 -0

416 lines not on this page · raw message

--
1.8.2.1.610.g562af5b
--
nvpublic

#2 lore raw

PATCH 1/1 Tegra210: add QSPI driver

Quoted 7 lines · Tom Warren

From: Yen Lin <[email protected]>

Tested on P2571 board with Winbond SPI ROM.
sf probe 2:0 to see SPI chip. Flashed U-Boot image to SPI, rebooted, read back data to RAM with sf read, then verified crc against original binary file.

  board/nvidia/p2571/pinmux-config-p2571.h |  14 +-
  configs/p2571_defconfig                  |   1 +

As a general comment, driver changes should be in separate patches to board changes to enable the driver. The two things are logically separate, and this also helps when cherry-picking patches between branches that might not have p2571 support.

Quoted 5 lines
board/nvidia/p2571/pinmux-config-p2571.h +0 -3
 
-	PINCFG(QSPI_SCK_PEE0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_CS_N_PEE1,       RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO0_PEE2,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),

board/nvidia/p2571/pinmux-config-p2571.h static const struct pmux_pingrp_config p2571_pingrps[] = { · line 219

Quoted 10 lines
board/nvidia/p2571/pinmux-config-p2571.h +7 -3
-	PINCFG(QSPI_IO1_PEE3,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO2_PEE4,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO3_PEE5,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
+	PINCFG(QSPI_SCK_PEE0,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_CS_N_PEE1,       QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO0_PEE2,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO1_PEE3,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO2_PEE4,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(QSPI_IO3_PEE5,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),

The current pinmux matches the syseng-supplied spreadsheet. If the spreadsheet is wrong, please get syseng to update the spreadsheet first. The pinmux files must not be manually edited, so we ensure that the mandated pinmux is used.

drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000..d827667

Quoted 9 lines
drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000..d827667 renamed from drivers/spi/tegra210_qspi.c +6 -0
 
 
+static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) {
+	struct tegra_spi_platdata *plat = bus->platdata;
+	const void *blob = gd->fdt_blob;
+	int node = bus->of_offset;
+
+	plat->base = fdtdec_get_addr(blob, node, "reg");

I think that should use dev_get_addr() now, since that does the correct thing w.r.t. #address-cells/#size-cells.

Quoted 5 lines
drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000..d827667 renamed from drivers/spi/tegra210_qspi.c +4 -0
+static int tegra210_qspi_claim_bus(struct udevice *bus) {
 
+	/* Clear stale status here */
+	setbits_le32(&regs->fifo_status,
+		     QSPI_FIFO_STS_ERR		|

drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000..d827667

Quoted 10 lines
drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000..d827667 renamed from drivers/spi/tegra210_qspi.c +10 -0
+		     QSPI_FIFO_STS_TX_FIFO_OVF	|
+		     QSPI_FIFO_STS_TX_FIFO_UNR	|
+		     QSPI_FIFO_STS_RX_FIFO_OVF	|
+		     QSPI_FIFO_STS_RX_FIFO_UNR	|
+		     QSPI_FIFO_STS_TX_FIFO_FULL	|
+		     QSPI_FIFO_STS_TX_FIFO_EMPTY	|
+		     QSPI_FIFO_STS_RX_FIFO_FULL	|
+		     QSPI_FIFO_STS_RX_FIFO_EMPTY);
+	debug("%s: FIFO STATUS = %08x\n", __func__,
+readl(&regs->fifo_status));

Indentation issue.

I would expect at least that setbits_le32() to happen inside the transfer function so that every transfer is immune to stale status, not just the first transfer after the bus is cleared.

Actually, it looks like the transfer function already does this, so the above code can simply be dropped.

Perhaps the other HW-touching code might be moved to, but it's probably fine to leave it here.

author
#3 lore raw

PATCH 1/1 Tegra210: add QSPI driver

Stephen,

-----Original Message-----
From: Stephen Warren [mailto:swarren at wwwdotorg.org]
Sent: Friday, October 09, 2015 11:51 AM
To: Tom Warren <[email protected]>
Cc: u-boot at lists.denx.de; Jagan Teki <[email protected]>; Stephen Warren <[email protected]>; tomcwarren3959 at gmail.com
Subject: Re: [U-Boot] [PATCH] Tegra210: add QSPI driver

Quoted 7 lines · Tom Warren

From: Yen Lin <[email protected]>

Tested on P2571 board with Winbond SPI ROM.
sf probe 2:0 to see SPI chip. Flashed U-Boot image to SPI, rebooted, read back data to RAM with sf read, then verified crc against original binary file.

  board/nvidia/p2571/pinmux-config-p2571.h |  14 +-
  configs/p2571_defconfig                  |   1 +

As a general comment, driver changes should be in separate patches to board changes to enable the driver. The two things are logically separate, and this also helps when cherry-picking patches between branches that might not have p2571 support.

True, my bad. I'll resubmit.

Quoted 6 lines
board/nvidia/p2571/pinmux-config-p2571.h +0 -3
 
-	PINCFG(QSPI_SCK_PEE0,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_CS_N_PEE1,       RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO0_PEE2,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),

board/nvidia/p2571/pinmux-config-p2571.h static const struct pmux_pingrp_config p2571_pingrps[] = { · line 219

Quoted 10 lines
board/nvidia/p2571/pinmux-config-p2571.h +7 -3
-	PINCFG(QSPI_IO1_PEE3,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO2_PEE4,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
-	PINCFG(QSPI_IO3_PEE5,        RSVD1,    DOWN,   TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+
+	PINCFG(QSPI_SCK_PEE0,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_CS_N_PEE1,       QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO0_PEE2,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO1_PEE3,        QSPI,     NORMAL, NORMAL,   INPUT,   DISABLE, DEFAULT),
+	PINCFG(QSPI_IO2_PEE4,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),
+	PINCFG(QSPI_IO3_PEE5,        QSPI,     UP,     TRISTATE, OUTPUT,  DISABLE, DEFAULT),

The current pinmux matches the syseng-supplied spreadsheet. If the spreadsheet is wrong, please get syseng to update the spreadsheet first. The pinmux files must not be manually edited, so we ensure that the mandated pinmux is used.

Valid point, I'm still used to changing the pinmux as desired to get new devices up. I'll pull down the latest P2571 spreadsheet and have it changed if it hasn't already been. Once it's corrected, I assume you can generate a new pinmux header and post a patch that I can put in ahead of the QSPI patches.

drivers/spi/tegra210_qspi.c line 116

Quoted 10 lines
drivers/spi/tegra210_qspi.c new file +6 -0
new file mode 100644 index 0000000..d827667
 
 
+static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) {
+	struct tegra_spi_platdata *plat = bus->platdata;
+	const void *blob = gd->fdt_blob;
+	int node = bus->of_offset;
+
+	plat->base = fdtdec_get_addr(blob, node, "reg");

I think that should use dev_get_addr() now, since that does the correct thing w.r.t. #address-cells/#size-cells.

Ok, I'll take a look. Thanks.

Quoted 5 lines
drivers/spi/tegra210_qspi.c new file +4 -0
+static int tegra210_qspi_claim_bus(struct udevice *bus) {
 
+	/* Clear stale status here */
+	setbits_le32(&regs->fifo_status,
+		     QSPI_FIFO_STS_ERR		|

drivers/spi/tegra210_qspi.c line 169

Quoted 10 lines
drivers/spi/tegra210_qspi.c new file +10 -0
+		     QSPI_FIFO_STS_TX_FIFO_OVF	|
+		     QSPI_FIFO_STS_TX_FIFO_UNR	|
+		     QSPI_FIFO_STS_RX_FIFO_OVF	|
+		     QSPI_FIFO_STS_RX_FIFO_UNR	|
+		     QSPI_FIFO_STS_TX_FIFO_FULL	|
+		     QSPI_FIFO_STS_TX_FIFO_EMPTY	|
+		     QSPI_FIFO_STS_RX_FIFO_FULL	|
+		     QSPI_FIFO_STS_RX_FIFO_EMPTY);
+	debug("%s: FIFO STATUS = %08x\n", __func__, 
+readl(&regs->fifo_status));

Indentation issue.

I would expect at least that setbits_le32() to happen inside the transfer function so that every transfer is immune to stale status, not just the first transfer after the bus is cleared.

Actually, it looks like the transfer function already does this, so the above code can simply be dropped.

Perhaps the other HW-touching code might be moved to, but it's probably fine to leave it here.

Yen wrote and debugged this driver awhile back - I don't know why he wasn't included by 'send-email', but I've added him to the CC list.

Thanks,

Tom
--
nvpublic