Skip to contentSkip to conversation

Documentation: dt: spi-bcm-qspi: NSP, NS2, BRCMSTB SoC bindings

PATCH In review Kamal Dasu 4 participants 27 messages Jun 17, 2016 – Jul 29, 2016 19 messages not in the archive

Subsystems (5)
lore
Share & tools
lore

Kamal Dasu

author
#0 lore raw

PATCH v4 1/5 Documentation: dt: spi-bcm-qspi: NSP, NS2, BRCMSTB SoC bindings

Added device tree bindings documentation for SoCs supported by the new spi-bcm-qspi driver.

---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 227 +++++++++++++++++++++
 1 file changed, 227 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt new file +227 -0
new file mode 100644
index 0000000..4c3f7e3
@@ -0,0 +1,227 @@
+Broadcom SPI controller
+
+The Broadcom SPI controller is a SPI master found on various SOCs, including
+BRCMSTB (BCM7XXX), Cygnus, NSP and NS2.
+
+Required properties:
+
+- #address-cells:
+    Must be <1>, as required by generic SPI binding.
+
+- #size-cells:
+    Must be <0>, also as required by generic SPI binding.
+
+- compatible:
+    Must be one of :
+    "brcm,spi-bcm-qspi"
+    "brcm,spi-brmstb" spi-nor and/or "brcm,spi-brmstb-mspi" unmanaged SPI Master
+
+- reg:
+    Define the bases and ranges of the associated I/O address spaces.
+    The required range is MSPI controller registers and interrupt registers, the others
+    are optional Boot SPI (BSPI) portion for fast flash reads.
+
+- reg-names:
+    First name does not matter, but must be reserved for the MSPI controller
+    register range as mentioned in 'reg' above, and will typically contain
+    - "bspi_regs": BSPI register range
+    - "mspi_regs": MSPI register range
+    - "intr_regs", "intr_status_reg" : Interrupt and status register for NSP, NS2 SoC
+    - "hif_spi_intr2" : Interrupt and status register for BRCMSTB SoC
+
+- interrupts
+    The interrupts used by the MSPI and/or BSPI controller.
+
+- interrupt-names:
+    Names of interrupts associated with this MSPI and/or BSPI controller.
+    - "mspi_halted" :
+    - "mspi_done": Indicates that the requested SPI operation is complete.
+    - "spi_lr_fullness_reached" : Linear read BSPI pipe full
+    - "spi_lr_session_aborted"  : Linear read BSPI pipe aborted
+    - "spi_lr_impatient" : Linear read BSPI requested when pipe empty
+    - "spi_lr_session_done" : Linear read BSPI session done
+
+Optional properties:
+
+- clocks:
+    A phandle to the reference clock for this block.  If not present, will
+    assume a 27 MHz fixed clock (default for UPG).
+
+
+Optional properties:
+
+- clocks:
+    A phandle to the reference clock for this block.
+
+- bspi-sel:
+    Chip selects that requires bspi support.
+
+Examples:
+
+BRCMSTB SoC Example:
+
+  SPI Master for SPI-NOR:
+
+    spi@f03e3400 {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "brcm,qspi-brcmstb";
+		reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>;
+		reg-names = "cs_reg", "hif_mspi", "bspi";
+		interrupts = <0x6 0x5 0x4 0x3 0x2 0x1 0x0>;
+		interrupt-parent = <0x1c>;
+		interrupt-names = "mspi_halted",
+				  "mspi_done",
+				  "spi_lr_overread",
+				  "spi_lr_session_done",
+				  "spi_lr_impatient",
+				  "spi_lr_session_aborted",
+				  "spi_lr_fullness_reached";
+
+		clocks = <0x1b>;
+		clock-names = "sw_spi";
+
+		m25p80@0 {
+			#size-cells = <0x2>;
+			#address-cells = <0x2>;
+			compatible = "m25p80";
+			reg = <0x0>;
+			spi-max-frequency = <0x2625a00>;
+			spi-cpol;
+			spi-cpha;
+			use-bspi;
+			m25p,fast-read;
+
+			flash0.bolt@0 {
+				reg = <0x0 0x0 0x0 0x100000>;
+			};
+
+			flash0.macadr@100000 {
+				reg = <0x0 0x100000 0x0 0x10000>;
+			};
+
+			flash0.nvram@110000 {
+				reg = <0x0 0x110000 0x0 0x10000>;
+			};
+
+			flash0.kernel@120000 {
+				reg = <0x0 0x120000 0x0 0x400000>;
+			};
+
+			flash0.devtree@520000 {
+				reg = <0x0 0x520000 0x0 0x10000>;
+			};
+
+			flash0.splash@530000 {
+				reg = <0x0 0x530000 0x0 0x80000>;
+			};
+
+			flash0@0 {
+				reg = <0x0 0x0 0x0 0x4000000>;
+			};
+		};
+	};
+
+
+    MSPI master:
+
+		spi@f0416000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&upg_fixed>;
+			compatible = "brcm,spi-brcmstb-mspi";
+			reg = <0xf0416000 0x180>;
+			reg-names = "mspi";
+			interrupts = <0x14>;
+			interrupt-parent = <&irq0_aon_intc>;
+			interrupt-names = "mspi_done";
+		};
+
+
+
+iProc SoC Example:
+
+    qspi: spi@18027200 {
+        compatible = "brcm,spi-bcm-qspi";
+        reg = <0x18027200 0x184>,
+	      <0x18027000 0x124>,
+              <0x1811c408 0x004>,
+              <0x180273a0 0x01c>;
+        reg-names = "mspi_regs", "bspi_regs", "intr_regs", "intr_status_reg";
+        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names =
+		     "spi_lr_fullness_reached",
+ 		     "spi_lr_session_aborted",
+		     "spi_lr_impatient",
+		     "spi_lr_session_done",
+		     "mspi_done",
+		     "mspi_halted";
+        clocks = <&iprocmed>;
+        clock-names = "iprocmed";
+        clock-frequency = <12500000>;
+        num-cs = <2>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
+
+
+ NS2 SoC Example:
+
+               qspi: spi@66470200 {
+                       compatible = "brcm,spi-bcm-qspi";
+                       reg = <0x66470200 0x184>,
+                             <0x66470000 0x124>,
+                             <0x67017408 0x004>,
+                             <0x664703a0 0x01c>;
+                       reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg";
+                       interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "spi_l1_intr";
+                        clocks = <&iprocmed>;
+                        clock-names = "iprocmed";
+                        clock-frequency = <12500000>;
+                        num-cs = <2>;
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+               };
+
+
+ m25p80 node for NSP, NS2 and iProc
+
+ 	 &qspi {
+    	     bspi-sel = <0>;
+       	     flash: m25p80@0 {
+             	      #address-cells = <1>;
+               	      #size-cells = <1>;
+		      compatible = "m25p80";
+		      reg = <0x0>;
+		      spi-max-frequency = <12500000>;
+		      m25p,fast-read;
+		      spi-cpol;
+		      spi-cpha;
+
+		      partition@0 {
+		      		  label = "boot";
+				  reg = <0x00000000 0x000a0000>;
+		      };
+
+		      partition@1 {
+		      		  label = "env";
+				  reg = <0x000a0000 0x00060000>;
+		      };
+
+		      partition@2 {
+		      		  label = "system";
+				  reg = <0x00100000 0x00600000>;
+		      };
+
+		      partition@3 {
+		      		  label = "rootfs";
+				  reg = <0x00700000 0x01900000>;
+		      };
+	 };
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1466197433-11290-1-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

author
#2 lore raw

PATCH v4 2/5 spi: bcm-qspi: Add SPI flash and MSPI driver

Adding unified SPI flash and MSPI driver for Broadcom BRCMSTB, NS2, NSP SoCs. Driver shall work with brcm,7120-l2-intc or brcm-l2-intc or with a single muxed L1 interrupt source. Driver implements the transfer_one() method for standard spi transfers and supports spi_flash_read so that the SoC controller can provide faster accelerated reads.

---
 drivers/spi/Kconfig        |   10 +
 drivers/spi/Makefile       |    1 +
 drivers/spi/spi-bcm-qspi.c | 1684 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1695 insertions(+)
 create mode 100644 drivers/spi/spi-bcm-qspi.c
drivers/spi/Kconfig +10 -0
index 4b931ec..d408628 100644
@@ -153,6 +153,16 @@ config SPI_BCM63XX_HSSPI
 	  This enables support for the High Speed SPI controller present on
 	  newer Broadcom BCM63XX SoCs.
 
+config SPI_BCM_QSPI
+	tristate "Broadcom BSPI and MSPI controller support"
+	depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_NSP || \
+			ARCH_BCM_CYGNUS || COMPILE_TEST
+	help
+	  Enables support for the Broadcom SPI flash and MSPI controller.
+	  Select this option for any one of BRCMSTB, Cygnus, NSP, NS2 SoCs
+	  based platforms. This driver works for both SPI master for spi-nor
+	  flash device as well as MSPI device.
+
 config SPI_BITBANG
 	tristate "Utilities for Bitbanging SPI masters"
 	help
drivers/spi/Makefile +1 -0
index 3c74d00..2c356c7 100644
@@ -21,6 +21,7 @@ obj-$(CONFIG_SPI_BCM2835AUX)		+= spi-bcm2835aux.o
 obj-$(CONFIG_SPI_BCM53XX)		+= spi-bcm53xx.o
 obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o
 obj-$(CONFIG_SPI_BCM63XX_HSSPI)		+= spi-bcm63xx-hsspi.o
+obj-$(CONFIG_SPI_BCM_QSPI)		+= spi-bcm-qspi.o
 obj-$(CONFIG_SPI_BFIN5XX)		+= spi-bfin5xx.o
 obj-$(CONFIG_SPI_ADI_V3)                += spi-adi-v3.o
 obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o
drivers/spi/spi-bcm-qspi.c new file +1684 -0

1,684 lines not on this page · raw message

Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1466197433-11290-2-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#4 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

drivers/spi/spi-bcm-qspi.c line 42

Quoted 11 lines · Kamal Dasu

Adding unified SPI flash and MSPI driver for Broadcom BRCMSTB, NS2, NSP SoCs. Driver shall work with brcm,7120-l2-intc or brcm-l2-intc or with a single muxed L1 interrupt source. Driver implements the transfer_one() method for standard spi transfers and supports spi_flash_read so that the SoC controller can provide faster accelerated reads.

drivers/spi/spi-bcm-qspi.c new file +3 -0
+#define STATE_IDLE				0
+#define STATE_RUNNING				1
+#define STATE_SHUTDOWN				2

There's a lot of defines with very generic names that look like they should be namespaced.

drivers/spi/spi-bcm-qspi.c line 180

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+#define DWORD_ALIGNED(a)			IS_ALIGNED((uintptr_t)(a), 4)
+#define ADDR_TO_4MBYTE_SEGMENT(addr)		(((u32)(addr)) >> 22)

This just doesn't belong in a driver, there's nothing driver specific about it. It should go in a generic header if it's useful.

drivers/spi/spi-bcm-qspi.c line 280

Quoted 12 lines
drivers/spi/spi-bcm-qspi.c new file +12 -0
+	/*
+	 * MIPS endianness is configured by boot strap, which also reverses all
+	 * bus endianness (i.e., big-endian CPU + big endian bus ==> native
+	 * endian I/O).
+	 *
+	 * Other architectures (e.g., ARM) either do not support big endian, or
+	 * else leave I/O in little endian mode.
+	 */
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+		return ioread32be(qspi->base[type] + offset);
+	else
+		return readl_relaxed(qspi->base[type] + offset);

Just put this in the DT like we do for other MIPS IPs.

drivers/spi/spi-bcm-qspi.c line 307

Quoted 13 lines
drivers/spi/spi-bcm-qspi.c new file +13 -0
+/* Interrupt helpers when not using brcm intc driver */
+static void bcm_qspi_enable_interrupt(struct bcm_qspi *qspi, u32 mask)
+{
+	unsigned int val;
+
+	if (qspi->hif_spi_mode) {
+		bcm_qspi_write(qspi, INTR, HIF_SPI_INTR2_CPU_MASK_CLEAR, mask);
+	} else {
+		val = bcm_qspi_read(qspi, INTR, 0);
+		val = val | (mask << INTR_BASE_BIT_SHIFT);
+		bcm_qspi_write(qspi, INTR, 0, val);
+	}
+}

All this interrupt code and especially the fact that it's a completely separate register range in the binding looks very much like it's just an interrupt controller IP that's not particularly anything to do with the SPI controller and should therefore be in a separate driver. Why is this part of the SPI controller driver?

drivers/spi/spi-bcm-qspi.c line 533

Quoted 7 lines
drivers/spi/spi-bcm-qspi.c new file +7 -0
+static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width,
+				      int addrlen, int hp)
+{
+	u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
+
+	pr_debug("set override mode w %x addrlen %x hp %d\n",
+		 width, addrlen, hp);

dev_dbg(). If you've got a device prints should use it, it makes reading logs vastly easier.

Quoted 9 lines
drivers/spi/spi-bcm-qspi.c new file +9 -0
+	switch (width) {
+	case SPI_NBITS_QUAD:
+		/* clear dual mode and set quad mode */
+		data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+		data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD;
+		break;
+	case SPI_NBITS_DUAL:
+		/* clear quad mode set dual mode */
+		data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD;

drivers/spi/spi-bcm-qspi.c line 553

Quoted 10 lines
drivers/spi/spi-bcm-qspi.c new file +10 -0
+		data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+		break;
+	case SPI_NBITS_SINGLE:
+		/* clear quad/dual mode */
+		data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD |
+			  BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL);
+		break;
+	default:
+		break;
+	}

We just ignore other widths?

drivers/spi/spi-bcm-qspi.c line 656

Quoted 5 lines
drivers/spi/spi-bcm-qspi.c new file +5 -0
+static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi)
+{
+
+	if ((!qspi->base[BSPI]) || (qspi->bspi_enabled))
+		return;

Why would it be OK to call this if we don't have BSPI?

drivers/spi/spi-bcm-qspi.c line 732

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+	xp->mode = spi->mode;
+	xp->bits_per_word = spi->bits_per_word ? spi->bits_per_word : 8;

Write normal if statements for legibility please.

Quoted 9 lines
drivers/spi/spi-bcm-qspi.c new file +9 -0
+/* MSPI helpers */
+
+/* stop at end of transfer, no other reason */
+#define FNB_BREAK_NONE			0
+/* stop at end of spi_message */
+#define FNB_BREAK_EOM			1
+/* stop at end of spi_transfer if delay */
+#define FNB_BREAK_DELAY			2
+/* stop at end of spi_transfer if cs_change */

drivers/spi/spi-bcm-qspi.c line 755

Quoted 10 lines
drivers/spi/spi-bcm-qspi.c new file +10 -0
+#define FNB_BREAK_CS_CHANGE		4
+/* stop if we run out of bytes */
+#define FNB_BREAK_NO_BYTES		8
+
+/* events that make us stop filling TX slots */
+#define FNB_BREAK_TX			(FNB_BREAK_EOM | FNB_BREAK_DELAY | \
+					 FNB_BREAK_CS_CHANGE)
+
+/* events that make us deassert CS */
+#define FNB_BREAK_DESELECT		(FNB_BREAK_EOM | FNB_BREAK_CS_CHANGE)

This block of defies is just randomly in the middle of the driver?

drivers/spi/spi-bcm-qspi.c line 760

Quoted 4 lines
drivers/spi/spi-bcm-qspi.c new file +4 -0
+static int find_next_byte(struct bcm_qspi *qspi, struct position *p,
+			  int flags)
+{
+	int ret = FNB_BREAK_NONE;

I'm unclear what this is intended to do, I suspect other readers might be too.

drivers/spi/spi-bcm-qspi.c line 1032

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+static int bcm_qspi_flash_read(struct spi_device *spi,
+			       struct spi_flash_read_message *msg)

There's a lot of flash code in the driver, it would make review a lot easier to split this out into a followup patch so we have one patch with the standard SPI controller and some more adding the flash acceleration.

drivers/spi/spi-bcm-qspi.c line 1094

Quoted 3 lines
drivers/spi/spi-bcm-qspi.c new file +3 -0
+static void bcm_qspi_trans_mode(struct bcm_qspi *qspi,
+				struct spi_device *spi,
+				struct spi_transfer *trans)

This still appears to be trying to parse the data in SPI transfers. Please don't do this, remove this code in favour of using the accelerated flash operations.

drivers/spi/spi-bcm-qspi.c line 1432

Quoted 4 lines
drivers/spi/spi-bcm-qspi.c new file +4 -0
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi");
+	if (!res)
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   "mspi");

Why support both names?

drivers/spi/spi-bcm-qspi.c line 1441

Quoted 8 lines
drivers/spi/spi-bcm-qspi.c new file +8 -0
+	if (res) {
+		qspi->base[MSPI]  = devm_ioremap_resource(dev, res);
+		if (IS_ERR(qspi->base[MSPI])) {
+			ret = PTR_ERR(qspi->base[MSPI]);
+			goto err2;
+		}
+	} else
+		goto err2;

Coding style, { } on both sides of the if.

drivers/spi/spi-bcm-qspi.c line 1455

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+	if (!qspi->bspi_mode)
+		master->bus_num += 1;

Why is the driver attempting to set a bus number manually? The core will assign bus numbers automatically and anything that relies on them is going to be fragile.

drivers/spi/spi-bcm-qspi.c line 1466

Quoted 8 lines
drivers/spi/spi-bcm-qspi.c new file +8 -0
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg");
+	if (res) {
+		qspi->base[CHIP_SELECT]  = devm_ioremap_resource(dev, res);
+		if (IS_ERR(qspi->base[CHIP_SELECT])) {
+			ret = PTR_ERR(qspi->base[CHIP_SELECT]);
+			goto err2;
+		}
+	}

As with the interrupt controller is this really part of the IP rather than just a GPIO block?

drivers/spi/spi-bcm-qspi.c line 1563

Quoted 5 lines
drivers/spi/spi-bcm-qspi.c new file +5 -0
+	qspi->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(qspi->clk)) {
+		dev_warn(dev, "unable to get clock, using defaults\n");
+		qspi->clk = NULL;
+	}

This is broken - it's just ignoring errors. That's going to be broken for probe deferral or any other case where a clock is specified but fails to be found for some reason. Given that this is a completely new binding and it's trivial to specify fixed clocks I can see no reason why we'd even want to support missing clocks, it's going to be much more robust to just require that the DT specifies the clock.

drivers/spi/spi-bcm-qspi.c line 1580

Quoted 3 lines
drivers/spi/spi-bcm-qspi.c new file +3 -0
+	bcm_qspi_hw_init(qspi);
+	init_completion(&qspi->mspi_done);
+	init_completion(&qspi->bspi_done);

Can we have mspi and bspi simultaneously?

A message that is not in the archive (sent off-list or not yet received): [email protected]

#6 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 6 lines · Mark Brown
Quoted 6 lines
drivers/spi/spi-bcm-qspi.c new file +6 -0
+	/*
+	 * MIPS endianness is configured by boot strap, which also reverses all
+	 * bus endianness (i.e., big-endian CPU + big endian bus ==> native
+	 * endian I/O).
+	 *
+	 * Other architectures (e.g., ARM) either do not support big endian, or
Quoted 8 lines

drivers/spi/spi-bcm-qspi.c line 280

Quoted 6 lines
drivers/spi/spi-bcm-qspi.c new file +6 -0
+	 * else leave I/O in little endian mode.
+	 */
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+		return ioread32be(qspi->base[type] + offset);
+	else
+		return readl_relaxed(qspi->base[type] + offset);

Just put this in the DT like we do for other MIPS IPs.

As in, putting a native-endian property for this node, right?

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#8 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 5 lines · Florian Fainelli
Quoted 1 line · Mark Brown

Just put this in the DT like we do for other MIPS IPs.

As in, putting a native-endian property for this node, right?

Right, and then parsing that.

#9 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

In reply to a message not in the archive

Mark,

Quoted 28 lines · Mark Brown

drivers/spi/spi-bcm-qspi.c line 42

Quoted 3 lines · Kamal Dasu
drivers/spi/spi-bcm-qspi.c new file +3 -0
+#define STATE_IDLE                           0
+#define STATE_RUNNING                                1
+#define STATE_SHUTDOWN                               2

There's a lot of defines with very generic names that look like they should be namespaced.

drivers/spi/spi-bcm-qspi.c line 180

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+#define DWORD_ALIGNED(a)                     IS_ALIGNED((uintptr_t)(a), 4)
+#define ADDR_TO_4MBYTE_SEGMENT(addr)         (((u32)(addr)) >> 22)

This just doesn't belong in a driver, there's nothing driver specific about it. It should go in a generic header if it's useful.

drivers/spi/spi-bcm-qspi.c line 280

Quoted 12 lines
drivers/spi/spi-bcm-qspi.c new file +12 -0
+     /*
+      * MIPS endianness is configured by boot strap, which also reverses all
+      * bus endianness (i.e., big-endian CPU + big endian bus ==> native
+      * endian I/O).
+      *
+      * Other architectures (e.g., ARM) either do not support big endian, or
+      * else leave I/O in little endian mode.
+      */
+     if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+             return ioread32be(qspi->base[type] + offset);
+     else
+             return readl_relaxed(qspi->base[type] + offset);
Quoted 1 line

Just put this in the DT like we do for other MIPS IPs.

Will fix all of the above.

Quoted 12 lines
Quoted 12 lines
drivers/spi/spi-bcm-qspi.c new file +11 -0
+/* Interrupt helpers when not using brcm intc driver */
+static void bcm_qspi_enable_interrupt(struct bcm_qspi *qspi, u32 mask)
+{
+     unsigned int val;
+
+     if (qspi->hif_spi_mode) {
+             bcm_qspi_write(qspi, INTR, HIF_SPI_INTR2_CPU_MASK_CLEAR, mask);
+     } else {
+             val = bcm_qspi_read(qspi, INTR, 0);
+             val = val | (mask << INTR_BASE_BIT_SHIFT);
+             bcm_qspi_write(qspi, INTR, 0, val);
Quoted 9 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+     }
+}

All this interrupt code and especially the fact that it's a completely separate register range in the binding looks very much like it's just an interrupt controller IP that's not particularly anything to do with the SPI controller and should therefore be in a separate driver. Why is this part of the SPI controller driver?

Some SoCs need this since they do not implement a separate interrupt controller and have dedicated l1 interrupt for spi. Also the handling is not generic enough to cover other ips as well in those case. Hence have to handle it within the driver.

Quoted 31 lines

drivers/spi/spi-bcm-qspi.c line 533

Quoted 7 lines
drivers/spi/spi-bcm-qspi.c new file +7 -0
+static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width,
+                                   int addrlen, int hp)
+{
+     u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
+
+     pr_debug("set override mode w %x addrlen %x hp %d\n",
+              width, addrlen, hp);

dev_dbg(). If you've got a device prints should use it, it makes reading logs vastly easier.

Quoted 9 lines
drivers/spi/spi-bcm-qspi.c new file +9 -0
+     switch (width) {
+     case SPI_NBITS_QUAD:
+             /* clear dual mode and set quad mode */
+             data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+             data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD;
+             break;
+     case SPI_NBITS_DUAL:
+             /* clear quad mode set dual mode */
+             data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD;

drivers/spi/spi-bcm-qspi.c line 553

Quoted 10 lines
drivers/spi/spi-bcm-qspi.c new file +10 -0
+             data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+             break;
+     case SPI_NBITS_SINGLE:
+             /* clear quad/dual mode */
+             data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD |
+                       BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL);
+             break;
+     default:
+             break;
+     }
Quoted 2 lines

We just ignore other widths?

These are the only supported widths will make SPI_NBITS_SINGLE default.

Quoted 8 lines

drivers/spi/spi-bcm-qspi.c line 656

Quoted 5 lines
drivers/spi/spi-bcm-qspi.c new file +5 -0
+static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi)
+{
+
+     if ((!qspi->base[BSPI]) || (qspi->bspi_enabled))
+             return;

Why would it be OK to call this if we don't have BSPI?

Quoted 5 lines

drivers/spi/spi-bcm-qspi.c line 732

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+     xp->mode = spi->mode;
+     xp->bits_per_word = spi->bits_per_word ? spi->bits_per_word : 8;

Write normal if statements for legibility please.

Will make the changes to this to make it more legible.

Quoted 30 lines
Quoted 9 lines
drivers/spi/spi-bcm-qspi.c new file +9 -0
+/* MSPI helpers */
+
+/* stop at end of transfer, no other reason */
+#define FNB_BREAK_NONE                       0
+/* stop at end of spi_message */
+#define FNB_BREAK_EOM                        1
+/* stop at end of spi_transfer if delay */
+#define FNB_BREAK_DELAY                      2
+/* stop at end of spi_transfer if cs_change */

drivers/spi/spi-bcm-qspi.c line 755

Quoted 10 lines
drivers/spi/spi-bcm-qspi.c new file +10 -0
+#define FNB_BREAK_CS_CHANGE          4
+/* stop if we run out of bytes */
+#define FNB_BREAK_NO_BYTES           8
+
+/* events that make us stop filling TX slots */
+#define FNB_BREAK_TX                 (FNB_BREAK_EOM | FNB_BREAK_DELAY | \
+                                      FNB_BREAK_CS_CHANGE)
+
+/* events that make us deassert CS */
+#define FNB_BREAK_DESELECT           (FNB_BREAK_EOM | FNB_BREAK_CS_CHANGE)

This block of defies is just randomly in the middle of the driver?

drivers/spi/spi-bcm-qspi.c line 760

Quoted 4 lines
drivers/spi/spi-bcm-qspi.c new file +4 -0
+static int find_next_byte(struct bcm_qspi *qspi, struct position *p,
+                       int flags)
+{
+     int ret = FNB_BREAK_NONE;

I'm unclear what this is intended to do, I suspect other readers might be too.

Quoted 7 lines

drivers/spi/spi-bcm-qspi.c line 1032

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+static int bcm_qspi_flash_read(struct spi_device *spi,
+                            struct spi_flash_read_message *msg)

There's a lot of flash code in the driver, it would make review a lot easier to split this out into a followup patch so we have one patch with the standard SPI controller and some more adding the flash acceleration.

Sounds reasonable, will split the changes and other changes to make it more readable.

Quoted 8 lines

drivers/spi/spi-bcm-qspi.c line 1094

Quoted 3 lines
drivers/spi/spi-bcm-qspi.c new file +3 -0
+static void bcm_qspi_trans_mode(struct bcm_qspi *qspi,
+                             struct spi_device *spi,
+                             struct spi_transfer *trans)

This still appears to be trying to parse the data in SPI transfers. Please don't do this, remove this code in favour of using the accelerated flash operations.

Quoted 6 lines

drivers/spi/spi-bcm-qspi.c line 1432

Quoted 4 lines
drivers/spi/spi-bcm-qspi.c new file +4 -0
+     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi");
+     if (!res)
+             res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                "mspi");

Why support both names?

We have BRCMSTB SoCs have two instances of the spi master one with the MSPI+BSPI called hif_mspi and the other is just MSPI. We generally use the hardware block names to be more clear and not confuse the two nodes in dt. Hence the probe is allowing for the naming difference.

Quoted 10 lines

drivers/spi/spi-bcm-qspi.c line 1441

Quoted 9 lines
drivers/spi/spi-bcm-qspi.c new file +8 -0
+     if (res) {
+             qspi->base[MSPI]  = devm_ioremap_resource(dev, res);
+             if (IS_ERR(qspi->base[MSPI])) {
+                     ret = PTR_ERR(qspi->base[MSPI]);
+                     goto err2;
+             }
+     } else
+             goto err2;
Quoted 9 lines

Coding style, { } on both sides of the if.

drivers/spi/spi-bcm-qspi.c line 1455

Quoted 2 lines
drivers/spi/spi-bcm-qspi.c new file +2 -0
+     if (!qspi->bspi_mode)
+             master->bus_num += 1;

Why is the driver attempting to set a bus number manually? The core will assign bus numbers automatically and anything that relies on them is going to be fragile.

Ok will assign bus_num = -1 so that its automatic.

Quoted 9 lines

drivers/spi/spi-bcm-qspi.c line 1466

Quoted 8 lines
drivers/spi/spi-bcm-qspi.c new file +8 -0
+     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg");
+     if (res) {
+             qspi->base[CHIP_SELECT]  = devm_ioremap_resource(dev, res);
+             if (IS_ERR(qspi->base[CHIP_SELECT])) {
+                     ret = PTR_ERR(qspi->base[CHIP_SELECT]);
+                     goto err2;
+             }
+     }
Quoted 3 lines

As with the interrupt controller is this really part of the IP rather than just a GPIO block?

SoCs have dedicated CS for SPI flash IP and hence it is part of the ip but happens to have it own address range.

Quoted 6 lines

drivers/spi/spi-bcm-qspi.c line 1563

Quoted 5 lines
drivers/spi/spi-bcm-qspi.c new file +5 -0
+     qspi->clk = devm_clk_get(&pdev->dev, NULL);
+     if (IS_ERR(qspi->clk)) {
+             dev_warn(dev, "unable to get clock, using defaults\n");
+             qspi->clk = NULL;
+     }
Quoted 7 lines

This is broken - it's just ignoring errors. That's going to be broken for probe deferral or any other case where a clock is specified but fails to be found for some reason. Given that this is a completely new binding and it's trivial to specify fixed clocks I can see no reason why we'd even want to support missing clocks, it's going to be much more robust to just require that the DT specifies the clock.

Will make this change. However on broadcom SoCs the clks are turned on by default and work with a default frequency.

Quoted 5 lines

drivers/spi/spi-bcm-qspi.c line 1580

Quoted 3 lines
drivers/spi/spi-bcm-qspi.c new file +3 -0
+     bcm_qspi_hw_init(qspi);
+     init_completion(&qspi->mspi_done);
+     init_completion(&qspi->bspi_done);

Can we have mspi and bspi simultaneously?

Yes in the instance where we are using the master controller for the spi-nor access. All writes and SPI cmds go through the MSPI logic and reads are accelerated through BSPI logic. Both work hand in hand. The other instance is the SPI only master generally used for other SPI devices. I will add few lines describing this in the dt bindings document.

Will send a new patch V5.And copy the mtd list as well.

Thanks for your patient review.

Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): CAKekbevYN3CLvqQs3stUXDFEMREMOJ0g4+w7Zsno1kV-ieYEiw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#11 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 10 lines · Kamal Dasu
Quoted 5 lines

All this interrupt code and especially the fact that it's a completely separate register range in the binding looks very much like it's just an interrupt controller IP that's not particularly anything to do with the SPI controller and should therefore be in a separate driver. Why is this part of the SPI controller driver?

Some SoCs need this since they do not implement a separate interrupt controller and have dedicated l1 interrupt for spi. Also the handling is not generic enough to cover other ips as well in those case. Hence have to handle it within the driver.

That doesn't seem to match what the code is actually doing. The register block this is controlling is separate to the rest of the IP. It's perfectly OK to have a driver for an interrupt controller which is only used in one place, though you may find one of the generic ones might be able to handle it anyway.

Quoted 7 lines
Quoted 5 lines

drivers/spi/spi-bcm-qspi.c line 518

Quoted 3 lines
drivers/spi/spi-bcm-qspi.c new file +3 -0
+     default:
+             break;
+     }

We just ignore other widths?

These are the only supported widths will make SPI_NBITS_SINGLE default.

If the user is trying to set an unsupported configuration you should return an error rather than silently set a different configuration.

A message that is not in the archive (sent off-list or not yet received): [email protected]

author
#13 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Mark,

Quoted 13 lines · Mark Brown
Quoted 10 lines · Kamal Dasu
Quoted 5 lines

All this interrupt code and especially the fact that it's a completely separate register range in the binding looks very much like it's just an interrupt controller IP that's not particularly anything to do with the SPI controller and should therefore be in a separate driver. Why is this part of the SPI controller driver?

Some SoCs need this since they do not implement a separate interrupt controller and have dedicated l1 interrupt for spi. Also the handling is not generic enough to cover other ips as well in those case. Hence have to handle it within the driver.

Quoted 6 lines

That doesn't seem to match what the code is actually doing. The register block this is controlling is separate to the rest of the IP. It's perfectly OK to have a driver for an interrupt controller which is only used in one place, though you may find one of the generic ones might be able to handle it anyway.

The NS* SoC SPI blocks has hw glue logic specific to MSPI+BSPI, so the re-usability of an interrupt controller driver for this logic is limited. The spi only (spi protocol) block does use l2 controller, however for the MSPI+BSPI block used for the spi-nor flash had to introduce the code to handle l1 interrupts within the code itself. In this case can the driver be accepted without having to introduce a new intc driver ?.

Thanks
Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): CAC=U0a3WN9TGw7zwwP3qFf5MUsRteUcVLytFgjnP4zScZS0xXA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#15 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 7 lines · Kamal Dasu

The NS* SoC SPI blocks has hw glue logic specific to MSPI+BSPI, so the re-usability of an interrupt controller driver for this logic is limited. The spi only (spi protocol) block does use l2 controller, however for the MSPI+BSPI block used for the spi-nor flash had to introduce the code to handle l1 interrupts within the code itself. In this case can the driver be accepted without having to introduce a new intc driver ?.

It's not really about reuse, it's about maintainability. All the code for handling this within the driver is quite unusual and makes the driver harder to understand and review. That's going to have an impact now and make things harder to follow in future too. Fitting in with the frameworks means that we get the benefit of the structure and support code that the frameworks provide while minimizing the amount of unusal code in the driver.

You may find that you may even be able to use one of the existing generic interrupt controller drivers if the hardware is simple enough.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#17 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 10 lines · Mark Brown
Quoted 7 lines · Kamal Dasu

The NS* SoC SPI blocks has hw glue logic specific to MSPI+BSPI, so the re-usability of an interrupt controller driver for this logic is limited. The spi only (spi protocol) block does use l2 controller, however for the MSPI+BSPI block used for the spi-nor flash had to introduce the code to handle l1 interrupts within the code itself. In this case can the driver be accepted without having to introduce a new intc driver ?.

Quoted 7 lines

It's not really about reuse, it's about maintainability. All the code for handling this within the driver is quite unusual and makes the driver harder to understand and review. That's going to have an impact now and make things harder to follow in future too. Fitting in with the frameworks means that we get the benefit of the structure and support code that the frameworks provide while minimizing the amount of unusal code in the driver.

This is not unusual at all, there are tons of peripherals that embed a L2/L3 interrupt controller, yet keep the code localized because the interrupt sources are not visible outside of the specific block and it would not make sense to demultiplex these different interrupt sources as individually requestable interrupt lines when the consumer is also local and self contained.

This is exactly what is going on here, and it this makes the driver more self contained without external dependencies to an irqchip driver to an interrupt controller provider.

The reusability argument is kind of the only one that makes sense here, maintaining two drivers instead of one seems like more maintenance burden imho.

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#19 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 10 lines · Florian Fainelli
Quoted 7 lines · Mark Brown

It's not really about reuse, it's about maintainability. All the code for handling this within the driver is quite unusual and makes the driver harder to understand and review. That's going to have an impact now and make things harder to follow in future too. Fitting in with the frameworks means that we get the benefit of the structure and support code that the frameworks provide while minimizing the amount of unusal code in the driver.

Quoted 6 lines

This is not unusual at all, there are tons of peripherals that embed a L2/L3 interrupt controller, yet keep the code localized because the interrupt sources are not visible outside of the specific block and it would not make sense to demultiplex these different interrupt sources as individually requestable interrupt lines when the consumer is also local and self contained.

If it was unconditionally in the perhipheral it'd be fairly normal and standard but it's not, it's a completely separate and optional register block with a bunch of separate code in a driver which already has above average complexity even for the bits that belong in it.

Quoted 3 lines

This is exactly what is going on here, and it this makes the driver more self contained without external dependencies to an irqchip driver to an interrupt controller provider.

Like I say it just isn't, it's an obviously separate interrupt controller.

Quoted 3 lines

The reusability argument is kind of the only one that makes sense here, maintaining two drivers instead of one seems like more maintenance burden imho.

It's definitely adding to the review complexity as things stand mainly due to the obvious disconnect from the actual IP. It should take very little time to refactor and it's really hard to see it ever taking much time to maintain in future, though it might be helpful if one of your hardware engineers ever tries to reuse that IP.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#21 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 18 lines · Mark Brown
Quoted 10 lines · Florian Fainelli
Quoted 7 lines · Mark Brown

It's not really about reuse, it's about maintainability. All the code for handling this within the driver is quite unusual and makes the driver harder to understand and review. That's going to have an impact now and make things harder to follow in future too. Fitting in with the frameworks means that we get the benefit of the structure and support code that the frameworks provide while minimizing the amount of unusal code in the driver.

Quoted 6 lines

This is not unusual at all, there are tons of peripherals that embed a L2/L3 interrupt controller, yet keep the code localized because the interrupt sources are not visible outside of the specific block and it would not make sense to demultiplex these different interrupt sources as individually requestable interrupt lines when the consumer is also local and self contained.

Quoted 4 lines

If it was unconditionally in the perhipheral it'd be fairly normal and standard but it's not, it's a completely separate and optional register block with a bunch of separate code in a driver which already has above average complexity even for the bits that belong in it.

It is not separate nor optional, the fact that the register range seems discontiguous is just an integration choice here, but it contains bits that are relevant exclusively to the SPI controller.

Quoted 7 lines
Quoted 4 lines

This is exactly what is going on here, and it this makes the driver more self contained without external dependencies to an irqchip driver to an interrupt controller provider.

Like I say it just isn't, it's an obviously separate interrupt controller.

First of all you cannot make that statement with just looking at the code and not having access to the datasheet, but I will accept that the limited view of what you got to see from the driver can make you think that.

It is not exclusively an interrupt controller, there are other bits in there are do not functionally belong into an interrupt controller driver per-se, things like a clock enable, arbiter control and a random bit to control MSPI flush behavior.

Oh, and please don't tell me regmap is the solution here if we need to control both the interrupt-related bits and the other bits within this register.

Quoted 11 lines
Quoted 4 lines

The reusability argument is kind of the only one that makes sense here, maintaining two drivers instead of one seems like more maintenance burden imho.

It's definitely adding to the review complexity as things stand mainly due to the obvious disconnect from the actual IP. It should take very little time to refactor and it's really hard to see it ever taking much time to maintain in future, though it might be helpful if one of your hardware engineers ever tries to reuse that IP.

Considering that this block aggregates interrupt enable bits, but not just, there is no reason for this block to change over time, and clearly this won't be handled via a generic interrupt controller driver either.

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#23 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 10 lines · Florian Fainelli
Quoted 4 lines · Mark Brown

If it was unconditionally in the perhipheral it'd be fairly normal and standard but it's not, it's a completely separate and optional register block with a bunch of separate code in a driver which already has above average complexity even for the bits that belong in it.

It is not separate nor optional, the fact that the register range seems discontiguous is just an integration choice here, but it contains bits that are relevant exclusively to the SPI controller.

Some versions of the block have it, some versions of the block don't have it. That suggests that it's optional. It is a completely separate register map, that suggests that it is an external block.

Quoted 8 lines

It is not exclusively an interrupt controller, there are other bits in there are do not functionally belong into an interrupt controller driver per-se, things like a clock enable, arbiter control and a random bit to control MSPI flush behavior.

Oh, and please don't tell me regmap is the solution here if we need to control both the interrupt-related bits and the other bits within this register.

That does sound system controllerish if those bits do need to be managed. Are we sure future designs won't just integrate this into the main system controller?

Quoted 3 lines

Considering that this block aggregates interrupt enable bits, but not just, there is no reason for this block to change over time, and clearly this won't be handled via a generic interrupt controller driver either.

There must be *some* logic behind the way the hardware has been structured, and right now the code just isn't making any of this apparent which makes it look like it needs refactoring.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#25 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 8 lines · Mark Brown
Quoted 6 lines · Florian Fainelli
Quoted 4 lines · Mark Brown

If it was unconditionally in the perhipheral it'd be fairly normal and standard but it's not, it's a completely separate and optional register block with a bunch of separate code in a driver which already has above average complexity even for the bits that belong in it.

Quoted 7 lines
Quoted 3 lines

It is not separate nor optional, the fact that the register range seems discontiguous is just an integration choice here, but it contains bits that are relevant exclusively to the SPI controller.

Some versions of the block have it, some versions of the block don't have it. That suggests that it's optional. It is a completely separate register map, that suggests that it is an external block.

OK, so maybe we should have given so more information about this is structured. The block originated from the group in which Kamal and I work, and original version of the IP is what the brcm,spi-brcmstb looks like:

- one block which is MSPI + BSPI capable, and is typically used for a SPI flash as the primary boot medium and storage of the device

- another one which is just MSPI capable, separate register range

- one separate level 2 interrupt controller for the MSPI + BSPI capable instance for which we have a driver already under drivers/irqchip/irq-brcmstb-l2.c which is a fairly generic piece of HW providing de-multiplexed L2 interrupts for MSPI_DONE, MSPI_HALTED, SPI_LR_* and only those relevant interrupts

- MSPI_DONE + MSPI_HALTED L2 interrupts wired to another L2 interrupt controller (not dedicated to just MSPI, shared with other L2 interrupts) for the second MSPI only instance, but also backed by the same HW block layout and thefore driver

That's for STB SoCs (BCM7xxx), which is a relatively simple and easy to support HW design.

Another group, in which Dhanajay works later integrated this SPI controller on the Norsthstar class of SoCs and did the following:

- added a dedicated IDM IO_CONTROL register block for SPI only (there are one dedicated per functional block, like NAND, USB etc.) which has a clock enable bit, some other HW-block top-level integration signals for test modes etc, but also added interrupt enable/disable bits, this is consistent across all Norsthar* chips, in the Device Tree binding this is described as the "intr_regs" resource

- grouped the MSPI + BSPI together, one after the other, and appended at the end of the MSPI block 7 32-bits words, for the 7 interrupt status bits which all can be read/written to for MSPI_DONE, MSPI_HALTED, SPI_LR_* interrupts, this is also consistent across all Norsthar* chips. In the DT binding, this is described as the "intr_status_regs" resource

Note that the layout of the IDM block and the MSPI+BSPI block are identical between Northstar, Northstar Plus and Northstar 2, so we got that going, which is nice.

Where they started to somehow diverge is here:

- Norsthar and Northstar Plus both allocated dedicated L1 interrupts from the top-level ARM GIC interrupt controller for each of the 7 Level-2 interrupts the SPI block cares about: MSPI_DONE, MSPI_HALTED etc. so we can requests these interrupts individually

- but Northstar 2 only has one single L1 interrupt for all of these 7 interrupts, so we need to into the interrupt status registers for each of these 7 interrupts bits, and that is done by looking at the 7 32-bits words after the MSPI block (the "intr_status_regs") resource

So with the exception of the separate L1 vs. multiple L1 interrupt sources for the MSPI+BMSPI, everything is fairly consistent, and this is why the driver needs to touch several blocks.

Quoted 6 lines
Quoted 5 lines

It is not exclusively an interrupt controller, there are other bits in there are do not functionally belong into an interrupt controller driver per-se, things like a clock enable, arbiter control and a random bit to control MSPI flush behavior.

Quoted 7 lines
Quoted 3 lines

Oh, and please don't tell me regmap is the solution here if we need to control both the interrupt-related bits and the other bits within this register.

That does sound system controllerish if those bits do need to be managed. Are we sure future designs won't just integrate this into the main system controller?

No of course we cannot be 100% sure, HW design teams do whatever the heck they want unles you give them feedback, but so far they have been very consistent in how they integrated SPI on 3 different generations of SoCs, and since the SW people there are hunting them down based on consistency, we should be confident.

Quoted 8 lines
Quoted 4 lines

Considering that this block aggregates interrupt enable bits, but not just, there is no reason for this block to change over time, and clearly this won't be handled via a generic interrupt controller driver either.

There must be *some* logic behind the way the hardware has been structured, and right now the code just isn't making any of this apparent which makes it look like it needs refactoring.

Hopefully what I just described here helps seeing what is common, and what is specific to a given SoC, I don't mind us updating the binding to reflec that information provided that this helps.

Now, as to whether it makes sense to model the IDM enable/disable (intr_regs resource) and the 7 32-bits interrupt status/acknowledge words at the end of the MSPI+BSPI block (intr_status_regs resource) as an interrupt controller makes sense or not, it is kind of hard to say, because really the IDM IO_CONTROL aggregates more than just interrupt enable/disable bits here, but the overall ownership of this IDM IO_CONTROL is clear and it belongs to the SPI function of the system.

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#27 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 7 lines · Florian Fainelli

Now, as to whether it makes sense to model the IDM enable/disable (intr_regs resource) and the 7 32-bits interrupt status/acknowledge words at the end of the MSPI+BSPI block (intr_status_regs resource) as an interrupt controller makes sense or not, it is kind of hard to say, because really the IDM IO_CONTROL aggregates more than just interrupt enable/disable bits here, but the overall ownership of this IDM IO_CONTROL is clear and it belongs to the SPI function of the system.

TBH if that's all it's doing then I'm surprised it's not simple to handle it with irq_setup_generic_chip() - have you looked at that at all?

A message that is not in the archive (sent off-list or not yet received): [email protected]

#29 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 10 lines · Mark Brown
Quoted 7 lines · Florian Fainelli

Now, as to whether it makes sense to model the IDM enable/disable (intr_regs resource) and the 7 32-bits interrupt status/acknowledge words at the end of the MSPI+BSPI block (intr_status_regs resource) as an interrupt controller makes sense or not, it is kind of hard to say, because really the IDM IO_CONTROL aggregates more than just interrupt enable/disable bits here, but the overall ownership of this IDM IO_CONTROL is clear and it belongs to the SPI function of the system.

Quoted 3 lines

TBH if that's all it's doing then I'm surprised it's not simple to handle it with irq_setup_generic_chip() - have you looked at that at all?

The generic IRQ chip model assumes that the mask/unmask/ack logic will operate against the same register base address, which won't be the case for the NS/NSP/NS2 platforms where the mask/unmask is in one register set (coined IDM), and the ack is in another one (actually 7 * 32-bits words).

You would need to write a custom irq_chip implementation to suppor that which is not a great fit because it is not dealing with just pure interrupt enable/disable bits, but manages a 32-bits word of register space which has other controls, and another set of 32-bits words which functionally belongs in the SPI controller for interrupt statuses.

In that case, my personal preference is to abstract that within a SoC-specific glue layer, ala brcmnand, where the SoC that needs this glue has full control and clear ownership of this 32-bits word of register space. This keeps the SoC-specific logic clean and separate, reasonably well abstracted, while making the core SPI driver deal with the ideal situation and not knowing how the SoC glues things together.

So yes, we actually did put some thought into this.

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): e3a069ad-ca2b-7c12-bde1-5566f5fe24d3-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#31 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 11 lines · Florian Fainelli
Quoted 3 lines · Mark Brown

TBH if that's all it's doing then I'm surprised it's not simple to handle it with irq_setup_generic_chip() - have you looked at that at all?

The generic IRQ chip model assumes that the mask/unmask/ack logic will operate against the same register base address, which won't be the case for the NS/NSP/NS2 platforms where the mask/unmask is in one register set (coined IDM), and the ack is in another one (actually 7 * 32-bits words).

I'd been thinking of just implementing an irqchip with no masking in it
- the source level masking isn't really a part of the irqchip itself here any more than it is when it's a real irqchip that's attached.

#32 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

In reply to a message not in the archive
Quoted 8 lines · Mark Brown
Quoted 6 lines · Florian Fainelli
Quoted 4 lines · Mark Brown

If it was unconditionally in the perhipheral it'd be fairly normal and standard but it's not, it's a completely separate and optional register block with a bunch of separate code in a driver which already has above average complexity even for the bits that belong in it.

Quoted 7 lines
Quoted 3 lines

It is not separate nor optional, the fact that the register range seems discontiguous is just an integration choice here, but it contains bits that are relevant exclusively to the SPI controller.

Some versions of the block have it, some versions of the block don't have it. That suggests that it's optional. It is a completely separate register map, that suggests that it is an external block.

Mark, would you oppose to a driver structure that looks like the Broadcom NAND driver under drivers/mtd/nand/brcmnand/, where we have something like this:

- the core driver only deals with individual interrupt lines which are available in the original version of the IP block as integrated on Set-top-box/Cable Modem chips

- the core driver allows for callbacks to perform additional interupt work when that is required for the iProc (Northstar, Northstar Plus, Northstar 2) and DSL SoCs where we have additional logic to enable/disable/acknowledge interrupt lines

We came up with this design for the NAND controller driver pretty much for the same reasons that the NAND controller originally came from the STB/CM group and was later adopted by the iProc SoCs and integrated in a way that made the number of layout of interrupts and control register different...

Thanks

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 583d6ec8-b367-b53a-7d9e-1d7ee06004c0-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#34 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

Quoted 7 lines · Florian Fainelli

Mark, would you oppose to a driver structure that looks like the Broadcom NAND driver under drivers/mtd/nand/brcmnand/, where we have something like this:

- the core driver only deals with individual interrupt lines which are available in the original version of the IP block as integrated on Set-top-box/Cable Modem chips

I need time to look at this (hopefully before Monday but stuff might come up) but I definitely think it would help to merge an initial driver that doesn't handle the extra register range and then deal with the extra register range as an incremental patch on top of that - this would mean we can get the common code that's used on all boards (which is fairly straighforward IIRC) merged and then whatever solution is used for the more complicated integrations can be handled separately. If nothing else it'd make it easier to think about the more complicated cases if we're looking at just that code in one patch.

But no need to do that if you don't want to, it might help speed things along though.

#35 lore raw

Re: [PATCH, V4, 2/5] spi: bcm-qspi: Add SPI flash and MSPI driver

In reply to a message not in the archive
Quoted 4 lines · Florian Fainelli

Mark, would you oppose to a driver structure that looks like the Broadcom NAND driver under drivers/mtd/nand/brcmnand/, where we have something like this:

Quoted 8 lines

- the core driver only deals with individual interrupt lines which are available in the original version of the IP block as integrated on Set-top-box/Cable Modem chips

- the core driver allows for callbacks to perform additional interupt work when that is required for the iProc (Northstar, Northstar Plus, Northstar 2) and DSL SoCs where we have additional logic to enable/disable/acknowledge interrupt lines

That seems like it might work but I'd need to see the code. Like I said previously it might be easier to deal with this as a separate patch to the core driver just from a review/code management point of view.

author
#36 lore raw

PATCH v4 3/5 arm: dts: Add bcm-nsp and bcm958625k support

In reply to a message not in the archive

Adding qspi node compatible with the new spi-bcm-qspi driver for the broadcom's northstar SoCwq.

---
 arch/arm/boot/dts/bcm-nsp.dtsi   | 30 ++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
arch/arm/boot/dts/bcm-nsp.dtsi +30 -0
index def9e78..aae45e6 100644
@@ -206,6 +206,36 @@
 			brcm,nand-has-wp;
 		};
 
+		qspi: qspi@27200 {
+			compatible = "brcm,spi-bcm-qspi";
+			reg = <0x027200 0x184>,
+			      <0x027000 0x124>,
+			      <0x11c408 0x004>,
+			      <0x0273a0 0x01c>;
+			reg-names = "mspi", "bspi", "intr_regs",
+				    "intr_status_reg";
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "spi_lr_fullness_reached",
+					  "spi_lr_session_aborted",
+					  "spi_lr_impatient",
+					  "spi_lr_session_done",
+					  "spi_lr_overhead",
+					  "mspi_done",
+					  "mspi_halted";
+			clocks = <&iprocmed>;
+			clock-names = "iprocmed";
+			clock-frequency = <12500000>;
+			num-cs = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		ccbtimer0: timer@34000 {
 			compatible = "arm,sp804";
 			reg = <0x34000 0x1000>;
arch/arm/boot/dts/bcm958625k.dts +34 -0
index e298450..5aea779 100644
@@ -114,3 +114,37 @@
 		groups = "nand_grp";
 	};
 };
+
+&qspi {
+	bspi-sel = <0>;
+	flash: m25p80@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "m25p80";
+		reg = <0x0>;
+		spi-max-frequency = <12500000>;
+		m25p,fast-read;
+		spi-cpol;
+		spi-cpha;
+
+		partition@0 {
+			label = "boot";
+			reg = <0x00000000 0x000a0000>;
+		};
+
+		partition@1 {
+			label = "env";
+			reg = <0x000a0000 0x00060000>;
+		};
+
+		partition@2 {
+			label = "system";
+			reg = <0x00100000 0x00600000>;
+		};
+
+		partition@3 {
+			label = "rootfs";
+			reg = <0x00700000 0x01900000>;
+		};
+	};
+};
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author
#37 lore raw

PATCH v4 4/5 arm64: dts: Add ns2 SoC support

In reply to a message not in the archive

Adding qspi node compatible with the new spi-bcm-qspi driver for the broadcom's northstar2 SoC.

---
 arch/arm64/boot/dts/broadcom/ns2-svk.dts | 34 ++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/broadcom/ns2.dtsi    | 19 ++++++++++++++++++
 2 files changed, 53 insertions(+)
arch/arm64/boot/dts/broadcom/ns2-svk.dts +34 -0
index 54ca40c..0754841 100644
@@ -132,3 +132,37 @@
 		#size-cells = <1>;
 	};
 };
+
+&qspi {
+	bspi-sel = <0>;
+	flash: m25p80@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "m25p80";
+		reg = <0x0>;
+		spi-max-frequency = <12500000>;
+		m25p,fast-read;
+		spi-cpol;
+		spi-cpha;
+
+		partition@0 {
+			label = "boot";
+			reg = <0x00000000 0x000a0000>;
+		};
+
+		partition@1 {
+			label = "env";
+			reg = <0x000a0000 0x00060000>;
+		};
+
+		partition@2 {
+			label = "system";
+			reg = <0x00100000 0x00600000>;
+		};
+
+		partition@3 {
+			label = "rootfs";
+			reg = <0x00700000 0x01900000>;
+		};
+	};
+};
arch/arm64/boot/dts/broadcom/ns2.dtsi +19 -0
index ec68ec1..9d7c90c 100644
@@ -399,5 +399,24 @@
 
 			brcm,nand-has-wp;
 		};
+
+		qspi: spi@66470200 {
+			compatible = "brcm,spi-bcm-qspi";
+			reg = <0x66470200 0x184>,
+				<0x66470000 0x124>,
+				<0x67017408 0x004>,
+				<0x664703a0 0x01c>;
+			reg-names = "mspi", "bspi", "intr_regs",
+				"intr_status_reg";
+			interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "spi_l1_intr";
+			clocks = <&iprocmed>;
+			clock-names = "iprocmed";
+			clock-frequency = <12500000>;
+			num-cs = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 	};
 };
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author
#38 lore raw

PATCH v4 5/5 mtd: m25p80: Let m25p80_read() fallback to spi transfer

In reply to a message not in the archive

In m25p80_read() even though spi_flash_read() is supported by some drivers, under certain circumstances like unaligned buffer, address or address range limitations on certain SoCs let it fallback to core spi reads. Such drivers are expected to return -EAGAIN so that the m25p80_read() uses standard spi transfer.

---
 drivers/mtd/devices/m25p80.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/mtd/devices/m25p80.c +5 -2
index 9d68544..3f90542 100644
@@ -149,8 +149,11 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
 		msg.data_nbits = m25p80_rx_nbits(nor);
 
 		ret = spi_flash_read(spi, &msg);
-		*retlen = msg.retlen;
-		return ret;
+		/* some drivers might need to fallback to spi transfer */
+		if (ret != -EAGAIN) {
+			*retlen = msg.retlen;
+			return ret;
+		}
 	}
 
 	spi_message_init(&m);
Signature · 6 lines
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1466197433-11290-5-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#40 lore raw

Re: [PATCH, V4, 5/5] mtd: m25p80: Let m25p80_read() fallback to spi transfer

Quoted 6 lines · Kamal Dasu

In m25p80_read() even though spi_flash_read() is supported by some drivers, under certain circumstances like unaligned buffer, address or address range limitations on certain SoCs let it fallback to core spi reads. Such drivers are expected to return -EAGAIN so that the m25p80_read() uses standard spi transfer.

This is a patch to the MTD subsystem, you need to send it to the MTD maintainers as covered in SubmittingPatches.

#41 lore raw
In reply to a message not in the archive
Quoted 2 lines · Kamal Dasu

Added device tree bindings documentation for SoCs supported by the new spi-bcm-qspi driver.

To repeat what I said on your previous version:

| So this is a perfect example of why you should use standard formats for
| subject lines, if things don't look relevant they're likely to get
| missed.  In this case it's both the prefix and the fact that the version
| is added in a weird way.  Frankly I didn't even notice that it wasn't a
| cover letter.

Please don't ignore review comments, people are generally making them for a reason and are likely to have the same concerns if issues remain unaddressed.

Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt line 17

Quoted 4 lines

+- compatible:

Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt new file +3 -0
+    Must be one of :
+    "brcm,spi-bcm-qspi"
+    "brcm,spi-brmstb" spi-nor and/or "brcm,spi-brmstb-mspi" unmanaged SPI Master

What do these compatible strings mean, what are the differences between them? The last two sound like configuration of a single IP rather than descriptions of hardware.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#43 lore raw
Quoted 16 lines · Mark Brown
Quoted 2 lines · Kamal Dasu

Added device tree bindings documentation for SoCs supported by the new spi-bcm-qspi driver.

To repeat what I said on your previous version:

| So this is a perfect example of why you should use standard formats for
| subject lines, if things don't look relevant they're likely to get
| missed.  In this case it's both the prefix and the fact that the version
| is added in a weird way.  Frankly I didn't even notice that it wasn't a
| cover letter.

Please don't ignore review comments, people are generally making them for a reason and are likely to have the same concerns if issues remain unaddressed.

Quoted 8 lines

Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt line 17

Quoted 4 lines

+- compatible:

Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt new file +3 -0
+    Must be one of :
+    "brcm,spi-bcm-qspi"
+    "brcm,spi-brmstb" spi-nor and/or "brcm,spi-brmstb-mspi" unmanaged SPI Master

What do these compatible strings mean, what are the differences between them? The last two sound like configuration of a single IP rather than descriptions of hardware.

The Broadcom STB SoCs have two instances of this SPI HW block, one which is MSPI+BSPI capable and another one which is MSPI only (or that's how we call them), the difference in the compatible strings tries to denote and capture that.

Signature · 5 lines
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#45 lore raw
Quoted 7 lines · Florian Fainelli
Quoted 4 lines · Mark Brown
Quoted 4 lines

+- compatible:

Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt new file +3 -0
+    Must be one of :
+    "brcm,spi-bcm-qspi"
+    "brcm,spi-brmstb" spi-nor and/or "brcm,spi-brmstb-mspi" unmanaged SPI Master
Quoted 8 lines
Quoted 3 lines

What do these compatible strings mean, what are the differences between them? The last two sound like configuration of a single IP rather than descriptions of hardware.

The Broadcom STB SoCs have two instances of this SPI HW block, one which is MSPI+BSPI capable and another one which is MSPI only (or that's how we call them), the difference in the compatible strings tries to denote and capture that.

The point is that we need some words in the binding that explain this so people know when to use them.