All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/8]  Broadcom stb, nsp, ns2, cygnus QSPI driver
@ 2016-07-29 22:13 ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu

This is V5 changes for common spi driver for the brcmstb, nsp, ns2, cygnus
SoCs. Changes include driver for  standard MSPI and accelerated BSPI blocks.
The Brodcom STB uses l2-intc where as the SoC specific interrupt handling
code has been separated in a new  driver. In case of NS and NS2 SoCs it does
not have a dedicated l2 controller and the interrupts are specific to the 
spi core. The drivers are organized in the follwoing way:
 
 drivers/spi/spi-bcm-qspi.c      - Common MSPI, BSPI driver

 drivers/spi/spi-bcm-qspi.h      - Common header 

 drivers/spi/spi-brcmstb-qspi.c  - SoC specific wth brcm,spi-brcmstb-qspi 
                                   compatibility, does not have anything 
                                   specific for stb SoC

 drivers/spi/spi-nsp-qspi.c      - Implements the interrupt hooks used by 
                                   the common driver with "brcm,spi-nsp-qspi"
                                   compatibility
Changes in V5:
 - Added additional description in the binding documentation non MSPI and BSPI SoC IP
 - Split commits for MSPI spi driver and accelarated BSPI driver used for accelerated
   flash reads
 - Removed any parsing of transfer structures for commands
 - Other code cleanup for readability
 - Kept the interrupt handling code in separate driver, since hardware abstraction and l2
   controller driver in software do not exisit certain SoCs

Kamal Dasu (8):
  Documentation: dt: spi: Add BRCMSTB SoC bindings
  spi: bcm-qspi: Add Broadcom MSPI driver
  spi: bcm-qspi: Add BSPI spi-nor flash controller driver
  mtd: m25p80: Let m25p80_read() fallback to spi transfer
  Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
  arm: dts: Add bcm-nsp and bcm958625k support
  arm64: dts: Add ns2 SoC support
  spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support

 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  |  235 ++++
 arch/arm/boot/dts/bcm-nsp.dtsi                     |   33 +-
 arch/arm/boot/dts/bcm958625k.dts                   |   34 +
 arch/arm64/boot/dts/broadcom/ns2-svk.dts           |   34 +-
 arch/arm64/boot/dts/broadcom/ns2.dtsi              |   19 +
 drivers/mtd/devices/m25p80.c                       |    7 +-
 drivers/spi/Kconfig                                |   10 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/spi-bcm-qspi.c                         | 1440 ++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h                         |  112 ++
 drivers/spi/spi-brcmstb-qspi.c                     |   53 +
 drivers/spi/spi-nsp-qspi.c                         |  158 +++
 12 files changed, 2126 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
 create mode 100644 drivers/spi/spi-bcm-qspi.c
 create mode 100644 drivers/spi/spi-bcm-qspi.h
 create mode 100644 drivers/spi/spi-brcmstb-qspi.c
 create mode 100644 drivers/spi/spi-nsp-qspi.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v5 0/8]  Broadcom stb, nsp, ns2, cygnus QSPI driver
@ 2016-07-29 22:13 ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu

This is V5 changes for common spi driver for the brcmstb, nsp, ns2, cygnus
SoCs. Changes include driver for  standard MSPI and accelerated BSPI blocks.
The Brodcom STB uses l2-intc where as the SoC specific interrupt handling
code has been separated in a new  driver. In case of NS and NS2 SoCs it does
not have a dedicated l2 controller and the interrupts are specific to the 
spi core. The drivers are organized in the follwoing way:
 
 drivers/spi/spi-bcm-qspi.c      - Common MSPI, BSPI driver

 drivers/spi/spi-bcm-qspi.h      - Common header 

 drivers/spi/spi-brcmstb-qspi.c  - SoC specific wth brcm,spi-brcmstb-qspi 
                                   compatibility, does not have anything 
                                   specific for stb SoC

 drivers/spi/spi-nsp-qspi.c      - Implements the interrupt hooks used by 
                                   the common driver with "brcm,spi-nsp-qspi"
                                   compatibility
Changes in V5:
 - Added additional description in the binding documentation non MSPI and BSPI SoC IP
 - Split commits for MSPI spi driver and accelarated BSPI driver used for accelerated
   flash reads
 - Removed any parsing of transfer structures for commands
 - Other code cleanup for readability
 - Kept the interrupt handling code in separate driver, since hardware abstraction and l2
   controller driver in software do not exisit certain SoCs

Kamal Dasu (8):
  Documentation: dt: spi: Add BRCMSTB SoC bindings
  spi: bcm-qspi: Add Broadcom MSPI driver
  spi: bcm-qspi: Add BSPI spi-nor flash controller driver
  mtd: m25p80: Let m25p80_read() fallback to spi transfer
  Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
  arm: dts: Add bcm-nsp and bcm958625k support
  arm64: dts: Add ns2 SoC support
  spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support

 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  |  235 ++++
 arch/arm/boot/dts/bcm-nsp.dtsi                     |   33 +-
 arch/arm/boot/dts/bcm958625k.dts                   |   34 +
 arch/arm64/boot/dts/broadcom/ns2-svk.dts           |   34 +-
 arch/arm64/boot/dts/broadcom/ns2.dtsi              |   19 +
 drivers/mtd/devices/m25p80.c                       |    7 +-
 drivers/spi/Kconfig                                |   10 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/spi-bcm-qspi.c                         | 1440 ++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h                         |  112 ++
 drivers/spi/spi-brcmstb-qspi.c                     |   53 +
 drivers/spi/spi-nsp-qspi.c                         |  158 +++
 12 files changed, 2126 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
 create mode 100644 drivers/spi/spi-bcm-qspi.c
 create mode 100644 drivers/spi/spi-bcm-qspi.h
 create mode 100644 drivers/spi/spi-brcmstb-qspi.c
 create mode 100644 drivers/spi/spi-nsp-qspi.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu

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

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 145 +++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
new file mode 100644
index 0000000..bbae763
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -0,0 +1,145 @@
+Broadcom SPI controller
+
+The Broadcom SPI controller is a SPI master found on various SOCs, including
+BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
+of :
+ MSPI : SPI master controller can read and write to a SPI slave device
+ BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
+        for flash reads and be configured to do single, double, quad lane
+        io with 3-byte and 4-byte addressing support.
+
+ Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
+ MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
+ of a MSPI master without the BSPI to use with non flash slave devices that
+ use SPI protocol.
+
+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-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
+						   BRCMSTB  SoCs
+
+- reg:
+    Define the bases and ranges of the associated I/O address spaces.
+    The required range is MSPI controller registers.
+
+- 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, not required with compatible
+                   "spi-brcmstb-mspi"
+    - "mspi_regs": MSPI register range is required for compatible strings
+
+- interrupts
+    The interrupts used by the MSPI and/or BSPI controller.
+
+- interrupt-names:
+    Names of interrupts associated with MSPI
+    - "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
+
+- clocks:
+    A phandle to the reference clock for this block.
+
+Optional properties:
+
+
+- native-endian
+    Defined when using BE SoC and device uses BE register read/write
+
+Recommended optional m25p80 properties:
+- spi-rx-bus-width: Definition as per
+                    Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Examples:
+
+BRCMSTB SoC Example:
+
+  SPI Master (MSPI+BSPI) for SPI-NOR access:
+
+    spi@f03e3400 {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-qspi";
+		reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>;
+		reg-names = "cs_reg", "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 = <&hif_spi>;
+		clock-names = "sw_spi";
+
+		m25p80@0 {
+			#size-cells = <0x2>;
+			#address-cells = <0x2>;
+			compatible = "m25p80";
+			reg = <0x0>;
+			spi-max-frequency = <0x2625a00>;
+			spi-cpol;
+			spi-cpha;
+			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 for any SPI device :
+
+	spi@f0416000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&upg_fixed>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-mspi";
+		reg = <0xf0416000 0x180>;
+		reg-names = "mspi";
+		interrupts = <0x14>;
+		interrupt-parent = <&irq0_aon_intc>;
+		interrupt-names = "mspi_done";
+	};
+
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu

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

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 145 +++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
new file mode 100644
index 0000000..bbae763
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -0,0 +1,145 @@
+Broadcom SPI controller
+
+The Broadcom SPI controller is a SPI master found on various SOCs, including
+BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
+of :
+ MSPI : SPI master controller can read and write to a SPI slave device
+ BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
+        for flash reads and be configured to do single, double, quad lane
+        io with 3-byte and 4-byte addressing support.
+
+ Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
+ MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
+ of a MSPI master without the BSPI to use with non flash slave devices that
+ use SPI protocol.
+
+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-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
+						   BRCMSTB  SoCs
+
+- reg:
+    Define the bases and ranges of the associated I/O address spaces.
+    The required range is MSPI controller registers.
+
+- 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, not required with compatible
+                   "spi-brcmstb-mspi"
+    - "mspi_regs": MSPI register range is required for compatible strings
+
+- interrupts
+    The interrupts used by the MSPI and/or BSPI controller.
+
+- interrupt-names:
+    Names of interrupts associated with MSPI
+    - "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
+
+- clocks:
+    A phandle to the reference clock for this block.
+
+Optional properties:
+
+
+- native-endian
+    Defined when using BE SoC and device uses BE register read/write
+
+Recommended optional m25p80 properties:
+- spi-rx-bus-width: Definition as per
+                    Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Examples:
+
+BRCMSTB SoC Example:
+
+  SPI Master (MSPI+BSPI) for SPI-NOR access:
+
+    spi@f03e3400 {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-qspi";
+		reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>;
+		reg-names = "cs_reg", "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 = <&hif_spi>;
+		clock-names = "sw_spi";
+
+		m25p80@0 {
+			#size-cells = <0x2>;
+			#address-cells = <0x2>;
+			compatible = "m25p80";
+			reg = <0x0>;
+			spi-max-frequency = <0x2625a00>;
+			spi-cpol;
+			spi-cpha;
+			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 for any SPI device :
+
+	spi@f0416000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&upg_fixed>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-mspi";
+		reg = <0xf0416000 0x180>;
+		reg-names = "mspi";
+		interrupts = <0x14>;
+		interrupt-parent = <&irq0_aon_intc>;
+		interrupt-names = "mspi_done";
+	};
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu,
	Yendapally Reddy Dhananjaya Reddy

Master SPI driver for Broadcom settop SoC. The driver
is used for devices that use SPI protocol.

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
 drivers/spi/Kconfig            |  10 +
 drivers/spi/Makefile           |   1 +
 drivers/spi/spi-bcm-qspi.c     | 751 +++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h     |  61 ++++
 drivers/spi/spi-brcmstb-qspi.c |  53 +++
 5 files changed, 876 insertions(+)
 create mode 100644 drivers/spi/spi-bcm-qspi.c
 create mode 100644 drivers/spi/spi-bcm-qspi.h
 create mode 100644 drivers/spi/spi-brcmstb-qspi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index d6fb8d4..6c95912 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -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
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 185367e..3e753db 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -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-brcmstb-qspi.o 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
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
new file mode 100644
index 0000000..fb26709
--- /dev/null
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -0,0 +1,751 @@
+/*
+ * Driver for Broadcom BRCMSTB, NSP,  NS2, Cygnus SPI Controllers
+ *
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include "spi-bcm-qspi.h"
+
+#define DRIVER_NAME "bcm_qspi"
+
+#define BCM_QSPI_STATE_IDLE			0
+#define BCM_QSPI_STATE_RUNNING			1
+
+/* MSPI register offsets */
+#define MSPI_SPCR0_LSB				0x000
+#define MSPI_SPCR0_MSB				0x004
+#define MSPI_SPCR1_LSB				0x008
+#define MSPI_SPCR1_MSB				0x00c
+#define MSPI_NEWQP				0x010
+#define MSPI_ENDQP				0x014
+#define MSPI_SPCR2				0x018
+#define MSPI_MSPI_STATUS			0x020
+#define MSPI_CPTQP				0x024
+#define MSPI_SPCR3				0x028
+#define MSPI_TXRAM				0x040
+#define MSPI_RXRAM				0x0c0
+#define MSPI_CDRAM				0x140
+#define MSPI_WRITE_LOCK			0x180
+
+#define MSPI_MASTER_BIT			BIT(7)
+
+#define MSPI_NUM_CDRAM				16
+#define MSPI_CDRAM_CONT_BIT			BIT(7)
+#define MSPI_CDRAM_BITSE_BIT			BIT(6)
+#define MSPI_CDRAM_PCS				0xf
+
+#define MSPI_SPCR2_SPE				BIT(6)
+#define MSPI_SPCR2_CONT_AFTER_CMD		BIT(7)
+
+#define MSPI_MSPI_STATUS_SPIF			BIT(0)
+
+#define INTR_BASE_BIT_SHIFT			0x02
+#define INTR_COUNT				0x07
+
+#define NUM_CHIPSELECT				4
+#define MSPI_BASE_FREQ				27000000UL
+#define QSPI_SPBR_MIN				8U
+#define QSPI_SPBR_MAX				255U
+#define MAX_SPEED_HZ		(MSPI_BASE_FREQ / (QSPI_SPBR_MIN * 2))
+
+#define OPCODE_DIOR				0xBB
+#define OPCODE_QIOR				0xEB
+#define OPCODE_DIOR_4B				0xBC
+#define OPCODE_QIOR_4B				0xEC
+
+#define MAX_CMD_SIZE				6
+
+#define ADDR_4MB_MASK				GENMASK(22, 0)
+
+/* stop at end of transfer, no other reason */
+#define TRANS_STATUS_BREAK_NONE		0
+/* stop at end of spi_message */
+#define TRANS_STATUS_BREAK_EOM			1
+/* stop at end of spi_transfer if delay */
+#define TRANS_STATUS_BREAK_DELAY		2
+/* stop at end of spi_transfer if cs_change */
+#define TRANS_STATUS_BREAK_CS_CHANGE		4
+/* stop if we run out of bytes */
+#define TRANS_STATUS_BREAK_NO_BYTES		8
+
+/* events that make us stop filling TX slots */
+#define TRANS_STATUS_BREAK_TX (TRANS_STATUS_BREAK_EOM |		\
+			       TRANS_STATUS_BREAK_DELAY |		\
+			       TRANS_STATUS_BREAK_CS_CHANGE)
+
+/* events that make us deassert CS */
+#define TRANS_STATUS_BREAK_DESELECT (TRANS_STATUS_BREAK_EOM |		\
+				     TRANS_STATUS_BREAK_CS_CHANGE)
+
+struct bcm_qspi_parms {
+	u32 speed_hz;
+	u8 mode;
+	u8 bits_per_word;
+};
+
+static const struct bcm_qspi_parms bcm_qspi_default_parms_cs0 = {
+	.speed_hz = MAX_SPEED_HZ,
+	.mode = SPI_MODE_3,
+	.bits_per_word = 8,
+};
+
+enum base_type {
+	MSPI,
+	CHIP_SELECT,
+	BASEMAX,
+};
+
+struct bcm_qspi_irq {
+	const char *irq_name;
+	const irq_handler_t irq_handler;
+	u32 mask;
+};
+
+struct bcm_qspi_dev_id {
+	const struct bcm_qspi_irq *irqp;
+	void *dev;
+};
+
+struct qspi_trans {
+	struct spi_transfer *trans;
+	int byte;
+};
+
+struct bcm_qspi {
+	struct platform_device *pdev;
+	struct spi_master *master;
+	struct clk *clk;
+	u32 base_clk;
+	u32 max_speed_hz;
+	void __iomem *base[BASEMAX];
+	struct bcm_qspi_parms last_parms;
+	struct qspi_trans  trans_pos;
+	int state;
+	int next_udelay;
+	int cs_change;
+	int curr_cs;
+	u32 s3_strap_override_ctrl;
+	bool big_endian;
+	int num_irqs;
+	struct bcm_qspi_dev_id *dev_ids;
+	struct completion mspi_done;
+};
+
+/* Read qspi controller register*/
+static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type,
+				unsigned int offset)
+{
+	return bcm_qspi_readl(qspi->pdev, qspi->base[type] + offset);
+}
+
+/* Write qspi controller register*/
+static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type,
+				  unsigned int offset, unsigned int data)
+{
+	bcm_qspi_writel(qspi->pdev, data, qspi->base[type] + offset);
+}
+
+static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs)
+{
+	u32 data = 0;
+
+	if (qspi->curr_cs == cs)
+		return;
+	if (qspi->base[CHIP_SELECT]) {
+		data = bcm_qspi_read(qspi, CHIP_SELECT, 0);
+		data = (data & ~0xff) | (1 << cs);
+		bcm_qspi_write(qspi, CHIP_SELECT, 0, data);
+		usleep_range(10, 20);
+	}
+	qspi->curr_cs = cs;
+}
+
+/* MSPI helpers */
+static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi,
+				  const struct bcm_qspi_parms *xp)
+{
+	u32 spcr, spbr = 0;
+
+	if (xp->speed_hz)
+		spbr = qspi->base_clk / (2 * xp->speed_hz);
+
+	spcr = clamp_val(spbr, QSPI_SPBR_MIN, QSPI_SPBR_MAX);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spcr);
+
+	spcr = MSPI_MASTER_BIT;
+	/* for 16 bit the data should be zero */
+	if (xp->bits_per_word != 16)
+		spcr |= xp->bits_per_word << 2;
+	spcr |= xp->mode & 3;
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_MSB, spcr);
+
+	qspi->last_parms = *xp;
+}
+
+static void bcm_qspi_update_parms(struct bcm_qspi *qspi,
+				  struct spi_device *spi,
+				  struct spi_transfer *trans)
+{
+	struct bcm_qspi_parms xp;
+
+	xp.speed_hz = trans->speed_hz;
+	xp.bits_per_word = trans->bits_per_word;
+	xp.mode = spi->mode;
+
+	bcm_qspi_hw_set_parms(qspi, &xp);
+}
+
+static int bcm_qspi_setup(struct spi_device *spi)
+{
+	struct bcm_qspi_parms *xp;
+
+	if (spi->bits_per_word > 16)
+		return -EINVAL;
+
+	xp = spi_get_ctldata(spi);
+	if (!xp) {
+		xp = kzalloc(sizeof(*xp), GFP_KERNEL);
+		if (!xp)
+			return -ENOMEM;
+		spi_set_ctldata(spi, xp);
+	}
+	xp->speed_hz = spi->max_speed_hz;
+	xp->mode = spi->mode;
+
+	if (spi->bits_per_word)
+		xp->bits_per_word = spi->bits_per_word;
+	else
+		xp->bits_per_word = 8;
+
+	return 0;
+}
+
+static int update_qspi_trans_byte_count(struct bcm_qspi *qspi,
+					struct qspi_trans *qt, int flags)
+{
+	int ret = TRANS_STATUS_BREAK_NONE;
+
+	/* count the last transferred bytes */
+	if (qt->trans->bits_per_word <= 8)
+		qt->byte++;
+	else
+		qt->byte += 2;
+
+	if (qt->byte >= qt->trans->len) {
+		/* we're at the end of the spi_transfer */
+
+		/* in TX mode, need to pause for a delay or CS change */
+		if (qt->trans->delay_usecs &&
+		    (flags & TRANS_STATUS_BREAK_DELAY))
+			ret |= TRANS_STATUS_BREAK_DELAY;
+		if (qt->trans->cs_change &&
+		    (flags & TRANS_STATUS_BREAK_CS_CHANGE))
+			ret |= TRANS_STATUS_BREAK_CS_CHANGE;
+		if (ret)
+			goto done;
+
+		dev_dbg(&qspi->pdev->dev, "advance msg exit\n");
+		if (spi_transfer_is_last(qspi->master, qt->trans))
+			ret = TRANS_STATUS_BREAK_EOM;
+		else
+			ret = TRANS_STATUS_BREAK_NO_BYTES;
+
+		qt->trans = NULL;
+	}
+
+done:
+	dev_dbg(&qspi->pdev->dev, "trans %p len %d byte %d ret %x\n",
+		qt->trans, qt->trans ? qt->trans->len : 0, qt->byte, ret);
+	return ret;
+}
+
+static inline u8 read_rxram_slot_u8(struct bcm_qspi *qspi, int slot)
+{
+	u32 slot_offset = MSPI_RXRAM + (slot << 3) + 0x4;
+
+	/* mask out reserved bits */
+	return bcm_qspi_read(qspi, MSPI, slot_offset) & 0xff;
+}
+
+static inline u16 read_rxram_slot_u16(struct bcm_qspi *qspi, int slot)
+{
+	u32 reg_offset = MSPI_RXRAM;
+	u32 lsb_offset = reg_offset + (slot << 3) + 0x4;
+	u32 msb_offset = reg_offset + (slot << 3);
+
+	return (bcm_qspi_read(qspi, MSPI, lsb_offset) & 0xff) |
+		((bcm_qspi_read(qspi, MSPI, msb_offset) & 0xff) << 8);
+}
+
+static void read_from_hw(struct bcm_qspi *qspi, int slots)
+{
+	struct qspi_trans tp;
+	int slot;
+
+	if (slots > MSPI_NUM_CDRAM) {
+		/* should never happen */
+		dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__);
+		return;
+	}
+
+	tp = qspi->trans_pos;
+
+	for (slot = 0; slot < slots; slot++) {
+		if (tp.trans->bits_per_word <= 8) {
+			u8 *buf = tp.trans->rx_buf;
+
+			if (buf)
+				buf[tp.byte] = read_rxram_slot_u8(qspi, slot);
+			dev_dbg(&qspi->pdev->dev, "RD %02x\n",
+				buf ? buf[tp.byte] : 0xff);
+		} else {
+			u16 *buf = tp.trans->rx_buf;
+
+			if (buf)
+				buf[tp.byte / 2] = read_rxram_slot_u16(qspi,
+								      slot);
+			dev_dbg(&qspi->pdev->dev, "RD %04x\n",
+				buf ? buf[tp.byte] : 0xffff);
+		}
+
+		update_qspi_trans_byte_count(qspi, &tp,
+					     TRANS_STATUS_BREAK_NONE);
+	}
+
+	qspi->trans_pos = tp;
+}
+
+static inline void write_txram_slot_u8(struct bcm_qspi *qspi, int slot,
+				       u8 val)
+{
+	u32 reg_offset = MSPI_TXRAM + (slot << 3);
+
+	/* mask out reserved bits */
+	bcm_qspi_write(qspi, MSPI, reg_offset, val);
+}
+
+static inline void write_txram_slot_u16(struct bcm_qspi *qspi, int slot,
+					u16 val)
+{
+	u32 reg_offset = MSPI_TXRAM;
+	u32 msb_offset = reg_offset + (slot << 3);
+	u32 lsb_offset = reg_offset + (slot << 3) + 0x4;
+
+	bcm_qspi_write(qspi, MSPI, msb_offset, (val >> 8));
+	bcm_qspi_write(qspi, MSPI, lsb_offset, (val & 0xff));
+}
+
+static inline u32 read_cdram_slot(struct bcm_qspi *qspi, int slot)
+{
+	return bcm_qspi_read(qspi, MSPI, MSPI_CDRAM + (slot << 2));
+}
+
+static inline void write_cdram_slot(struct bcm_qspi *qspi, int slot, u32 val)
+{
+	bcm_qspi_write(qspi, MSPI, (MSPI_CDRAM + (slot << 2)), val);
+}
+
+/* Return number of slots written */
+static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
+{
+	struct qspi_trans tp;
+	int slot = 0, tstatus = 0;
+	u32 mspi_cdram = 0;
+
+	tp = qspi->trans_pos;
+	bcm_qspi_update_parms(qspi, spi, tp.trans);
+
+	/* Run until end of transfer or reached the max data */
+	while (!tstatus && slot < MSPI_NUM_CDRAM) {
+		if (tp.trans->bits_per_word <= 8) {
+			const u8 *buf = tp.trans->tx_buf;
+			u8 val = buf ? buf[tp.byte] : 0xff;
+
+			write_txram_slot_u8(qspi, slot, val);
+			dev_dbg(&qspi->pdev->dev, "WR %02x\n", val);
+		} else {
+			const u16 *buf = tp.trans->tx_buf;
+			u16 val = buf ? buf[tp.byte / 2] : 0xffff;
+
+			write_txram_slot_u16(qspi, slot, val);
+			dev_dbg(&qspi->pdev->dev, "WR %04x\n", val);
+		}
+		mspi_cdram = MSPI_CDRAM_CONT_BIT;
+		mspi_cdram |= (~(1 << spi->chip_select) &
+			       MSPI_CDRAM_PCS);
+		mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 :
+				MSPI_CDRAM_BITSE_BIT);
+
+		write_cdram_slot(qspi, slot, mspi_cdram);
+
+		tstatus = update_qspi_trans_byte_count(qspi, &tp,
+						       TRANS_STATUS_BREAK_TX);
+		slot++;
+	}
+	if (!slot) {
+		dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__);
+		goto done;
+	}
+
+	/* in TX mode, need to pause for a delay or CS change */
+	if (tstatus & TRANS_STATUS_BREAK_CS_CHANGE)
+		qspi->cs_change = 1;
+	if (tstatus & TRANS_STATUS_BREAK_DELAY)
+		qspi->next_udelay = tp.trans->delay_usecs;
+
+	dev_dbg(&qspi->pdev->dev, "submitting %d slots\n", slot);
+	bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, slot - 1);
+
+	if (tstatus & TRANS_STATUS_BREAK_DESELECT) {
+		mspi_cdram = read_cdram_slot(qspi, slot - 1) &
+			~MSPI_CDRAM_CONT_BIT;
+		write_cdram_slot(qspi, slot - 1, mspi_cdram);
+	}
+
+	/* Must flush previous writes before starting MSPI operation */
+	mb();
+	/* Set cont | spe | spifie */
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0xe0);
+	qspi->state = BCM_QSPI_STATE_RUNNING;
+
+done:
+	return slot;
+}
+
+static void hw_stop(struct bcm_qspi *qspi)
+{
+	qspi->state = BCM_QSPI_STATE_IDLE;
+}
+
+static int bcm_qspi_transfer_one(struct spi_master *master,
+				 struct spi_device *spi,
+				 struct spi_transfer *trans)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(master);
+	int slots;
+	unsigned long timeo = msecs_to_jiffies(100);
+
+	bcm_qspi_chip_select(qspi, spi->chip_select);
+	qspi->trans_pos.trans = trans;
+	qspi->trans_pos.byte = 0;
+
+	while (qspi->trans_pos.byte < trans->len) {
+		reinit_completion(&qspi->mspi_done);
+
+		slots = write_to_hw(qspi, spi);
+		if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
+			dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
+			return -ETIMEDOUT;
+		}
+
+		if (qspi->next_udelay) {
+			udelay(qspi->next_udelay);
+			qspi->next_udelay = 0;
+		}
+
+		read_from_hw(qspi, slots);
+		if (qspi->cs_change) {
+			usleep_range(10, 20);
+			qspi->cs_change = 0;
+		}
+	}
+
+	if (spi_transfer_is_last(master, trans))
+		hw_stop(qspi);
+
+	return 0;
+}
+
+static void bcm_qspi_cleanup(struct spi_device *spi)
+{
+	struct bcm_qspi_parms *xp = spi_get_ctldata(spi);
+
+	kfree(xp);
+}
+
+static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
+
+	if (status & MSPI_MSPI_STATUS_SPIF) {
+		/* clear interrupt */
+		status &= ~MSPI_MSPI_STATUS_SPIF;
+		bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
+		complete(&qspi->mspi_done);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static const struct bcm_qspi_irq qspi_irq_tab[] = {
+	{
+		.irq_name = "mspi_done",
+		.irq_handler = bcm_qspi_mspi_l2_isr,
+		.mask = INTR_MSPI_DONE_MASK,
+	},
+	{
+		.irq_name = "mspi_halted",
+		.irq_handler = bcm_qspi_mspi_l2_isr,
+		.mask = INTR_MSPI_HALTED_MASK,
+	},
+};
+
+static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
+{
+	u32 val = 0;
+	struct bcm_qspi_parms parms;
+
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_LSB, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_MSB, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0x20);
+
+	parms.mode = SPI_MODE_3;
+	parms.bits_per_word = 8;
+	of_property_read_u32(qspi->pdev->dev.of_node, "clock-frequency", &val);
+	if (val > 0) {
+		parms.speed_hz = val;
+		bcm_qspi_hw_set_parms(qspi, &parms);
+	} else {
+		bcm_qspi_hw_set_parms(qspi, &bcm_qspi_default_parms_cs0);
+	}
+
+}
+
+static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
+{
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0);
+}
+
+static const struct of_device_id bcm_qspi_of_match[] = {
+	{ .compatible = "brcm,spi-bcm-qspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
+
+int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm_qspi *qspi;
+	struct spi_master *master;
+	struct resource *res;
+	int irq, ret = 0, num_ints = 0;
+	u32 val;
+	const char *name = NULL;
+	int num_irqs = ARRAY_SIZE(qspi_irq_tab);
+
+	/* We only support device-tree instantiation */
+	if (!dev->of_node)
+		return -ENODEV;
+
+	if (!of_match_node(bcm_qspi_of_match, dev->of_node))
+		return -ENODEV;
+
+	master = spi_alloc_master(dev, sizeof(struct bcm_qspi));
+	if (!master) {
+		dev_err(dev, "error allocating spi_master\n");
+		return -ENOMEM;
+	}
+
+	qspi = spi_master_get_devdata(master);
+	qspi->pdev = pdev;
+	qspi->state = BCM_QSPI_STATE_IDLE;
+	qspi->trans_pos.trans = NULL;
+	qspi->trans_pos.byte = 0;
+	qspi->master = master;
+
+	master->bus_num = -1;
+	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD;
+	master->setup = bcm_qspi_setup;
+	master->transfer_one = bcm_qspi_transfer_one;
+	master->cleanup = bcm_qspi_cleanup;
+	master->dev.of_node = dev->of_node;
+	master->num_chipselect = NUM_CHIPSELECT;
+
+	qspi->big_endian = of_device_is_big_endian(dev->of_node);
+
+	if (!of_property_read_u32(dev->of_node, "num-cs", &val))
+		master->num_chipselect = val;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi");
+	if (!res)
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   "mspi");
+
+	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;
+	}
+
+	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;
+		}
+	}
+
+	qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id),
+				GFP_KERNEL);
+	if (IS_ERR(qspi->dev_ids)) {
+		ret = PTR_ERR(qspi->dev_ids);
+		goto err2;
+	}
+
+	for (val = 0; val < num_irqs; val++) {
+		irq = -1;
+		name = qspi_irq_tab[val].irq_name;
+		irq = platform_get_irq_byname(pdev, name);
+
+		if (irq  >= 0) {
+			ret = devm_request_irq(&pdev->dev, irq,
+					       qspi_irq_tab[val].irq_handler, 0,
+					       name,
+					       &qspi->dev_ids[val]);
+			if (ret < 0) {
+				dev_err(&pdev->dev, "IRQ %s not found\n", name);
+				goto err2;
+			}
+
+			qspi->dev_ids[val].dev = qspi;
+			qspi->dev_ids[val].irqp = &qspi_irq_tab[val];
+			num_ints++;
+			dev_dbg(&pdev->dev, "registered IRQ %s %d\n",
+				qspi_irq_tab[val].irq_name,
+				irq);
+		}
+	}
+
+	if (!num_ints) {
+		dev_err(&pdev->dev, "no IRQs registered, cannot init driver\n");
+		goto err2;
+	}
+
+	qspi->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(qspi->clk)) {
+		dev_warn(dev, "unable to get clock\n");
+		goto err2;
+	}
+
+	ret = clk_prepare_enable(qspi->clk);
+	if (ret) {
+		dev_err(dev, "failed to prepare clock\n");
+		goto err2;
+	}
+
+	qspi->base_clk = clk_get_rate(qspi->clk);
+	qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2);
+
+	bcm_qspi_hw_init(qspi);
+	init_completion(&qspi->mspi_done);
+	qspi->curr_cs = -1;
+
+	platform_set_drvdata(pdev, qspi);
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret < 0) {
+		dev_err(dev, "can't register master\n");
+		goto err1;
+	}
+
+	return 0;
+
+err1:
+	bcm_qspi_hw_uninit(qspi);
+	clk_disable_unprepare(qspi->clk);
+err2:
+	spi_master_put(master);
+	kfree(qspi->dev_ids);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_qspi_probe);
+
+int bcm_qspi_remove(struct platform_device *pdev)
+{
+	struct bcm_qspi *qspi = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	bcm_qspi_hw_uninit(qspi);
+	clk_disable_unprepare(qspi->clk);
+	kfree(qspi->dev_ids);
+	spi_unregister_master(qspi->master);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(bcm_qspi_remove);
+
+#ifdef CONFIG_PM_SLEEP
+static int bcm_qspi_suspend(struct device *dev)
+{
+	struct bcm_qspi *qspi = dev_get_drvdata(dev);
+
+	clk_disable(qspi->clk);
+	return 0;
+};
+
+static int bcm_qspi_resume(struct device *dev)
+{
+	struct bcm_qspi *qspi = dev_get_drvdata(dev);
+	int curr_cs = qspi->curr_cs;
+	int ret = 0;
+
+	bcm_qspi_hw_init(qspi);
+	qspi->curr_cs = -1;
+	bcm_qspi_chip_select(qspi, curr_cs);
+
+	ret = clk_enable(qspi->clk);
+
+	return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+const struct dev_pm_ops bcm_qspi_pm_ops = {
+	.suspend = bcm_qspi_suspend,
+	.resume  = bcm_qspi_resume,
+};
+EXPORT_SYMBOL_GPL(bcm_qspi_pm_ops);
+
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("Broadcom QSPI driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
new file mode 100644
index 0000000..0bdddd4
--- /dev/null
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#ifndef __SPI_BCM_QSPI_H__
+#define __SPI_BCM_QSPI_H__
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/* MSPI Interrupt masks */
+#define INTR_MSPI_HALTED_MASK			BIT(6)
+#define INTR_MSPI_DONE_MASK			BIT(5)
+
+#define MSPI_INTERRUPTS_ALL		       \
+	(INTR_MSPI_DONE_MASK |		       \
+	 INTR_MSPI_HALTED_MASK)
+
+struct platform_device;
+struct dev_pm_ops;
+
+struct bcm_qspi_soc;
+
+/* Read controller register*/
+static inline u32 bcm_qspi_readl(struct platform_device *pdev,
+				 void __iomem *addr)
+{
+	if (of_device_is_big_endian(pdev->dev.of_node))
+		return ioread32be(addr);
+	else
+		return readl_relaxed(addr);
+}
+
+/* Write controller register*/
+static inline void bcm_qspi_writel(struct platform_device *pdev,
+				   unsigned int data, void __iomem *addr)
+{
+	if (of_device_is_big_endian(pdev->dev.of_node))
+		iowrite32be(data, addr);
+	else
+		writel_relaxed(data, addr);
+}
+
+int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc);
+int bcm_qspi_remove(struct platform_device *pdev);
+
+extern const struct dev_pm_ops bcm_qspi_pm_ops;
+
+#endif /* __SPI_BCM_QSPI_H__ */
diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
new file mode 100644
index 0000000..c7df92e
--- /dev/null
+++ b/drivers/spi/spi-brcmstb-qspi.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include "spi-bcm-qspi.h"
+
+static const struct of_device_id brcmstb_qspi_of_match[] = {
+	{ .compatible = "brcm,spi-brcmstb-qspi" },
+	{ .compatible = "brcm,spi-brcmstb-mspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, brcmstb_qspi_of_match);
+
+static int brcmstb_qspi_probe(struct platform_device *pdev)
+{
+	return bcm_qspi_probe(pdev, NULL);
+}
+
+static int brcmstb_qspi_remove(struct platform_device *pdev)
+{
+	return bcm_qspi_remove(pdev);
+}
+
+static struct platform_driver brcmstb_qspi_driver = {
+	.probe			= brcmstb_qspi_probe,
+	.remove			= brcmstb_qspi_remove,
+	.driver = {
+		.name		= "brcmstb_qspi",
+		.pm		= &bcm_qspi_pm_ops,
+		.of_match_table = brcmstb_qspi_of_match,
+	}
+};
+module_platform_driver(brcmstb_qspi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("Broadcom SPI driver for settop SoC");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu, Yendapally Reddy Dhananjaya Reddy

Master SPI driver for Broadcom settop SoC. The driver
is used for devices that use SPI protocol.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
---
 drivers/spi/Kconfig            |  10 +
 drivers/spi/Makefile           |   1 +
 drivers/spi/spi-bcm-qspi.c     | 751 +++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h     |  61 ++++
 drivers/spi/spi-brcmstb-qspi.c |  53 +++
 5 files changed, 876 insertions(+)
 create mode 100644 drivers/spi/spi-bcm-qspi.c
 create mode 100644 drivers/spi/spi-bcm-qspi.h
 create mode 100644 drivers/spi/spi-brcmstb-qspi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index d6fb8d4..6c95912 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -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
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 185367e..3e753db 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -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-brcmstb-qspi.o 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
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
new file mode 100644
index 0000000..fb26709
--- /dev/null
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -0,0 +1,751 @@
+/*
+ * Driver for Broadcom BRCMSTB, NSP,  NS2, Cygnus SPI Controllers
+ *
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include "spi-bcm-qspi.h"
+
+#define DRIVER_NAME "bcm_qspi"
+
+#define BCM_QSPI_STATE_IDLE			0
+#define BCM_QSPI_STATE_RUNNING			1
+
+/* MSPI register offsets */
+#define MSPI_SPCR0_LSB				0x000
+#define MSPI_SPCR0_MSB				0x004
+#define MSPI_SPCR1_LSB				0x008
+#define MSPI_SPCR1_MSB				0x00c
+#define MSPI_NEWQP				0x010
+#define MSPI_ENDQP				0x014
+#define MSPI_SPCR2				0x018
+#define MSPI_MSPI_STATUS			0x020
+#define MSPI_CPTQP				0x024
+#define MSPI_SPCR3				0x028
+#define MSPI_TXRAM				0x040
+#define MSPI_RXRAM				0x0c0
+#define MSPI_CDRAM				0x140
+#define MSPI_WRITE_LOCK			0x180
+
+#define MSPI_MASTER_BIT			BIT(7)
+
+#define MSPI_NUM_CDRAM				16
+#define MSPI_CDRAM_CONT_BIT			BIT(7)
+#define MSPI_CDRAM_BITSE_BIT			BIT(6)
+#define MSPI_CDRAM_PCS				0xf
+
+#define MSPI_SPCR2_SPE				BIT(6)
+#define MSPI_SPCR2_CONT_AFTER_CMD		BIT(7)
+
+#define MSPI_MSPI_STATUS_SPIF			BIT(0)
+
+#define INTR_BASE_BIT_SHIFT			0x02
+#define INTR_COUNT				0x07
+
+#define NUM_CHIPSELECT				4
+#define MSPI_BASE_FREQ				27000000UL
+#define QSPI_SPBR_MIN				8U
+#define QSPI_SPBR_MAX				255U
+#define MAX_SPEED_HZ		(MSPI_BASE_FREQ / (QSPI_SPBR_MIN * 2))
+
+#define OPCODE_DIOR				0xBB
+#define OPCODE_QIOR				0xEB
+#define OPCODE_DIOR_4B				0xBC
+#define OPCODE_QIOR_4B				0xEC
+
+#define MAX_CMD_SIZE				6
+
+#define ADDR_4MB_MASK				GENMASK(22, 0)
+
+/* stop at end of transfer, no other reason */
+#define TRANS_STATUS_BREAK_NONE		0
+/* stop at end of spi_message */
+#define TRANS_STATUS_BREAK_EOM			1
+/* stop at end of spi_transfer if delay */
+#define TRANS_STATUS_BREAK_DELAY		2
+/* stop at end of spi_transfer if cs_change */
+#define TRANS_STATUS_BREAK_CS_CHANGE		4
+/* stop if we run out of bytes */
+#define TRANS_STATUS_BREAK_NO_BYTES		8
+
+/* events that make us stop filling TX slots */
+#define TRANS_STATUS_BREAK_TX (TRANS_STATUS_BREAK_EOM |		\
+			       TRANS_STATUS_BREAK_DELAY |		\
+			       TRANS_STATUS_BREAK_CS_CHANGE)
+
+/* events that make us deassert CS */
+#define TRANS_STATUS_BREAK_DESELECT (TRANS_STATUS_BREAK_EOM |		\
+				     TRANS_STATUS_BREAK_CS_CHANGE)
+
+struct bcm_qspi_parms {
+	u32 speed_hz;
+	u8 mode;
+	u8 bits_per_word;
+};
+
+static const struct bcm_qspi_parms bcm_qspi_default_parms_cs0 = {
+	.speed_hz = MAX_SPEED_HZ,
+	.mode = SPI_MODE_3,
+	.bits_per_word = 8,
+};
+
+enum base_type {
+	MSPI,
+	CHIP_SELECT,
+	BASEMAX,
+};
+
+struct bcm_qspi_irq {
+	const char *irq_name;
+	const irq_handler_t irq_handler;
+	u32 mask;
+};
+
+struct bcm_qspi_dev_id {
+	const struct bcm_qspi_irq *irqp;
+	void *dev;
+};
+
+struct qspi_trans {
+	struct spi_transfer *trans;
+	int byte;
+};
+
+struct bcm_qspi {
+	struct platform_device *pdev;
+	struct spi_master *master;
+	struct clk *clk;
+	u32 base_clk;
+	u32 max_speed_hz;
+	void __iomem *base[BASEMAX];
+	struct bcm_qspi_parms last_parms;
+	struct qspi_trans  trans_pos;
+	int state;
+	int next_udelay;
+	int cs_change;
+	int curr_cs;
+	u32 s3_strap_override_ctrl;
+	bool big_endian;
+	int num_irqs;
+	struct bcm_qspi_dev_id *dev_ids;
+	struct completion mspi_done;
+};
+
+/* Read qspi controller register*/
+static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type,
+				unsigned int offset)
+{
+	return bcm_qspi_readl(qspi->pdev, qspi->base[type] + offset);
+}
+
+/* Write qspi controller register*/
+static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type,
+				  unsigned int offset, unsigned int data)
+{
+	bcm_qspi_writel(qspi->pdev, data, qspi->base[type] + offset);
+}
+
+static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs)
+{
+	u32 data = 0;
+
+	if (qspi->curr_cs == cs)
+		return;
+	if (qspi->base[CHIP_SELECT]) {
+		data = bcm_qspi_read(qspi, CHIP_SELECT, 0);
+		data = (data & ~0xff) | (1 << cs);
+		bcm_qspi_write(qspi, CHIP_SELECT, 0, data);
+		usleep_range(10, 20);
+	}
+	qspi->curr_cs = cs;
+}
+
+/* MSPI helpers */
+static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi,
+				  const struct bcm_qspi_parms *xp)
+{
+	u32 spcr, spbr = 0;
+
+	if (xp->speed_hz)
+		spbr = qspi->base_clk / (2 * xp->speed_hz);
+
+	spcr = clamp_val(spbr, QSPI_SPBR_MIN, QSPI_SPBR_MAX);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spcr);
+
+	spcr = MSPI_MASTER_BIT;
+	/* for 16 bit the data should be zero */
+	if (xp->bits_per_word != 16)
+		spcr |= xp->bits_per_word << 2;
+	spcr |= xp->mode & 3;
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_MSB, spcr);
+
+	qspi->last_parms = *xp;
+}
+
+static void bcm_qspi_update_parms(struct bcm_qspi *qspi,
+				  struct spi_device *spi,
+				  struct spi_transfer *trans)
+{
+	struct bcm_qspi_parms xp;
+
+	xp.speed_hz = trans->speed_hz;
+	xp.bits_per_word = trans->bits_per_word;
+	xp.mode = spi->mode;
+
+	bcm_qspi_hw_set_parms(qspi, &xp);
+}
+
+static int bcm_qspi_setup(struct spi_device *spi)
+{
+	struct bcm_qspi_parms *xp;
+
+	if (spi->bits_per_word > 16)
+		return -EINVAL;
+
+	xp = spi_get_ctldata(spi);
+	if (!xp) {
+		xp = kzalloc(sizeof(*xp), GFP_KERNEL);
+		if (!xp)
+			return -ENOMEM;
+		spi_set_ctldata(spi, xp);
+	}
+	xp->speed_hz = spi->max_speed_hz;
+	xp->mode = spi->mode;
+
+	if (spi->bits_per_word)
+		xp->bits_per_word = spi->bits_per_word;
+	else
+		xp->bits_per_word = 8;
+
+	return 0;
+}
+
+static int update_qspi_trans_byte_count(struct bcm_qspi *qspi,
+					struct qspi_trans *qt, int flags)
+{
+	int ret = TRANS_STATUS_BREAK_NONE;
+
+	/* count the last transferred bytes */
+	if (qt->trans->bits_per_word <= 8)
+		qt->byte++;
+	else
+		qt->byte += 2;
+
+	if (qt->byte >= qt->trans->len) {
+		/* we're at the end of the spi_transfer */
+
+		/* in TX mode, need to pause for a delay or CS change */
+		if (qt->trans->delay_usecs &&
+		    (flags & TRANS_STATUS_BREAK_DELAY))
+			ret |= TRANS_STATUS_BREAK_DELAY;
+		if (qt->trans->cs_change &&
+		    (flags & TRANS_STATUS_BREAK_CS_CHANGE))
+			ret |= TRANS_STATUS_BREAK_CS_CHANGE;
+		if (ret)
+			goto done;
+
+		dev_dbg(&qspi->pdev->dev, "advance msg exit\n");
+		if (spi_transfer_is_last(qspi->master, qt->trans))
+			ret = TRANS_STATUS_BREAK_EOM;
+		else
+			ret = TRANS_STATUS_BREAK_NO_BYTES;
+
+		qt->trans = NULL;
+	}
+
+done:
+	dev_dbg(&qspi->pdev->dev, "trans %p len %d byte %d ret %x\n",
+		qt->trans, qt->trans ? qt->trans->len : 0, qt->byte, ret);
+	return ret;
+}
+
+static inline u8 read_rxram_slot_u8(struct bcm_qspi *qspi, int slot)
+{
+	u32 slot_offset = MSPI_RXRAM + (slot << 3) + 0x4;
+
+	/* mask out reserved bits */
+	return bcm_qspi_read(qspi, MSPI, slot_offset) & 0xff;
+}
+
+static inline u16 read_rxram_slot_u16(struct bcm_qspi *qspi, int slot)
+{
+	u32 reg_offset = MSPI_RXRAM;
+	u32 lsb_offset = reg_offset + (slot << 3) + 0x4;
+	u32 msb_offset = reg_offset + (slot << 3);
+
+	return (bcm_qspi_read(qspi, MSPI, lsb_offset) & 0xff) |
+		((bcm_qspi_read(qspi, MSPI, msb_offset) & 0xff) << 8);
+}
+
+static void read_from_hw(struct bcm_qspi *qspi, int slots)
+{
+	struct qspi_trans tp;
+	int slot;
+
+	if (slots > MSPI_NUM_CDRAM) {
+		/* should never happen */
+		dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__);
+		return;
+	}
+
+	tp = qspi->trans_pos;
+
+	for (slot = 0; slot < slots; slot++) {
+		if (tp.trans->bits_per_word <= 8) {
+			u8 *buf = tp.trans->rx_buf;
+
+			if (buf)
+				buf[tp.byte] = read_rxram_slot_u8(qspi, slot);
+			dev_dbg(&qspi->pdev->dev, "RD %02x\n",
+				buf ? buf[tp.byte] : 0xff);
+		} else {
+			u16 *buf = tp.trans->rx_buf;
+
+			if (buf)
+				buf[tp.byte / 2] = read_rxram_slot_u16(qspi,
+								      slot);
+			dev_dbg(&qspi->pdev->dev, "RD %04x\n",
+				buf ? buf[tp.byte] : 0xffff);
+		}
+
+		update_qspi_trans_byte_count(qspi, &tp,
+					     TRANS_STATUS_BREAK_NONE);
+	}
+
+	qspi->trans_pos = tp;
+}
+
+static inline void write_txram_slot_u8(struct bcm_qspi *qspi, int slot,
+				       u8 val)
+{
+	u32 reg_offset = MSPI_TXRAM + (slot << 3);
+
+	/* mask out reserved bits */
+	bcm_qspi_write(qspi, MSPI, reg_offset, val);
+}
+
+static inline void write_txram_slot_u16(struct bcm_qspi *qspi, int slot,
+					u16 val)
+{
+	u32 reg_offset = MSPI_TXRAM;
+	u32 msb_offset = reg_offset + (slot << 3);
+	u32 lsb_offset = reg_offset + (slot << 3) + 0x4;
+
+	bcm_qspi_write(qspi, MSPI, msb_offset, (val >> 8));
+	bcm_qspi_write(qspi, MSPI, lsb_offset, (val & 0xff));
+}
+
+static inline u32 read_cdram_slot(struct bcm_qspi *qspi, int slot)
+{
+	return bcm_qspi_read(qspi, MSPI, MSPI_CDRAM + (slot << 2));
+}
+
+static inline void write_cdram_slot(struct bcm_qspi *qspi, int slot, u32 val)
+{
+	bcm_qspi_write(qspi, MSPI, (MSPI_CDRAM + (slot << 2)), val);
+}
+
+/* Return number of slots written */
+static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
+{
+	struct qspi_trans tp;
+	int slot = 0, tstatus = 0;
+	u32 mspi_cdram = 0;
+
+	tp = qspi->trans_pos;
+	bcm_qspi_update_parms(qspi, spi, tp.trans);
+
+	/* Run until end of transfer or reached the max data */
+	while (!tstatus && slot < MSPI_NUM_CDRAM) {
+		if (tp.trans->bits_per_word <= 8) {
+			const u8 *buf = tp.trans->tx_buf;
+			u8 val = buf ? buf[tp.byte] : 0xff;
+
+			write_txram_slot_u8(qspi, slot, val);
+			dev_dbg(&qspi->pdev->dev, "WR %02x\n", val);
+		} else {
+			const u16 *buf = tp.trans->tx_buf;
+			u16 val = buf ? buf[tp.byte / 2] : 0xffff;
+
+			write_txram_slot_u16(qspi, slot, val);
+			dev_dbg(&qspi->pdev->dev, "WR %04x\n", val);
+		}
+		mspi_cdram = MSPI_CDRAM_CONT_BIT;
+		mspi_cdram |= (~(1 << spi->chip_select) &
+			       MSPI_CDRAM_PCS);
+		mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 :
+				MSPI_CDRAM_BITSE_BIT);
+
+		write_cdram_slot(qspi, slot, mspi_cdram);
+
+		tstatus = update_qspi_trans_byte_count(qspi, &tp,
+						       TRANS_STATUS_BREAK_TX);
+		slot++;
+	}
+	if (!slot) {
+		dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__);
+		goto done;
+	}
+
+	/* in TX mode, need to pause for a delay or CS change */
+	if (tstatus & TRANS_STATUS_BREAK_CS_CHANGE)
+		qspi->cs_change = 1;
+	if (tstatus & TRANS_STATUS_BREAK_DELAY)
+		qspi->next_udelay = tp.trans->delay_usecs;
+
+	dev_dbg(&qspi->pdev->dev, "submitting %d slots\n", slot);
+	bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, slot - 1);
+
+	if (tstatus & TRANS_STATUS_BREAK_DESELECT) {
+		mspi_cdram = read_cdram_slot(qspi, slot - 1) &
+			~MSPI_CDRAM_CONT_BIT;
+		write_cdram_slot(qspi, slot - 1, mspi_cdram);
+	}
+
+	/* Must flush previous writes before starting MSPI operation */
+	mb();
+	/* Set cont | spe | spifie */
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0xe0);
+	qspi->state = BCM_QSPI_STATE_RUNNING;
+
+done:
+	return slot;
+}
+
+static void hw_stop(struct bcm_qspi *qspi)
+{
+	qspi->state = BCM_QSPI_STATE_IDLE;
+}
+
+static int bcm_qspi_transfer_one(struct spi_master *master,
+				 struct spi_device *spi,
+				 struct spi_transfer *trans)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(master);
+	int slots;
+	unsigned long timeo = msecs_to_jiffies(100);
+
+	bcm_qspi_chip_select(qspi, spi->chip_select);
+	qspi->trans_pos.trans = trans;
+	qspi->trans_pos.byte = 0;
+
+	while (qspi->trans_pos.byte < trans->len) {
+		reinit_completion(&qspi->mspi_done);
+
+		slots = write_to_hw(qspi, spi);
+		if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) {
+			dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n");
+			return -ETIMEDOUT;
+		}
+
+		if (qspi->next_udelay) {
+			udelay(qspi->next_udelay);
+			qspi->next_udelay = 0;
+		}
+
+		read_from_hw(qspi, slots);
+		if (qspi->cs_change) {
+			usleep_range(10, 20);
+			qspi->cs_change = 0;
+		}
+	}
+
+	if (spi_transfer_is_last(master, trans))
+		hw_stop(qspi);
+
+	return 0;
+}
+
+static void bcm_qspi_cleanup(struct spi_device *spi)
+{
+	struct bcm_qspi_parms *xp = spi_get_ctldata(spi);
+
+	kfree(xp);
+}
+
+static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
+
+	if (status & MSPI_MSPI_STATUS_SPIF) {
+		/* clear interrupt */
+		status &= ~MSPI_MSPI_STATUS_SPIF;
+		bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
+		complete(&qspi->mspi_done);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static const struct bcm_qspi_irq qspi_irq_tab[] = {
+	{
+		.irq_name = "mspi_done",
+		.irq_handler = bcm_qspi_mspi_l2_isr,
+		.mask = INTR_MSPI_DONE_MASK,
+	},
+	{
+		.irq_name = "mspi_halted",
+		.irq_handler = bcm_qspi_mspi_l2_isr,
+		.mask = INTR_MSPI_HALTED_MASK,
+	},
+};
+
+static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
+{
+	u32 val = 0;
+	struct bcm_qspi_parms parms;
+
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_LSB, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_MSB, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, 0);
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0x20);
+
+	parms.mode = SPI_MODE_3;
+	parms.bits_per_word = 8;
+	of_property_read_u32(qspi->pdev->dev.of_node, "clock-frequency", &val);
+	if (val > 0) {
+		parms.speed_hz = val;
+		bcm_qspi_hw_set_parms(qspi, &parms);
+	} else {
+		bcm_qspi_hw_set_parms(qspi, &bcm_qspi_default_parms_cs0);
+	}
+
+}
+
+static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
+{
+	bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0);
+}
+
+static const struct of_device_id bcm_qspi_of_match[] = {
+	{ .compatible = "brcm,spi-bcm-qspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
+
+int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm_qspi *qspi;
+	struct spi_master *master;
+	struct resource *res;
+	int irq, ret = 0, num_ints = 0;
+	u32 val;
+	const char *name = NULL;
+	int num_irqs = ARRAY_SIZE(qspi_irq_tab);
+
+	/* We only support device-tree instantiation */
+	if (!dev->of_node)
+		return -ENODEV;
+
+	if (!of_match_node(bcm_qspi_of_match, dev->of_node))
+		return -ENODEV;
+
+	master = spi_alloc_master(dev, sizeof(struct bcm_qspi));
+	if (!master) {
+		dev_err(dev, "error allocating spi_master\n");
+		return -ENOMEM;
+	}
+
+	qspi = spi_master_get_devdata(master);
+	qspi->pdev = pdev;
+	qspi->state = BCM_QSPI_STATE_IDLE;
+	qspi->trans_pos.trans = NULL;
+	qspi->trans_pos.byte = 0;
+	qspi->master = master;
+
+	master->bus_num = -1;
+	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD;
+	master->setup = bcm_qspi_setup;
+	master->transfer_one = bcm_qspi_transfer_one;
+	master->cleanup = bcm_qspi_cleanup;
+	master->dev.of_node = dev->of_node;
+	master->num_chipselect = NUM_CHIPSELECT;
+
+	qspi->big_endian = of_device_is_big_endian(dev->of_node);
+
+	if (!of_property_read_u32(dev->of_node, "num-cs", &val))
+		master->num_chipselect = val;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi");
+	if (!res)
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   "mspi");
+
+	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;
+	}
+
+	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;
+		}
+	}
+
+	qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id),
+				GFP_KERNEL);
+	if (IS_ERR(qspi->dev_ids)) {
+		ret = PTR_ERR(qspi->dev_ids);
+		goto err2;
+	}
+
+	for (val = 0; val < num_irqs; val++) {
+		irq = -1;
+		name = qspi_irq_tab[val].irq_name;
+		irq = platform_get_irq_byname(pdev, name);
+
+		if (irq  >= 0) {
+			ret = devm_request_irq(&pdev->dev, irq,
+					       qspi_irq_tab[val].irq_handler, 0,
+					       name,
+					       &qspi->dev_ids[val]);
+			if (ret < 0) {
+				dev_err(&pdev->dev, "IRQ %s not found\n", name);
+				goto err2;
+			}
+
+			qspi->dev_ids[val].dev = qspi;
+			qspi->dev_ids[val].irqp = &qspi_irq_tab[val];
+			num_ints++;
+			dev_dbg(&pdev->dev, "registered IRQ %s %d\n",
+				qspi_irq_tab[val].irq_name,
+				irq);
+		}
+	}
+
+	if (!num_ints) {
+		dev_err(&pdev->dev, "no IRQs registered, cannot init driver\n");
+		goto err2;
+	}
+
+	qspi->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(qspi->clk)) {
+		dev_warn(dev, "unable to get clock\n");
+		goto err2;
+	}
+
+	ret = clk_prepare_enable(qspi->clk);
+	if (ret) {
+		dev_err(dev, "failed to prepare clock\n");
+		goto err2;
+	}
+
+	qspi->base_clk = clk_get_rate(qspi->clk);
+	qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2);
+
+	bcm_qspi_hw_init(qspi);
+	init_completion(&qspi->mspi_done);
+	qspi->curr_cs = -1;
+
+	platform_set_drvdata(pdev, qspi);
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret < 0) {
+		dev_err(dev, "can't register master\n");
+		goto err1;
+	}
+
+	return 0;
+
+err1:
+	bcm_qspi_hw_uninit(qspi);
+	clk_disable_unprepare(qspi->clk);
+err2:
+	spi_master_put(master);
+	kfree(qspi->dev_ids);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_qspi_probe);
+
+int bcm_qspi_remove(struct platform_device *pdev)
+{
+	struct bcm_qspi *qspi = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	bcm_qspi_hw_uninit(qspi);
+	clk_disable_unprepare(qspi->clk);
+	kfree(qspi->dev_ids);
+	spi_unregister_master(qspi->master);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(bcm_qspi_remove);
+
+#ifdef CONFIG_PM_SLEEP
+static int bcm_qspi_suspend(struct device *dev)
+{
+	struct bcm_qspi *qspi = dev_get_drvdata(dev);
+
+	clk_disable(qspi->clk);
+	return 0;
+};
+
+static int bcm_qspi_resume(struct device *dev)
+{
+	struct bcm_qspi *qspi = dev_get_drvdata(dev);
+	int curr_cs = qspi->curr_cs;
+	int ret = 0;
+
+	bcm_qspi_hw_init(qspi);
+	qspi->curr_cs = -1;
+	bcm_qspi_chip_select(qspi, curr_cs);
+
+	ret = clk_enable(qspi->clk);
+
+	return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+const struct dev_pm_ops bcm_qspi_pm_ops = {
+	.suspend = bcm_qspi_suspend,
+	.resume  = bcm_qspi_resume,
+};
+EXPORT_SYMBOL_GPL(bcm_qspi_pm_ops);
+
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("Broadcom QSPI driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
new file mode 100644
index 0000000..0bdddd4
--- /dev/null
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#ifndef __SPI_BCM_QSPI_H__
+#define __SPI_BCM_QSPI_H__
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/* MSPI Interrupt masks */
+#define INTR_MSPI_HALTED_MASK			BIT(6)
+#define INTR_MSPI_DONE_MASK			BIT(5)
+
+#define MSPI_INTERRUPTS_ALL		       \
+	(INTR_MSPI_DONE_MASK |		       \
+	 INTR_MSPI_HALTED_MASK)
+
+struct platform_device;
+struct dev_pm_ops;
+
+struct bcm_qspi_soc;
+
+/* Read controller register*/
+static inline u32 bcm_qspi_readl(struct platform_device *pdev,
+				 void __iomem *addr)
+{
+	if (of_device_is_big_endian(pdev->dev.of_node))
+		return ioread32be(addr);
+	else
+		return readl_relaxed(addr);
+}
+
+/* Write controller register*/
+static inline void bcm_qspi_writel(struct platform_device *pdev,
+				   unsigned int data, void __iomem *addr)
+{
+	if (of_device_is_big_endian(pdev->dev.of_node))
+		iowrite32be(data, addr);
+	else
+		writel_relaxed(data, addr);
+}
+
+int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc);
+int bcm_qspi_remove(struct platform_device *pdev);
+
+extern const struct dev_pm_ops bcm_qspi_pm_ops;
+
+#endif /* __SPI_BCM_QSPI_H__ */
diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
new file mode 100644
index 0000000..c7df92e
--- /dev/null
+++ b/drivers/spi/spi-brcmstb-qspi.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include "spi-bcm-qspi.h"
+
+static const struct of_device_id brcmstb_qspi_of_match[] = {
+	{ .compatible = "brcm,spi-brcmstb-qspi" },
+	{ .compatible = "brcm,spi-brcmstb-mspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, brcmstb_qspi_of_match);
+
+static int brcmstb_qspi_probe(struct platform_device *pdev)
+{
+	return bcm_qspi_probe(pdev, NULL);
+}
+
+static int brcmstb_qspi_remove(struct platform_device *pdev)
+{
+	return bcm_qspi_remove(pdev);
+}
+
+static struct platform_driver brcmstb_qspi_driver = {
+	.probe			= brcmstb_qspi_probe,
+	.remove			= brcmstb_qspi_remove,
+	.driver = {
+		.name		= "brcmstb_qspi",
+		.pm		= &bcm_qspi_pm_ops,
+		.of_match_table = brcmstb_qspi_of_match,
+	}
+};
+module_platform_driver(brcmstb_qspi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("Broadcom SPI driver for settop SoC");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu,
	Yendapally Reddy Dhananjaya Reddy

This change implements BSPI driver for Broadcom BRCMSTB, NS2,
NSP SoCs works in combination with the MSPI controller driver
and implements flash read acceleration and provides the
spi_flash_read() method. Both MSPI and BSPI controllers are
needed to access spi-nor flash.

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
 drivers/spi/spi-bcm-qspi.c | 602 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h |  20 ++
 2 files changed, 622 insertions(+)

diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index fb26709..0c1a617 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -41,6 +41,57 @@
 #define BCM_QSPI_STATE_IDLE			0
 #define BCM_QSPI_STATE_RUNNING			1
 
+/* BSPI register offsets */
+#define BSPI_REVISION_ID			0x000
+#define BSPI_SCRATCH				0x004
+#define BSPI_MAST_N_BOOT_CTRL			0x008
+#define BSPI_BUSY_STATUS			0x00c
+#define BSPI_INTR_STATUS			0x010
+#define BSPI_B0_STATUS				0x014
+#define BSPI_B0_CTRL				0x018
+#define BSPI_B1_STATUS				0x01c
+#define BSPI_B1_CTRL				0x020
+#define BSPI_STRAP_OVERRIDE_CTRL		0x024
+#define BSPI_FLEX_MODE_ENABLE			0x028
+#define BSPI_BITS_PER_CYCLE			0x02c
+#define BSPI_BITS_PER_PHASE			0x030
+#define BSPI_CMD_AND_MODE_BYTE			0x034
+#define BSPI_BSPI_FLASH_UPPER_ADDR_BYTE	0x038
+#define BSPI_BSPI_XOR_VALUE			0x03c
+#define BSPI_BSPI_XOR_ENABLE			0x040
+#define BSPI_BSPI_PIO_MODE_ENABLE		0x044
+#define BSPI_BSPI_PIO_IODIR			0x048
+#define BSPI_BSPI_PIO_DATA			0x04c
+
+/* RAF register offsets */
+#define BSPI_RAF_START_ADDR			0x100
+#define BSPI_RAF_NUM_WORDS			0x104
+#define BSPI_RAF_CTRL				0x108
+#define BSPI_RAF_FULLNESS			0x10c
+#define BSPI_RAF_WATERMARK			0x110
+#define BSPI_RAF_STATUS			0x114
+#define BSPI_RAF_READ_DATA			0x118
+#define BSPI_RAF_WORD_CNT			0x11c
+#define BSPI_RAF_CURR_ADDR			0x120
+
+/* Override mode masks */
+#define BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE	BIT(0)
+#define BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL	BIT(1)
+#define BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE	BIT(2)
+#define BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD	BIT(3)
+#define BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE	BIT(4)
+
+#define BSPI_ADDRLEN_3BYTES			3
+#define BSPI_ADDRLEN_4BYTES			4
+
+#define BSPI_RAF_STATUS_FIFO_EMPTY_MASK	BIT(1)
+
+#define BSPI_RAF_CTRL_START_MASK		BIT(0)
+#define BSPI_RAF_CTRL_CLEAR_MASK		BIT(1)
+
+#define BSPI_BPP_MODE_SELECT_MASK		BIT(8)
+#define BSPI_BPP_ADDR_SELECT_MASK		BIT(16)
+
 /* MSPI register offsets */
 #define MSPI_SPCR0_LSB				0x000
 #define MSPI_SPCR0_MSB				0x004
@@ -119,8 +170,16 @@ static const struct bcm_qspi_parms bcm_qspi_default_parms_cs0 = {
 	.bits_per_word = 8,
 };
 
+struct bcm_xfer_mode {
+	bool flex_mode;
+	unsigned int width;
+	unsigned int addrlen;
+	unsigned int hp;
+};
+
 enum base_type {
 	MSPI,
+	BSPI,
 	CHIP_SELECT,
 	BASEMAX,
 };
@@ -154,13 +213,28 @@ struct bcm_qspi {
 	int next_udelay;
 	int cs_change;
 	int curr_cs;
+	int bspi_maj_rev;
+	int bspi_min_rev;
+	int bspi_enabled;
+	struct spi_flash_read_message *bspi_rf_msg;
+	u32 bspi_rf_msg_idx;
+	u32 bspi_rf_msg_len;
+	u32 bspi_rf_msg_status;
+	struct bcm_xfer_mode xfer_mode;
 	u32 s3_strap_override_ctrl;
+	bool bspi_mode;
 	bool big_endian;
 	int num_irqs;
 	struct bcm_qspi_dev_id *dev_ids;
 	struct completion mspi_done;
+	struct completion bspi_done;
 };
 
+static inline bool has_bspi(struct bcm_qspi *qspi)
+{
+	return qspi->bspi_mode;
+}
+
 /* Read qspi controller register*/
 static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type,
 				unsigned int offset)
@@ -175,6 +249,307 @@ static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type,
 	bcm_qspi_writel(qspi->pdev, data, qspi->base[type] + offset);
 }
 
+/* BSPI helpers */
+static int bcm_qspi_bspi_busy_poll(struct bcm_qspi *qspi)
+{
+	int i;
+
+	/* this should normally finish within 10us */
+	for (i = 0; i < 1000; i++) {
+		if (!(bcm_qspi_read(qspi, BSPI, BSPI_BUSY_STATUS) & 1))
+			return 0;
+		udelay(1);
+	}
+	dev_warn(&qspi->pdev->dev, "timeout waiting for !busy_status\n");
+	return -EIO;
+}
+
+static inline bool bcm_qspi_bspi_ver_three(struct bcm_qspi *qspi)
+{
+	if (qspi->bspi_maj_rev < 4)
+		return true;
+	return false;
+}
+
+static void bcm_qspi_bspi_flush_prefetch_buffers(struct bcm_qspi *qspi)
+{
+	bcm_qspi_bspi_busy_poll(qspi);
+	/* Force rising edge for the b0/b1 'flush' field */
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0);
+}
+
+static int bcm_qspi_bspi_lr_is_fifo_empty(struct bcm_qspi *qspi)
+{
+	return (bcm_qspi_read(qspi, BSPI, BSPI_RAF_STATUS) &
+				BSPI_RAF_STATUS_FIFO_EMPTY_MASK);
+}
+
+static inline u32 bcm_qspi_bspi_lr_read_fifo(struct bcm_qspi *qspi)
+{
+	u32 data = bcm_qspi_read(qspi, BSPI, BSPI_RAF_READ_DATA);
+
+	/* BSPI v3 LR is LE only, convert data to host endianness */
+	if (bcm_qspi_bspi_ver_three(qspi))
+		data = le32_to_cpu(data);
+
+	return data;
+}
+
+static inline void bcm_qspi_bspi_lr_start(struct bcm_qspi *qspi)
+{
+	bcm_qspi_bspi_busy_poll(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL,
+		       BSPI_RAF_CTRL_START_MASK);
+}
+
+static inline void bcm_qspi_bspi_lr_clear(struct bcm_qspi *qspi)
+{
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL,
+		       BSPI_RAF_CTRL_CLEAR_MASK);
+	bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+}
+
+static void bcm_qspi_bspi_lr_data_read(struct bcm_qspi *qspi)
+{
+	u32 *buf = (u32 *)qspi->bspi_rf_msg->buf;
+	u32 data = 0;
+
+	dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_msg,
+		qspi->bspi_rf_msg->buf, qspi->bspi_rf_msg_len);
+	while (!bcm_qspi_bspi_lr_is_fifo_empty(qspi)) {
+		data = bcm_qspi_bspi_lr_read_fifo(qspi);
+		if (likely(qspi->bspi_rf_msg_len >= 4) &&
+		    IS_ALIGNED((uintptr_t)buf, 4)) {
+			buf[qspi->bspi_rf_msg_idx++] = data;
+			qspi->bspi_rf_msg_len -= 4;
+		} else {
+			/* Read out remaining bytes, make sure*/
+			u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_msg_idx];
+
+			data = cpu_to_le32(data);
+			while (qspi->bspi_rf_msg_len) {
+				*cbuf++ = (u8)data;
+				data >>= 8;
+				qspi->bspi_rf_msg_len--;
+			}
+		}
+	}
+}
+
+static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte,
+					  int bpp, int bpc, int flex_mode)
+{
+	bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0);
+	bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_CYCLE, bpc);
+	bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_PHASE, bpp);
+	bcm_qspi_write(qspi, BSPI, BSPI_CMD_AND_MODE_BYTE, cmd_byte);
+	bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode);
+}
+
+static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, int width,
+				       int addrlen, int hp)
+{
+	int bpc = 0, bpp = 0;
+	u8 command = SPINOR_OP_READ_FAST;
+	int flex_mode = 1, rv = 0;
+	bool spans_4byte = false;
+
+	dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n",
+		width, addrlen, hp);
+
+	if (addrlen == BSPI_ADDRLEN_4BYTES) {
+		bpp = BSPI_BPP_ADDR_SELECT_MASK;
+		spans_4byte = true;
+	}
+
+	bpp |= 8;
+
+	switch (width) {
+	case SPI_NBITS_SINGLE:
+		if (addrlen == BSPI_ADDRLEN_3BYTES)
+			/* default mode, does not need flex_cmd */
+			flex_mode = 0;
+		else
+			command = SPINOR_OP_READ4_FAST;
+		break;
+	case SPI_NBITS_DUAL:
+		bpc = 0x00000001;
+		if (hp) {
+			bpc |= 0x00010100; /* address and mode are 2-bit */
+			bpp = BSPI_BPP_MODE_SELECT_MASK;
+			command = OPCODE_DIOR;
+			if (spans_4byte)
+				command = OPCODE_DIOR_4B;
+		} else {
+			command = SPINOR_OP_READ_1_1_2;
+			if (spans_4byte)
+				command = SPINOR_OP_READ4_1_1_2;
+		}
+		break;
+	case SPI_NBITS_QUAD:
+		bpc = 0x00000002;
+		if (hp) {
+			bpc |= 0x00020200; /* address and mode are 4-bit */
+			bpp = 4; /* dummy cycles */
+			bpp |= BSPI_BPP_ADDR_SELECT_MASK;
+			command = OPCODE_QIOR;
+			if (spans_4byte)
+				command = OPCODE_QIOR_4B;
+		} else {
+			command = SPINOR_OP_READ_1_1_4;
+			if (spans_4byte)
+				command = SPINOR_OP_READ4_1_1_4;
+		}
+		break;
+	default:
+		rv = -EINVAL;
+		break;
+	}
+
+	if (rv == 0)
+		bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc,
+					      flex_mode);
+
+	return rv;
+}
+
+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);
+
+	dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n",
+		width, addrlen, hp);
+
+	switch (width) {
+	case SPI_NBITS_SINGLE:
+		/* clear quad/dual mode */
+		data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD |
+			  BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL);
+		break;
+
+	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;
+		data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (addrlen == BSPI_ADDRLEN_4BYTES)
+		/* set 4byte mode*/
+		data |= BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE;
+	else
+		/* clear 4 byte mode */
+		data &= ~BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE;
+
+	/* set the override mode */
+	data |=	BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
+	bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data);
+	bcm_qspi_bspi_set_xfer_params(qspi, SPINOR_OP_READ_FAST, 0, 0, 0);
+
+	return 0;
+}
+
+static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
+				  int width, int addrlen, int hp)
+{
+	int error = 0;
+
+	if (width == -1)
+		width = qspi->xfer_mode.width;
+	if (addrlen == -1)
+		addrlen = qspi->xfer_mode.addrlen;
+	if (hp == -1)
+		hp = qspi->xfer_mode.hp;
+
+	/* default mode */
+	qspi->xfer_mode.flex_mode = true;
+
+	if (!bcm_qspi_bspi_ver_three(qspi)) {
+		u32 val, mask;
+
+		val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
+		mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
+		if (val & mask || qspi->s3_strap_override_ctrl & mask) {
+			qspi->xfer_mode.flex_mode = false;
+			bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE,
+				       0);
+
+			if ((val | qspi->s3_strap_override_ctrl) &
+			    BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL)
+				width = SPI_NBITS_DUAL;
+			else if ((val |  qspi->s3_strap_override_ctrl) &
+				 BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD)
+				width = SPI_NBITS_QUAD;
+
+			error = bcm_qspi_bspi_set_override(qspi, width, addrlen,
+							   hp);
+		}
+	}
+
+	if (qspi->xfer_mode.flex_mode)
+		error = bcm_qspi_bspi_set_flex_mode(qspi, width, addrlen, hp);
+
+	if (error) {
+		dev_warn(&qspi->pdev->dev,
+			 "INVALID COMBINATION: width=%d addrlen=%d hp=%d\n",
+			 width, addrlen, hp);
+	} else if (qspi->xfer_mode.width != width ||
+		   qspi->xfer_mode.addrlen != addrlen ||
+		   qspi->xfer_mode.hp != hp) {
+		qspi->xfer_mode.width = width;
+		qspi->xfer_mode.addrlen = addrlen;
+		qspi->xfer_mode.hp = hp;
+		dev_dbg(&qspi->pdev->dev,
+			"cs:%d %d-lane output, %d-byte address%s\n",
+			qspi->curr_cs,
+			qspi->xfer_mode.width,
+			qspi->xfer_mode.addrlen,
+			qspi->xfer_mode.hp != -1 ? ", hp mode" : "");
+	}
+
+	return error;
+}
+
+static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi)
+{
+	if (!has_bspi(qspi) || (qspi->bspi_enabled))
+		return;
+
+	qspi->bspi_enabled = 1;
+	if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1) == 0)
+		return;
+
+	bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+	udelay(1);
+	bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 0);
+	udelay(1);
+}
+
+static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi)
+{
+	if (!has_bspi(qspi) || (!qspi->bspi_enabled))
+		return;
+
+	qspi->bspi_enabled = 0;
+	if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1))
+		return;
+
+	bcm_qspi_bspi_busy_poll(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 1);
+	udelay(1);
+}
+
 static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs)
 {
 	u32 data = 0;
@@ -312,6 +687,8 @@ static void read_from_hw(struct bcm_qspi *qspi, int slots)
 	struct qspi_trans tp;
 	int slot;
 
+	bcm_qspi_disable_bspi(qspi);
+
 	if (slots > MSPI_NUM_CDRAM) {
 		/* should never happen */
 		dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__);
@@ -382,6 +759,7 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
 	int slot = 0, tstatus = 0;
 	u32 mspi_cdram = 0;
 
+	bcm_qspi_disable_bspi(qspi);
 	tp = qspi->trans_pos;
 	bcm_qspi_update_parms(qspi, spi, tp.trans);
 
@@ -433,6 +811,9 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
 		write_cdram_slot(qspi, slot - 1, mspi_cdram);
 	}
 
+	if (has_bspi(qspi))
+		bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 1);
+
 	/* Must flush previous writes before starting MSPI operation */
 	mb();
 	/* Set cont | spe | spifie */
@@ -445,9 +826,126 @@ done:
 
 static void hw_stop(struct bcm_qspi *qspi)
 {
+	if (has_bspi(qspi))
+		bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
 	qspi->state = BCM_QSPI_STATE_IDLE;
 }
 
+static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
+				    struct spi_flash_read_message *msg)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
+	u32 addr = 0, len, len_words;
+	u8 *buf;
+	int ret = 0;
+	int retry = 3;
+	unsigned long timeo = msecs_to_jiffies(100);
+
+	if (bcm_qspi_bspi_ver_three(qspi))
+		if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
+			return -EIO;
+
+	bcm_qspi_chip_select(qspi, spi->chip_select);
+
+	/*
+	 * when using flex mode mode we need to send
+	 * the upper address byte to bspi
+	 */
+	if (bcm_qspi_bspi_ver_three(qspi) == false) {
+		addr = msg->from & 0xff000000;
+		bcm_qspi_write(qspi, BSPI,
+			       BSPI_BSPI_FLASH_UPPER_ADDR_BYTE, addr);
+	}
+
+	if (!qspi->xfer_mode.flex_mode)
+		addr = msg->from;
+	else
+		addr = msg->from & 0x00ffffff;
+
+	/* read result into buffer */
+	buf = msg->buf;
+	len = msg->len;
+
+	if (bcm_qspi_bspi_ver_three(qspi) == true)
+		addr = (addr + 0xc00000) & 0xffffff;
+
+retry:
+	reinit_completion(&qspi->bspi_done);
+	bcm_qspi_enable_bspi(qspi);
+	len_words = (len + 3) >> 2;
+	qspi->bspi_rf_msg = msg;
+	qspi->bspi_rf_msg_status = 0;
+	qspi->bspi_rf_msg_idx = 0;
+	qspi->bspi_rf_msg_len = len;
+	dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len);
+
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
+
+	bcm_qspi_bspi_lr_start(qspi);
+	/* Must flush previous writes before starting BSPI operation */
+	mb();
+	if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
+		if (retry--)
+			goto retry;
+
+		dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n");
+		ret = -ETIMEDOUT;
+	} else {
+		/* set the return length for the caller */
+		msg->retlen = len;
+	}
+
+	return ret;
+}
+
+static int bcm_qspi_flash_read(struct spi_device *spi,
+			       struct spi_flash_read_message *msg)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
+	int ret = 0;
+	bool mspi_read = false;
+	u32 io_width, addrlen, addr, len;
+	u_char *buf;
+
+	buf = msg->buf;
+	addr = msg->from;
+	len = msg->len;
+
+	if (bcm_qspi_bspi_ver_three(qspi) == true) {
+		/*
+		 * The address coming into this function is a raw flash offset.
+		 * But for BSPI <= V3, we need to convert it to a remapped BSPI
+		 * address. If it crosses a 4MB boundary, just revert back to
+		 * using MSPI.
+		 */
+		addr = (addr + 0xc00000) & 0xffffff;
+
+		if ((~ADDR_4MB_MASK & addr) ^
+		    (~ADDR_4MB_MASK & (addr + len - 1)))
+			mspi_read = true;
+	}
+
+	/* non-aligned and very short transfers are handled by MSPI */
+	if (!IS_ALIGNED((uintptr_t)addr, 4) || !IS_ALIGNED((uintptr_t)buf, 4) ||
+	    len < 4)
+		mspi_read = true;
+
+	if (mspi_read)
+		/* this will make the m25p80 read to fallback to mspi read */
+		return -EAGAIN;
+
+	io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
+	addrlen = msg->addr_width;
+	ret = bcm_qspi_bspi_set_mode(qspi, io_width, addrlen, -1);
+
+	if (!ret)
+		ret = bcm_qspi_bspi_flash_read(spi, msg);
+
+	return ret;
+}
+
 static int bcm_qspi_transfer_one(struct spi_master *master,
 				 struct spi_device *spi,
 				 struct spi_transfer *trans)
@@ -511,8 +1009,70 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
 	}
 }
 
+static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+
+	if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
+		bcm_qspi_bspi_lr_data_read(qspi);
+		if (qspi->bspi_rf_msg_len == 0) {
+			qspi->bspi_rf_msg = NULL;
+			if (qspi->bspi_rf_msg_status)
+				bcm_qspi_bspi_lr_clear(qspi);
+			else
+				bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+
+			complete(&qspi->bspi_done);
+		}
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+
+	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
+		qspi_dev_id->irqp->mask);
+	qspi->bspi_rf_msg_status = -EIO;
+	complete(&qspi->bspi_done);
+	return IRQ_HANDLED;
+}
+
 static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	{
+		.irq_name = "spi_lr_fullness_reached",
+		.irq_handler = bcm_qspi_bspi_lr_l2_isr,
+		.mask = INTR_BSPI_LR_FULLNESS_REACHED_MASK,
+	},
+	{
+		.irq_name = "spi_lr_session_aborted",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_SESSION_ABORTED_MASK,
+	},
+	{
+		.irq_name = "spi_lr_impatient",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_IMPATIENT_MASK,
+	},
+	{
+		.irq_name = "spi_lr_session_done",
+		.irq_handler = bcm_qspi_bspi_lr_l2_isr,
+		.mask = INTR_BSPI_LR_SESSION_DONE_MASK,
+	},
+#ifdef  QSPI_INT_DEBUG
+	/* this interrupt is for debug purposes only, dont request irq */
+	{
+		.irq_name = "spi_lr_overread",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_OVERREAD_MASK,
+	},
+#endif
+	{
 		.irq_name = "mspi_done",
 		.irq_handler = bcm_qspi_mspi_l2_isr,
 		.mask = INTR_MSPI_DONE_MASK,
@@ -524,6 +1084,24 @@ static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	},
 };
 
+static void bcm_qspi_bspi_init(struct bcm_qspi *qspi)
+{
+	u32 val = 0;
+
+	val = bcm_qspi_read(qspi, BSPI, BSPI_REVISION_ID);
+	qspi->bspi_maj_rev = (val >> 8) & 0xff;
+	qspi->bspi_min_rev = val & 0xff;
+	if (!(bcm_qspi_bspi_ver_three(qspi))) {
+		/* Force mapping of BSPI address -> flash offset */
+		bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_VALUE, 0);
+		bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_ENABLE, 1);
+	}
+	qspi->bspi_enabled = 1;
+	bcm_qspi_disable_bspi(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1);
+}
+
 static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
 {
 	u32 val = 0;
@@ -545,6 +1123,8 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
 		bcm_qspi_hw_set_parms(qspi, &bcm_qspi_default_parms_cs0);
 	}
 
+	if (has_bspi(qspi))
+		bcm_qspi_bspi_init(qspi);
 }
 
 static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
@@ -593,6 +1173,7 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD;
 	master->setup = bcm_qspi_setup;
 	master->transfer_one = bcm_qspi_transfer_one;
+	master->spi_flash_read = bcm_qspi_flash_read;
 	master->cleanup = bcm_qspi_cleanup;
 	master->dev.of_node = dev->of_node;
 	master->num_chipselect = NUM_CHIPSELECT;
@@ -617,6 +1198,20 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 		goto err2;
 	}
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
+	if (res) {
+		qspi->base[BSPI]  = devm_ioremap_resource(dev, res);
+		if (IS_ERR(qspi->base[BSPI])) {
+			ret = PTR_ERR(qspi->base[BSPI]);
+			goto err2;
+		}
+		qspi->bspi_mode = true;
+	} else {
+		qspi->bspi_mode = false;
+	}
+
+	dev_info(dev, "using %smspi mode\n", qspi->bspi_mode ? "bspi-" : "");
+
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg");
 	if (res) {
 		qspi->base[CHIP_SELECT]  = devm_ioremap_resource(dev, res);
@@ -679,9 +1274,15 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 
 	bcm_qspi_hw_init(qspi);
 	init_completion(&qspi->mspi_done);
+	init_completion(&qspi->bspi_done);
 	qspi->curr_cs = -1;
 
 	platform_set_drvdata(pdev, qspi);
+
+	qspi->xfer_mode.width = -1;
+	qspi->xfer_mode.addrlen = -1;
+	qspi->xfer_mode.hp = -1;
+
 	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 		dev_err(dev, "can't register master\n");
@@ -730,6 +1331,7 @@ static int bcm_qspi_resume(struct device *dev)
 	int ret = 0;
 
 	bcm_qspi_hw_init(qspi);
+	bcm_qspi_bspi_set_mode(qspi, -1, -1, -1);
 	qspi->curr_cs = -1;
 	bcm_qspi_chip_select(qspi, curr_cs);
 
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
index 0bdddd4..e0a354a 100644
--- a/drivers/spi/spi-bcm-qspi.h
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -20,6 +20,26 @@
 #include <linux/types.h>
 #include <linux/io.h>
 
+/* BSPI interrupt masks */
+#define INTR_BSPI_LR_OVERREAD_MASK		BIT(4)
+#define INTR_BSPI_LR_SESSION_DONE_MASK		BIT(3)
+#define INTR_BSPI_LR_IMPATIENT_MASK		BIT(2)
+#define INTR_BSPI_LR_SESSION_ABORTED_MASK	BIT(1)
+#define INTR_BSPI_LR_FULLNESS_REACHED_MASK	BIT(0)
+
+#define BSPI_LR_INTERRUPTS_DATA		       \
+	(INTR_BSPI_LR_SESSION_DONE_MASK |	       \
+	 INTR_BSPI_LR_FULLNESS_REACHED_MASK)
+
+#define BSPI_LR_INTERRUPTS_ERROR               \
+	(INTR_BSPI_LR_OVERREAD_MASK |	       \
+	 INTR_BSPI_LR_IMPATIENT_MASK |	       \
+	 INTR_BSPI_LR_SESSION_ABORTED_MASK)
+
+#define BSPI_LR_INTERRUPTS_ALL                 \
+	(BSPI_LR_INTERRUPTS_ERROR |	       \
+	 BSPI_LR_INTERRUPTS_DATA)
+
 /* MSPI Interrupt masks */
 #define INTR_MSPI_HALTED_MASK			BIT(6)
 #define INTR_MSPI_DONE_MASK			BIT(5)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu, Yendapally Reddy Dhananjaya Reddy

This change implements BSPI driver for Broadcom BRCMSTB, NS2,
NSP SoCs works in combination with the MSPI controller driver
and implements flash read acceleration and provides the
spi_flash_read() method. Both MSPI and BSPI controllers are
needed to access spi-nor flash.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
---
 drivers/spi/spi-bcm-qspi.c | 602 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/spi/spi-bcm-qspi.h |  20 ++
 2 files changed, 622 insertions(+)

diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index fb26709..0c1a617 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -41,6 +41,57 @@
 #define BCM_QSPI_STATE_IDLE			0
 #define BCM_QSPI_STATE_RUNNING			1
 
+/* BSPI register offsets */
+#define BSPI_REVISION_ID			0x000
+#define BSPI_SCRATCH				0x004
+#define BSPI_MAST_N_BOOT_CTRL			0x008
+#define BSPI_BUSY_STATUS			0x00c
+#define BSPI_INTR_STATUS			0x010
+#define BSPI_B0_STATUS				0x014
+#define BSPI_B0_CTRL				0x018
+#define BSPI_B1_STATUS				0x01c
+#define BSPI_B1_CTRL				0x020
+#define BSPI_STRAP_OVERRIDE_CTRL		0x024
+#define BSPI_FLEX_MODE_ENABLE			0x028
+#define BSPI_BITS_PER_CYCLE			0x02c
+#define BSPI_BITS_PER_PHASE			0x030
+#define BSPI_CMD_AND_MODE_BYTE			0x034
+#define BSPI_BSPI_FLASH_UPPER_ADDR_BYTE	0x038
+#define BSPI_BSPI_XOR_VALUE			0x03c
+#define BSPI_BSPI_XOR_ENABLE			0x040
+#define BSPI_BSPI_PIO_MODE_ENABLE		0x044
+#define BSPI_BSPI_PIO_IODIR			0x048
+#define BSPI_BSPI_PIO_DATA			0x04c
+
+/* RAF register offsets */
+#define BSPI_RAF_START_ADDR			0x100
+#define BSPI_RAF_NUM_WORDS			0x104
+#define BSPI_RAF_CTRL				0x108
+#define BSPI_RAF_FULLNESS			0x10c
+#define BSPI_RAF_WATERMARK			0x110
+#define BSPI_RAF_STATUS			0x114
+#define BSPI_RAF_READ_DATA			0x118
+#define BSPI_RAF_WORD_CNT			0x11c
+#define BSPI_RAF_CURR_ADDR			0x120
+
+/* Override mode masks */
+#define BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE	BIT(0)
+#define BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL	BIT(1)
+#define BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE	BIT(2)
+#define BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD	BIT(3)
+#define BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE	BIT(4)
+
+#define BSPI_ADDRLEN_3BYTES			3
+#define BSPI_ADDRLEN_4BYTES			4
+
+#define BSPI_RAF_STATUS_FIFO_EMPTY_MASK	BIT(1)
+
+#define BSPI_RAF_CTRL_START_MASK		BIT(0)
+#define BSPI_RAF_CTRL_CLEAR_MASK		BIT(1)
+
+#define BSPI_BPP_MODE_SELECT_MASK		BIT(8)
+#define BSPI_BPP_ADDR_SELECT_MASK		BIT(16)
+
 /* MSPI register offsets */
 #define MSPI_SPCR0_LSB				0x000
 #define MSPI_SPCR0_MSB				0x004
@@ -119,8 +170,16 @@ static const struct bcm_qspi_parms bcm_qspi_default_parms_cs0 = {
 	.bits_per_word = 8,
 };
 
+struct bcm_xfer_mode {
+	bool flex_mode;
+	unsigned int width;
+	unsigned int addrlen;
+	unsigned int hp;
+};
+
 enum base_type {
 	MSPI,
+	BSPI,
 	CHIP_SELECT,
 	BASEMAX,
 };
@@ -154,13 +213,28 @@ struct bcm_qspi {
 	int next_udelay;
 	int cs_change;
 	int curr_cs;
+	int bspi_maj_rev;
+	int bspi_min_rev;
+	int bspi_enabled;
+	struct spi_flash_read_message *bspi_rf_msg;
+	u32 bspi_rf_msg_idx;
+	u32 bspi_rf_msg_len;
+	u32 bspi_rf_msg_status;
+	struct bcm_xfer_mode xfer_mode;
 	u32 s3_strap_override_ctrl;
+	bool bspi_mode;
 	bool big_endian;
 	int num_irqs;
 	struct bcm_qspi_dev_id *dev_ids;
 	struct completion mspi_done;
+	struct completion bspi_done;
 };
 
+static inline bool has_bspi(struct bcm_qspi *qspi)
+{
+	return qspi->bspi_mode;
+}
+
 /* Read qspi controller register*/
 static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type,
 				unsigned int offset)
@@ -175,6 +249,307 @@ static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type,
 	bcm_qspi_writel(qspi->pdev, data, qspi->base[type] + offset);
 }
 
+/* BSPI helpers */
+static int bcm_qspi_bspi_busy_poll(struct bcm_qspi *qspi)
+{
+	int i;
+
+	/* this should normally finish within 10us */
+	for (i = 0; i < 1000; i++) {
+		if (!(bcm_qspi_read(qspi, BSPI, BSPI_BUSY_STATUS) & 1))
+			return 0;
+		udelay(1);
+	}
+	dev_warn(&qspi->pdev->dev, "timeout waiting for !busy_status\n");
+	return -EIO;
+}
+
+static inline bool bcm_qspi_bspi_ver_three(struct bcm_qspi *qspi)
+{
+	if (qspi->bspi_maj_rev < 4)
+		return true;
+	return false;
+}
+
+static void bcm_qspi_bspi_flush_prefetch_buffers(struct bcm_qspi *qspi)
+{
+	bcm_qspi_bspi_busy_poll(qspi);
+	/* Force rising edge for the b0/b1 'flush' field */
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0);
+}
+
+static int bcm_qspi_bspi_lr_is_fifo_empty(struct bcm_qspi *qspi)
+{
+	return (bcm_qspi_read(qspi, BSPI, BSPI_RAF_STATUS) &
+				BSPI_RAF_STATUS_FIFO_EMPTY_MASK);
+}
+
+static inline u32 bcm_qspi_bspi_lr_read_fifo(struct bcm_qspi *qspi)
+{
+	u32 data = bcm_qspi_read(qspi, BSPI, BSPI_RAF_READ_DATA);
+
+	/* BSPI v3 LR is LE only, convert data to host endianness */
+	if (bcm_qspi_bspi_ver_three(qspi))
+		data = le32_to_cpu(data);
+
+	return data;
+}
+
+static inline void bcm_qspi_bspi_lr_start(struct bcm_qspi *qspi)
+{
+	bcm_qspi_bspi_busy_poll(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL,
+		       BSPI_RAF_CTRL_START_MASK);
+}
+
+static inline void bcm_qspi_bspi_lr_clear(struct bcm_qspi *qspi)
+{
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL,
+		       BSPI_RAF_CTRL_CLEAR_MASK);
+	bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+}
+
+static void bcm_qspi_bspi_lr_data_read(struct bcm_qspi *qspi)
+{
+	u32 *buf = (u32 *)qspi->bspi_rf_msg->buf;
+	u32 data = 0;
+
+	dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_msg,
+		qspi->bspi_rf_msg->buf, qspi->bspi_rf_msg_len);
+	while (!bcm_qspi_bspi_lr_is_fifo_empty(qspi)) {
+		data = bcm_qspi_bspi_lr_read_fifo(qspi);
+		if (likely(qspi->bspi_rf_msg_len >= 4) &&
+		    IS_ALIGNED((uintptr_t)buf, 4)) {
+			buf[qspi->bspi_rf_msg_idx++] = data;
+			qspi->bspi_rf_msg_len -= 4;
+		} else {
+			/* Read out remaining bytes, make sure*/
+			u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_msg_idx];
+
+			data = cpu_to_le32(data);
+			while (qspi->bspi_rf_msg_len) {
+				*cbuf++ = (u8)data;
+				data >>= 8;
+				qspi->bspi_rf_msg_len--;
+			}
+		}
+	}
+}
+
+static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte,
+					  int bpp, int bpc, int flex_mode)
+{
+	bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0);
+	bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_CYCLE, bpc);
+	bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_PHASE, bpp);
+	bcm_qspi_write(qspi, BSPI, BSPI_CMD_AND_MODE_BYTE, cmd_byte);
+	bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode);
+}
+
+static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, int width,
+				       int addrlen, int hp)
+{
+	int bpc = 0, bpp = 0;
+	u8 command = SPINOR_OP_READ_FAST;
+	int flex_mode = 1, rv = 0;
+	bool spans_4byte = false;
+
+	dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n",
+		width, addrlen, hp);
+
+	if (addrlen == BSPI_ADDRLEN_4BYTES) {
+		bpp = BSPI_BPP_ADDR_SELECT_MASK;
+		spans_4byte = true;
+	}
+
+	bpp |= 8;
+
+	switch (width) {
+	case SPI_NBITS_SINGLE:
+		if (addrlen == BSPI_ADDRLEN_3BYTES)
+			/* default mode, does not need flex_cmd */
+			flex_mode = 0;
+		else
+			command = SPINOR_OP_READ4_FAST;
+		break;
+	case SPI_NBITS_DUAL:
+		bpc = 0x00000001;
+		if (hp) {
+			bpc |= 0x00010100; /* address and mode are 2-bit */
+			bpp = BSPI_BPP_MODE_SELECT_MASK;
+			command = OPCODE_DIOR;
+			if (spans_4byte)
+				command = OPCODE_DIOR_4B;
+		} else {
+			command = SPINOR_OP_READ_1_1_2;
+			if (spans_4byte)
+				command = SPINOR_OP_READ4_1_1_2;
+		}
+		break;
+	case SPI_NBITS_QUAD:
+		bpc = 0x00000002;
+		if (hp) {
+			bpc |= 0x00020200; /* address and mode are 4-bit */
+			bpp = 4; /* dummy cycles */
+			bpp |= BSPI_BPP_ADDR_SELECT_MASK;
+			command = OPCODE_QIOR;
+			if (spans_4byte)
+				command = OPCODE_QIOR_4B;
+		} else {
+			command = SPINOR_OP_READ_1_1_4;
+			if (spans_4byte)
+				command = SPINOR_OP_READ4_1_1_4;
+		}
+		break;
+	default:
+		rv = -EINVAL;
+		break;
+	}
+
+	if (rv == 0)
+		bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc,
+					      flex_mode);
+
+	return rv;
+}
+
+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);
+
+	dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n",
+		width, addrlen, hp);
+
+	switch (width) {
+	case SPI_NBITS_SINGLE:
+		/* clear quad/dual mode */
+		data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD |
+			  BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL);
+		break;
+
+	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;
+		data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (addrlen == BSPI_ADDRLEN_4BYTES)
+		/* set 4byte mode*/
+		data |= BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE;
+	else
+		/* clear 4 byte mode */
+		data &= ~BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE;
+
+	/* set the override mode */
+	data |=	BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
+	bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data);
+	bcm_qspi_bspi_set_xfer_params(qspi, SPINOR_OP_READ_FAST, 0, 0, 0);
+
+	return 0;
+}
+
+static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi,
+				  int width, int addrlen, int hp)
+{
+	int error = 0;
+
+	if (width == -1)
+		width = qspi->xfer_mode.width;
+	if (addrlen == -1)
+		addrlen = qspi->xfer_mode.addrlen;
+	if (hp == -1)
+		hp = qspi->xfer_mode.hp;
+
+	/* default mode */
+	qspi->xfer_mode.flex_mode = true;
+
+	if (!bcm_qspi_bspi_ver_three(qspi)) {
+		u32 val, mask;
+
+		val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
+		mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE;
+		if (val & mask || qspi->s3_strap_override_ctrl & mask) {
+			qspi->xfer_mode.flex_mode = false;
+			bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE,
+				       0);
+
+			if ((val | qspi->s3_strap_override_ctrl) &
+			    BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL)
+				width = SPI_NBITS_DUAL;
+			else if ((val |  qspi->s3_strap_override_ctrl) &
+				 BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD)
+				width = SPI_NBITS_QUAD;
+
+			error = bcm_qspi_bspi_set_override(qspi, width, addrlen,
+							   hp);
+		}
+	}
+
+	if (qspi->xfer_mode.flex_mode)
+		error = bcm_qspi_bspi_set_flex_mode(qspi, width, addrlen, hp);
+
+	if (error) {
+		dev_warn(&qspi->pdev->dev,
+			 "INVALID COMBINATION: width=%d addrlen=%d hp=%d\n",
+			 width, addrlen, hp);
+	} else if (qspi->xfer_mode.width != width ||
+		   qspi->xfer_mode.addrlen != addrlen ||
+		   qspi->xfer_mode.hp != hp) {
+		qspi->xfer_mode.width = width;
+		qspi->xfer_mode.addrlen = addrlen;
+		qspi->xfer_mode.hp = hp;
+		dev_dbg(&qspi->pdev->dev,
+			"cs:%d %d-lane output, %d-byte address%s\n",
+			qspi->curr_cs,
+			qspi->xfer_mode.width,
+			qspi->xfer_mode.addrlen,
+			qspi->xfer_mode.hp != -1 ? ", hp mode" : "");
+	}
+
+	return error;
+}
+
+static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi)
+{
+	if (!has_bspi(qspi) || (qspi->bspi_enabled))
+		return;
+
+	qspi->bspi_enabled = 1;
+	if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1) == 0)
+		return;
+
+	bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+	udelay(1);
+	bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 0);
+	udelay(1);
+}
+
+static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi)
+{
+	if (!has_bspi(qspi) || (!qspi->bspi_enabled))
+		return;
+
+	qspi->bspi_enabled = 0;
+	if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1))
+		return;
+
+	bcm_qspi_bspi_busy_poll(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 1);
+	udelay(1);
+}
+
 static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs)
 {
 	u32 data = 0;
@@ -312,6 +687,8 @@ static void read_from_hw(struct bcm_qspi *qspi, int slots)
 	struct qspi_trans tp;
 	int slot;
 
+	bcm_qspi_disable_bspi(qspi);
+
 	if (slots > MSPI_NUM_CDRAM) {
 		/* should never happen */
 		dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__);
@@ -382,6 +759,7 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
 	int slot = 0, tstatus = 0;
 	u32 mspi_cdram = 0;
 
+	bcm_qspi_disable_bspi(qspi);
 	tp = qspi->trans_pos;
 	bcm_qspi_update_parms(qspi, spi, tp.trans);
 
@@ -433,6 +811,9 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
 		write_cdram_slot(qspi, slot - 1, mspi_cdram);
 	}
 
+	if (has_bspi(qspi))
+		bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 1);
+
 	/* Must flush previous writes before starting MSPI operation */
 	mb();
 	/* Set cont | spe | spifie */
@@ -445,9 +826,126 @@ done:
 
 static void hw_stop(struct bcm_qspi *qspi)
 {
+	if (has_bspi(qspi))
+		bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
 	qspi->state = BCM_QSPI_STATE_IDLE;
 }
 
+static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
+				    struct spi_flash_read_message *msg)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
+	u32 addr = 0, len, len_words;
+	u8 *buf;
+	int ret = 0;
+	int retry = 3;
+	unsigned long timeo = msecs_to_jiffies(100);
+
+	if (bcm_qspi_bspi_ver_three(qspi))
+		if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
+			return -EIO;
+
+	bcm_qspi_chip_select(qspi, spi->chip_select);
+
+	/*
+	 * when using flex mode mode we need to send
+	 * the upper address byte to bspi
+	 */
+	if (bcm_qspi_bspi_ver_three(qspi) == false) {
+		addr = msg->from & 0xff000000;
+		bcm_qspi_write(qspi, BSPI,
+			       BSPI_BSPI_FLASH_UPPER_ADDR_BYTE, addr);
+	}
+
+	if (!qspi->xfer_mode.flex_mode)
+		addr = msg->from;
+	else
+		addr = msg->from & 0x00ffffff;
+
+	/* read result into buffer */
+	buf = msg->buf;
+	len = msg->len;
+
+	if (bcm_qspi_bspi_ver_three(qspi) == true)
+		addr = (addr + 0xc00000) & 0xffffff;
+
+retry:
+	reinit_completion(&qspi->bspi_done);
+	bcm_qspi_enable_bspi(qspi);
+	len_words = (len + 3) >> 2;
+	qspi->bspi_rf_msg = msg;
+	qspi->bspi_rf_msg_status = 0;
+	qspi->bspi_rf_msg_idx = 0;
+	qspi->bspi_rf_msg_len = len;
+	dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len);
+
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
+	bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
+
+	bcm_qspi_bspi_lr_start(qspi);
+	/* Must flush previous writes before starting BSPI operation */
+	mb();
+	if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
+		if (retry--)
+			goto retry;
+
+		dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n");
+		ret = -ETIMEDOUT;
+	} else {
+		/* set the return length for the caller */
+		msg->retlen = len;
+	}
+
+	return ret;
+}
+
+static int bcm_qspi_flash_read(struct spi_device *spi,
+			       struct spi_flash_read_message *msg)
+{
+	struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
+	int ret = 0;
+	bool mspi_read = false;
+	u32 io_width, addrlen, addr, len;
+	u_char *buf;
+
+	buf = msg->buf;
+	addr = msg->from;
+	len = msg->len;
+
+	if (bcm_qspi_bspi_ver_three(qspi) == true) {
+		/*
+		 * The address coming into this function is a raw flash offset.
+		 * But for BSPI <= V3, we need to convert it to a remapped BSPI
+		 * address. If it crosses a 4MB boundary, just revert back to
+		 * using MSPI.
+		 */
+		addr = (addr + 0xc00000) & 0xffffff;
+
+		if ((~ADDR_4MB_MASK & addr) ^
+		    (~ADDR_4MB_MASK & (addr + len - 1)))
+			mspi_read = true;
+	}
+
+	/* non-aligned and very short transfers are handled by MSPI */
+	if (!IS_ALIGNED((uintptr_t)addr, 4) || !IS_ALIGNED((uintptr_t)buf, 4) ||
+	    len < 4)
+		mspi_read = true;
+
+	if (mspi_read)
+		/* this will make the m25p80 read to fallback to mspi read */
+		return -EAGAIN;
+
+	io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
+	addrlen = msg->addr_width;
+	ret = bcm_qspi_bspi_set_mode(qspi, io_width, addrlen, -1);
+
+	if (!ret)
+		ret = bcm_qspi_bspi_flash_read(spi, msg);
+
+	return ret;
+}
+
 static int bcm_qspi_transfer_one(struct spi_master *master,
 				 struct spi_device *spi,
 				 struct spi_transfer *trans)
@@ -511,8 +1009,70 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
 	}
 }
 
+static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+
+	if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
+		bcm_qspi_bspi_lr_data_read(qspi);
+		if (qspi->bspi_rf_msg_len == 0) {
+			qspi->bspi_rf_msg = NULL;
+			if (qspi->bspi_rf_msg_status)
+				bcm_qspi_bspi_lr_clear(qspi);
+			else
+				bcm_qspi_bspi_flush_prefetch_buffers(qspi);
+
+			complete(&qspi->bspi_done);
+		}
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+
+	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
+		qspi_dev_id->irqp->mask);
+	qspi->bspi_rf_msg_status = -EIO;
+	complete(&qspi->bspi_done);
+	return IRQ_HANDLED;
+}
+
 static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	{
+		.irq_name = "spi_lr_fullness_reached",
+		.irq_handler = bcm_qspi_bspi_lr_l2_isr,
+		.mask = INTR_BSPI_LR_FULLNESS_REACHED_MASK,
+	},
+	{
+		.irq_name = "spi_lr_session_aborted",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_SESSION_ABORTED_MASK,
+	},
+	{
+		.irq_name = "spi_lr_impatient",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_IMPATIENT_MASK,
+	},
+	{
+		.irq_name = "spi_lr_session_done",
+		.irq_handler = bcm_qspi_bspi_lr_l2_isr,
+		.mask = INTR_BSPI_LR_SESSION_DONE_MASK,
+	},
+#ifdef  QSPI_INT_DEBUG
+	/* this interrupt is for debug purposes only, dont request irq */
+	{
+		.irq_name = "spi_lr_overread",
+		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
+		.mask = INTR_BSPI_LR_OVERREAD_MASK,
+	},
+#endif
+	{
 		.irq_name = "mspi_done",
 		.irq_handler = bcm_qspi_mspi_l2_isr,
 		.mask = INTR_MSPI_DONE_MASK,
@@ -524,6 +1084,24 @@ static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	},
 };
 
+static void bcm_qspi_bspi_init(struct bcm_qspi *qspi)
+{
+	u32 val = 0;
+
+	val = bcm_qspi_read(qspi, BSPI, BSPI_REVISION_ID);
+	qspi->bspi_maj_rev = (val >> 8) & 0xff;
+	qspi->bspi_min_rev = val & 0xff;
+	if (!(bcm_qspi_bspi_ver_three(qspi))) {
+		/* Force mapping of BSPI address -> flash offset */
+		bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_VALUE, 0);
+		bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_ENABLE, 1);
+	}
+	qspi->bspi_enabled = 1;
+	bcm_qspi_disable_bspi(qspi);
+	bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1);
+	bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1);
+}
+
 static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
 {
 	u32 val = 0;
@@ -545,6 +1123,8 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
 		bcm_qspi_hw_set_parms(qspi, &bcm_qspi_default_parms_cs0);
 	}
 
+	if (has_bspi(qspi))
+		bcm_qspi_bspi_init(qspi);
 }
 
 static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
@@ -593,6 +1173,7 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD;
 	master->setup = bcm_qspi_setup;
 	master->transfer_one = bcm_qspi_transfer_one;
+	master->spi_flash_read = bcm_qspi_flash_read;
 	master->cleanup = bcm_qspi_cleanup;
 	master->dev.of_node = dev->of_node;
 	master->num_chipselect = NUM_CHIPSELECT;
@@ -617,6 +1198,20 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 		goto err2;
 	}
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi");
+	if (res) {
+		qspi->base[BSPI]  = devm_ioremap_resource(dev, res);
+		if (IS_ERR(qspi->base[BSPI])) {
+			ret = PTR_ERR(qspi->base[BSPI]);
+			goto err2;
+		}
+		qspi->bspi_mode = true;
+	} else {
+		qspi->bspi_mode = false;
+	}
+
+	dev_info(dev, "using %smspi mode\n", qspi->bspi_mode ? "bspi-" : "");
+
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg");
 	if (res) {
 		qspi->base[CHIP_SELECT]  = devm_ioremap_resource(dev, res);
@@ -679,9 +1274,15 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 
 	bcm_qspi_hw_init(qspi);
 	init_completion(&qspi->mspi_done);
+	init_completion(&qspi->bspi_done);
 	qspi->curr_cs = -1;
 
 	platform_set_drvdata(pdev, qspi);
+
+	qspi->xfer_mode.width = -1;
+	qspi->xfer_mode.addrlen = -1;
+	qspi->xfer_mode.hp = -1;
+
 	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 		dev_err(dev, "can't register master\n");
@@ -730,6 +1331,7 @@ static int bcm_qspi_resume(struct device *dev)
 	int ret = 0;
 
 	bcm_qspi_hw_init(qspi);
+	bcm_qspi_bspi_set_mode(qspi, -1, -1, -1);
 	qspi->curr_cs = -1;
 	bcm_qspi_chip_select(qspi, curr_cs);
 
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
index 0bdddd4..e0a354a 100644
--- a/drivers/spi/spi-bcm-qspi.h
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -20,6 +20,26 @@
 #include <linux/types.h>
 #include <linux/io.h>
 
+/* BSPI interrupt masks */
+#define INTR_BSPI_LR_OVERREAD_MASK		BIT(4)
+#define INTR_BSPI_LR_SESSION_DONE_MASK		BIT(3)
+#define INTR_BSPI_LR_IMPATIENT_MASK		BIT(2)
+#define INTR_BSPI_LR_SESSION_ABORTED_MASK	BIT(1)
+#define INTR_BSPI_LR_FULLNESS_REACHED_MASK	BIT(0)
+
+#define BSPI_LR_INTERRUPTS_DATA		       \
+	(INTR_BSPI_LR_SESSION_DONE_MASK |	       \
+	 INTR_BSPI_LR_FULLNESS_REACHED_MASK)
+
+#define BSPI_LR_INTERRUPTS_ERROR               \
+	(INTR_BSPI_LR_OVERREAD_MASK |	       \
+	 INTR_BSPI_LR_IMPATIENT_MASK |	       \
+	 INTR_BSPI_LR_SESSION_ABORTED_MASK)
+
+#define BSPI_LR_INTERRUPTS_ALL                 \
+	(BSPI_LR_INTERRUPTS_ERROR |	       \
+	 BSPI_LR_INTERRUPTS_DATA)
+
 /* MSPI Interrupt masks */
 #define INTR_MSPI_HALTED_MASK			BIT(6)
 #define INTR_MSPI_DONE_MASK			BIT(5)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, 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.

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/mtd/devices/m25p80.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 9d68544..3f90542 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -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);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, 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.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
---
 drivers/mtd/devices/m25p80.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 9d68544..3f90542 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 5/8] Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu

Modify device tree bindings documentation to include
NS*, Cygnus and iProc SoCs supported by the new spi-bcm-qspi,
spi-nsp-qspi driver.

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 96 +++++++++++++++++++++-
 1 file changed, 93 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
index bbae763..bc01b73 100644
--- a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -5,8 +5,8 @@ BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
 of :
  MSPI : SPI master controller can read and write to a SPI slave device
  BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
-        for flash reads and be configured to do single, double, quad lane
-        io with 3-byte and 4-byte addressing support.
+	for flash reads and be configured to do single, double, quad lane
+	io with 3-byte and 4-byte addressing support.
 
  Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
  MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
@@ -26,6 +26,8 @@ Required properties:
     "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
     "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
 						   BRCMSTB  SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi" : Uses MSPI+BSPI on Cygnus, NSP,
+			 		       NS2 SoCs
 
 - reg:
     Define the bases and ranges of the associated I/O address spaces.
@@ -35,8 +37,10 @@ Required properties:
     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, not required with compatible
-                   "spi-brcmstb-mspi"
+		   "spi-brcmstb-mspi"
     - "mspi_regs": MSPI register range is required for compatible strings
+    - "intr_regs", "intr_status_reg" : Interrupt and status register for
+      NSP, NS2, Cygnus SoC
 
 - interrupts
     The interrupts used by the MSPI and/or BSPI controller.
@@ -143,3 +147,89 @@ BRCMSTB SoC Example:
 		interrupt-names = "mspi_done";
 	};
 
+iProc SoC Example:
+
+    qspi: spi@18027200 {
+	compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-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", "brcm,spi-nsp-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
+
+	 &qspi {
+		      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>;
+		      };
+	};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 5/8] Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu

Modify device tree bindings documentation to include
NS*, Cygnus and iProc SoCs supported by the new spi-bcm-qspi,
spi-nsp-qspi driver.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 96 +++++++++++++++++++++-
 1 file changed, 93 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
index bbae763..bc01b73 100644
--- a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -5,8 +5,8 @@ BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
 of :
  MSPI : SPI master controller can read and write to a SPI slave device
  BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
-        for flash reads and be configured to do single, double, quad lane
-        io with 3-byte and 4-byte addressing support.
+	for flash reads and be configured to do single, double, quad lane
+	io with 3-byte and 4-byte addressing support.
 
  Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
  MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
@@ -26,6 +26,8 @@ Required properties:
     "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
     "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
 						   BRCMSTB  SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi" : Uses MSPI+BSPI on Cygnus, NSP,
+			 		       NS2 SoCs
 
 - reg:
     Define the bases and ranges of the associated I/O address spaces.
@@ -35,8 +37,10 @@ Required properties:
     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, not required with compatible
-                   "spi-brcmstb-mspi"
+		   "spi-brcmstb-mspi"
     - "mspi_regs": MSPI register range is required for compatible strings
+    - "intr_regs", "intr_status_reg" : Interrupt and status register for
+      NSP, NS2, Cygnus SoC
 
 - interrupts
     The interrupts used by the MSPI and/or BSPI controller.
@@ -143,3 +147,89 @@ BRCMSTB SoC Example:
 		interrupt-names = "mspi_done";
 	};
 
+iProc SoC Example:
+
+    qspi: spi@18027200 {
+	compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-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", "brcm,spi-nsp-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
+
+	 &qspi {
+		      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>;
+		      };
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu,
	Yendapally Reddy Dhananjaya Reddy

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

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
 arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
 arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 6a40ed7..26c863e 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -160,7 +160,7 @@
 
 	axi {
 		compatible = "simple-bus";
-		ranges = <0x00000000 0x18000000 0x0011ba08>;
+		ranges = <0x00000000 0x18000000 0x0011c40a>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 
@@ -206,9 +206,34 @@
 			brcm,nand-has-wp;
 		};
 
-		rng: rng@33000 {
-			compatible = "brcm,bcm-nsp-rng";
-			reg = <0x33000 0x14>;
+		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 {
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
index 2d84226..ab7ba8f 100644
--- a/arch/arm/boot/dts/bcm958625k.dts
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -126,3 +126,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>;
+		};
+	};
+};
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu, Yendapally Reddy Dhananjaya Reddy

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

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
 arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 6a40ed7..26c863e 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -160,7 +160,7 @@
 
 	axi {
 		compatible = "simple-bus";
-		ranges = <0x00000000 0x18000000 0x0011ba08>;
+		ranges = <0x00000000 0x18000000 0x0011c40a>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 
@@ -206,9 +206,34 @@
 			brcm,nand-has-wp;
 		};
 
-		rng: rng@33000 {
-			compatible = "brcm,bcm-nsp-rng";
-			reg = <0x33000 0x14>;
+		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 {
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
index 2d84226..ab7ba8f 100644
--- a/arch/arm/boot/dts/bcm958625k.dts
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -126,3 +126,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>;
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 7/8] arm64: dts: Add ns2 SoC support
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu,
	Yendapally Reddy Dhananjaya Reddy

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

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
 arch/arm64/boot/dts/broadcom/ns2-svk.dts | 34 ++++++++++++++++++++++++++++----
 arch/arm64/boot/dts/broadcom/ns2.dtsi    | 19 ++++++++++++++++++
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index ea5603f..a40d3f5 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -141,10 +141,36 @@
 	};
 };
 
-&mdio_mux_iproc {
-	mdio@10 {
-		gphy0: eth-phy@10 {
-			reg = <0x10>;
+&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>;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index 46b78fa..efc5d50 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -438,5 +438,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>;
+		};
+
 	};
 };
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 7/8] arm64: dts: Add ns2 SoC support
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu, Yendapally Reddy Dhananjaya Reddy

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

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
---
 arch/arm64/boot/dts/broadcom/ns2-svk.dts | 34 ++++++++++++++++++++++++++++----
 arch/arm64/boot/dts/broadcom/ns2.dtsi    | 19 ++++++++++++++++++
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index ea5603f..a40d3f5 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -141,10 +141,36 @@
 	};
 };
 
-&mdio_mux_iproc {
-	mdio@10 {
-		gphy0: eth-phy@10 {
-			reg = <0x10>;
+&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>;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index 46b78fa..efc5d50 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -438,5 +438,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>;
+		};
+
 	};
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
  2016-07-29 22:13 ` Kamal Dasu
@ 2016-07-29 22:13     ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu

This spi driver uses the common spi-bcm-qspi driver
and implements NS*, Cysgnus  SoC specific intrrupt handlers.
The common driver now calls the SoC handlers when present.
Adding support for both muxed l1 and unmuxed interrupt sources.

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/Makefile       |   2 +-
 drivers/spi/spi-bcm-qspi.c |  89 ++++++++++++++++++++++++-
 drivers/spi/spi-bcm-qspi.h |  33 +++++++++-
 drivers/spi/spi-nsp-qspi.c | 158 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 279 insertions(+), 3 deletions(-)
 create mode 100644 drivers/spi/spi-nsp-qspi.c

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3e753db..5e46538 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -21,7 +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-brcmstb-qspi.o spi-bcm-qspi.o
+obj-$(CONFIG_SPI_BCM_QSPI)		+= spi-nsp-qspi.o spi-brcmstb-qspi.o 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
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index 0c1a617..45b2636 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -184,9 +184,15 @@ enum base_type {
 	BASEMAX,
 };
 
+enum irq_source {
+	SINGLE_L2,
+	MUXED_L1,
+};
+
 struct bcm_qspi_irq {
 	const char *irq_name;
 	const irq_handler_t irq_handler;
+	int irq_source;
 	u32 mask;
 };
 
@@ -207,6 +213,10 @@ struct bcm_qspi {
 	u32 base_clk;
 	u32 max_speed_hz;
 	void __iomem *base[BASEMAX];
+
+	/* Some SoCs provide custom interrupt status register(s) */
+	struct bcm_qspi_soc	*soc;
+
 	struct bcm_qspi_parms last_parms;
 	struct qspi_trans  trans_pos;
 	int state;
@@ -840,6 +850,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
 	int ret = 0;
 	int retry = 3;
 	unsigned long timeo = msecs_to_jiffies(100);
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	if (bcm_qspi_bspi_ver_three(qspi))
 		if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
@@ -883,6 +894,15 @@ retry:
 	bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
 	bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
 
+	if (qspi->soc) {
+		/*
+		 * clear soc MSPI and BSPI interrupts and enable
+		 * BSPI interrupts.
+		 */
+		soc->bcm_qspi_int_ack(soc, MSPI_BSPI_DONE);
+		soc->bcm_qspi_int_set(soc, BSPI_DONE, true);
+	}
+
 	bcm_qspi_bspi_lr_start(qspi);
 	/* Must flush previous writes before starting BSPI operation */
 	mb();
@@ -999,9 +1019,12 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
 	u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
 
 	if (status & MSPI_MSPI_STATUS_SPIF) {
+		struct bcm_qspi_soc *soc = qspi->soc;
 		/* clear interrupt */
 		status &= ~MSPI_MSPI_STATUS_SPIF;
 		bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
+		if (qspi->soc)
+			soc->bcm_qspi_int_ack(soc, MSPI_DONE);
 		complete(&qspi->mspi_done);
 		return IRQ_HANDLED;
 	} else {
@@ -1013,11 +1036,16 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
 {
 	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
 	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
 		bcm_qspi_bspi_lr_data_read(qspi);
 		if (qspi->bspi_rf_msg_len == 0) {
 			qspi->bspi_rf_msg = NULL;
+			if (qspi->soc)
+				/* disable soc BSPI interrupt */
+				soc->bcm_qspi_int_set(soc, BSPI_DONE, false);
+
 			if (qspi->bspi_rf_msg_status)
 				bcm_qspi_bspi_lr_clear(qspi);
 			else
@@ -1025,6 +1053,11 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
 
 			complete(&qspi->bspi_done);
 		}
+
+		if (qspi->soc)
+			/* clear soc BSPI interrupt */
+			soc->bcm_qspi_int_ack(soc, BSPI_DONE);
+
 		return IRQ_HANDLED;
 	}
 
@@ -1035,14 +1068,40 @@ static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
 {
 	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
 	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
 		qspi_dev_id->irqp->mask);
 	qspi->bspi_rf_msg_status = -EIO;
+	if (qspi->soc)
+		/* clear soc interrupt */
+		soc->bcm_qspi_int_ack(soc, BSPI_ERR);
+
 	complete(&qspi->bspi_done);
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t bcm_qspi_l1_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (soc) {
+		u32 status = soc->bcm_qspi_get_int_status(soc);
+
+		if (status & MSPI_DONE)
+			ret = bcm_qspi_mspi_l2_isr(irq, dev_id);
+		else if (status & BSPI_DONE)
+			ret = bcm_qspi_bspi_lr_l2_isr(irq, dev_id);
+		else if (status & BSPI_ERR)
+			ret = bcm_qspi_bspi_lr_err_l2_isr(irq, dev_id);
+	}
+
+	return ret;
+}
+
 static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	{
 		.irq_name = "spi_lr_fullness_reached",
@@ -1082,6 +1141,13 @@ static const struct bcm_qspi_irq qspi_irq_tab[] = {
 		.irq_handler = bcm_qspi_mspi_l2_isr,
 		.mask = INTR_MSPI_HALTED_MASK,
 	},
+	{
+		/* single muxed L1 interrupt source */
+		.irq_name = "spi_l1_intr",
+		.irq_handler = bcm_qspi_l1_isr,
+		.irq_source = MUXED_L1,
+		.mask = QSPI_INTERRUPTS_ALL,
+	},
 };
 
 static void bcm_qspi_bspi_init(struct bcm_qspi *qspi)
@@ -1231,7 +1297,17 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 	for (val = 0; val < num_irqs; val++) {
 		irq = -1;
 		name = qspi_irq_tab[val].irq_name;
-		irq = platform_get_irq_byname(pdev, name);
+		if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
+			/* all mspi, bspi intrs muxed to one L1 intr */
+			irq = platform_get_irq(pdev, 0);
+			of_property_read_string(dev->of_node,
+						"interrupt-names",
+						&name);
+		}
+
+		if (qspi_irq_tab[val].irq_source == SINGLE_L2)
+			/* get the l2 interrupts */
+			irq = platform_get_irq_byname(pdev, name);
 
 		if (irq  >= 0) {
 			ret = devm_request_irq(&pdev->dev, irq,
@@ -1257,6 +1333,17 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 		goto err2;
 	}
 
+	/*
+	 * Some SoCs integrate spi controller (e.g., its interrupt bits)
+	 * in specific ways
+	 */
+	if (soc) {
+		qspi->soc = soc;
+		soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
+	} else {
+		qspi->soc = NULL;
+	}
+
 	qspi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(qspi->clk)) {
 		dev_warn(dev, "unable to get clock\n");
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
index e0a354a..407059c 100644
--- a/drivers/spi/spi-bcm-qspi.h
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -48,10 +48,25 @@
 	(INTR_MSPI_DONE_MASK |		       \
 	 INTR_MSPI_HALTED_MASK)
 
+#define QSPI_INTERRUPTS_ALL                    \
+	(MSPI_INTERRUPTS_ALL |		       \
+	 BSPI_LR_INTERRUPTS_ALL)
+
 struct platform_device;
 struct dev_pm_ops;
 
-struct bcm_qspi_soc;
+enum {
+	MSPI_DONE = 0x1,
+	BSPI_DONE = 0x2,
+	BSPI_ERR = 0x4,
+	MSPI_BSPI_DONE = 0x7
+};
+
+struct bcm_qspi_soc {
+	void (*bcm_qspi_int_ack)(struct bcm_qspi_soc *soc, int type);
+	void (*bcm_qspi_int_set)(struct bcm_qspi_soc *soc, int type, bool en);
+	u32 (*bcm_qspi_get_int_status)(struct bcm_qspi_soc *soc);
+};
 
 /* Read controller register*/
 static inline u32 bcm_qspi_readl(struct platform_device *pdev,
@@ -73,6 +88,22 @@ static inline void bcm_qspi_writel(struct platform_device *pdev,
 		writel_relaxed(data, addr);
 }
 
+static inline u32 get_qspi_mask(int type)
+{
+	switch (type) {
+	case MSPI_DONE:
+		return INTR_MSPI_DONE_MASK;
+	case BSPI_DONE:
+		return BSPI_LR_INTERRUPTS_ALL;
+	case MSPI_BSPI_DONE:
+		return QSPI_INTERRUPTS_ALL;
+	case BSPI_ERR:
+		return BSPI_LR_INTERRUPTS_ERROR;
+	}
+
+	return 0;
+}
+
 int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc);
 int bcm_qspi_remove(struct platform_device *pdev);
 
diff --git a/drivers/spi/spi-nsp-qspi.c b/drivers/spi/spi-nsp-qspi.c
new file mode 100644
index 0000000..2a4e052
--- /dev/null
+++ b/drivers/spi/spi-nsp-qspi.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2016 Broadcom Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "spi-bcm-qspi.h"
+
+#define INTR_BASE_BIT_SHIFT			0x02
+#define INTR_COUNT				0x07
+
+struct bcm_nsp_soc {
+	struct bcm_qspi_soc soc;
+	struct platform_device *pdev;
+	void __iomem *int_reg;
+	void __iomem *int_status_reg;
+	spinlock_t soclock;
+};
+
+static u32 bcm_nsp_qspi_get_l2_int_status(struct bcm_qspi_soc *soc)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_status_reg;
+	int i;
+	u32 val = 0, sts = 0;
+
+	for (i = 0; i < INTR_COUNT; i++) {
+		if (bcm_qspi_readl(priv->pdev, mmio + (i * 4)))
+			val |= 1UL << i;
+	}
+
+	if (val & INTR_MSPI_DONE_MASK)
+		sts |= MSPI_DONE;
+
+	if (val & BSPI_LR_INTERRUPTS_ALL)
+		sts |= BSPI_DONE;
+
+	if (val & BSPI_LR_INTERRUPTS_ERROR)
+		sts |= BSPI_ERR;
+
+	return sts;
+}
+
+static void bcm_nsp_qspi_int_ack(struct bcm_qspi_soc *soc, int type)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_status_reg;
+	u32 mask = get_qspi_mask(type);
+	int i;
+
+	for (i = 0; i < INTR_COUNT; i++) {
+		if (mask & (1UL << i))
+			bcm_qspi_writel(priv->pdev, 1, mmio + (i * 4));
+	}
+}
+
+static void bcm_nsp_qspi_int_set(struct bcm_qspi_soc *soc, int type, bool en)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_reg;
+	u32 mask = get_qspi_mask(type);
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->soclock, flags);
+
+	val = bcm_qspi_readl(priv->pdev, mmio);
+
+	if (en)
+		val = val | (mask << INTR_BASE_BIT_SHIFT);
+	else
+		val = val & ~(mask << INTR_BASE_BIT_SHIFT);
+
+	bcm_qspi_writel(priv->pdev, val, mmio);
+
+	spin_unlock_irqrestore(&priv->soclock, flags);
+}
+
+static int bcm_nsp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm_nsp_soc *priv;
+	struct bcm_qspi_soc *soc;
+	struct resource *res;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	soc = &priv->soc;
+	priv->pdev = pdev;
+
+	spin_lock_init(&priv->soclock);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr_regs");
+	priv->int_reg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->int_reg))
+		return PTR_ERR(priv->int_reg);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "intr_status_reg");
+	priv->int_status_reg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->int_status_reg))
+		return PTR_ERR(priv->int_status_reg);
+
+	bcm_nsp_qspi_int_ack(soc, MSPI_BSPI_DONE);
+	bcm_nsp_qspi_int_set(soc, MSPI_BSPI_DONE, false);
+
+	soc->bcm_qspi_int_ack = bcm_nsp_qspi_int_ack;
+	soc->bcm_qspi_int_set = bcm_nsp_qspi_int_set;
+	soc->bcm_qspi_get_int_status = bcm_nsp_qspi_get_l2_int_status;
+
+	return bcm_qspi_probe(pdev, soc);
+}
+
+static int bcm_nsp_remove(struct platform_device *pdev)
+{
+	return bcm_qspi_remove(pdev);
+}
+
+static const struct of_device_id bcm_nsp_of_match[] = {
+	{ .compatible = "brcm,spi-nsp-qspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm_nsp_of_match);
+
+static struct platform_driver bcm_nsp_driver = {
+	.probe			= bcm_nsp_probe,
+	.remove			= bcm_nsp_remove,
+	.driver = {
+		.name		= "bcm_nsp",
+		.pm		= &bcm_qspi_pm_ops,
+		.of_match_table = bcm_nsp_of_match,
+	}
+};
+module_platform_driver(bcm_nsp_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("SPI flash driver for Broadcom NSP, NS2, Cygnus SoCs");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
@ 2016-07-29 22:13     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:13 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu

This spi driver uses the common spi-bcm-qspi driver
and implements NS*, Cysgnus  SoC specific intrrupt handlers.
The common driver now calls the SoC handlers when present.
Adding support for both muxed l1 and unmuxed interrupt sources.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
---
 drivers/spi/Makefile       |   2 +-
 drivers/spi/spi-bcm-qspi.c |  89 ++++++++++++++++++++++++-
 drivers/spi/spi-bcm-qspi.h |  33 +++++++++-
 drivers/spi/spi-nsp-qspi.c | 158 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 279 insertions(+), 3 deletions(-)
 create mode 100644 drivers/spi/spi-nsp-qspi.c

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3e753db..5e46538 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -21,7 +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-brcmstb-qspi.o spi-bcm-qspi.o
+obj-$(CONFIG_SPI_BCM_QSPI)		+= spi-nsp-qspi.o spi-brcmstb-qspi.o 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
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index 0c1a617..45b2636 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -184,9 +184,15 @@ enum base_type {
 	BASEMAX,
 };
 
+enum irq_source {
+	SINGLE_L2,
+	MUXED_L1,
+};
+
 struct bcm_qspi_irq {
 	const char *irq_name;
 	const irq_handler_t irq_handler;
+	int irq_source;
 	u32 mask;
 };
 
@@ -207,6 +213,10 @@ struct bcm_qspi {
 	u32 base_clk;
 	u32 max_speed_hz;
 	void __iomem *base[BASEMAX];
+
+	/* Some SoCs provide custom interrupt status register(s) */
+	struct bcm_qspi_soc	*soc;
+
 	struct bcm_qspi_parms last_parms;
 	struct qspi_trans  trans_pos;
 	int state;
@@ -840,6 +850,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
 	int ret = 0;
 	int retry = 3;
 	unsigned long timeo = msecs_to_jiffies(100);
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	if (bcm_qspi_bspi_ver_three(qspi))
 		if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
@@ -883,6 +894,15 @@ retry:
 	bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
 	bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
 
+	if (qspi->soc) {
+		/*
+		 * clear soc MSPI and BSPI interrupts and enable
+		 * BSPI interrupts.
+		 */
+		soc->bcm_qspi_int_ack(soc, MSPI_BSPI_DONE);
+		soc->bcm_qspi_int_set(soc, BSPI_DONE, true);
+	}
+
 	bcm_qspi_bspi_lr_start(qspi);
 	/* Must flush previous writes before starting BSPI operation */
 	mb();
@@ -999,9 +1019,12 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
 	u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
 
 	if (status & MSPI_MSPI_STATUS_SPIF) {
+		struct bcm_qspi_soc *soc = qspi->soc;
 		/* clear interrupt */
 		status &= ~MSPI_MSPI_STATUS_SPIF;
 		bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
+		if (qspi->soc)
+			soc->bcm_qspi_int_ack(soc, MSPI_DONE);
 		complete(&qspi->mspi_done);
 		return IRQ_HANDLED;
 	} else {
@@ -1013,11 +1036,16 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
 {
 	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
 	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
 		bcm_qspi_bspi_lr_data_read(qspi);
 		if (qspi->bspi_rf_msg_len == 0) {
 			qspi->bspi_rf_msg = NULL;
+			if (qspi->soc)
+				/* disable soc BSPI interrupt */
+				soc->bcm_qspi_int_set(soc, BSPI_DONE, false);
+
 			if (qspi->bspi_rf_msg_status)
 				bcm_qspi_bspi_lr_clear(qspi);
 			else
@@ -1025,6 +1053,11 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
 
 			complete(&qspi->bspi_done);
 		}
+
+		if (qspi->soc)
+			/* clear soc BSPI interrupt */
+			soc->bcm_qspi_int_ack(soc, BSPI_DONE);
+
 		return IRQ_HANDLED;
 	}
 
@@ -1035,14 +1068,40 @@ static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
 {
 	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
 	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
 
 	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
 		qspi_dev_id->irqp->mask);
 	qspi->bspi_rf_msg_status = -EIO;
+	if (qspi->soc)
+		/* clear soc interrupt */
+		soc->bcm_qspi_int_ack(soc, BSPI_ERR);
+
 	complete(&qspi->bspi_done);
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t bcm_qspi_l1_isr(int irq, void *dev_id)
+{
+	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
+	struct bcm_qspi *qspi = qspi_dev_id->dev;
+	struct bcm_qspi_soc *soc = qspi->soc;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (soc) {
+		u32 status = soc->bcm_qspi_get_int_status(soc);
+
+		if (status & MSPI_DONE)
+			ret = bcm_qspi_mspi_l2_isr(irq, dev_id);
+		else if (status & BSPI_DONE)
+			ret = bcm_qspi_bspi_lr_l2_isr(irq, dev_id);
+		else if (status & BSPI_ERR)
+			ret = bcm_qspi_bspi_lr_err_l2_isr(irq, dev_id);
+	}
+
+	return ret;
+}
+
 static const struct bcm_qspi_irq qspi_irq_tab[] = {
 	{
 		.irq_name = "spi_lr_fullness_reached",
@@ -1082,6 +1141,13 @@ static const struct bcm_qspi_irq qspi_irq_tab[] = {
 		.irq_handler = bcm_qspi_mspi_l2_isr,
 		.mask = INTR_MSPI_HALTED_MASK,
 	},
+	{
+		/* single muxed L1 interrupt source */
+		.irq_name = "spi_l1_intr",
+		.irq_handler = bcm_qspi_l1_isr,
+		.irq_source = MUXED_L1,
+		.mask = QSPI_INTERRUPTS_ALL,
+	},
 };
 
 static void bcm_qspi_bspi_init(struct bcm_qspi *qspi)
@@ -1231,7 +1297,17 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 	for (val = 0; val < num_irqs; val++) {
 		irq = -1;
 		name = qspi_irq_tab[val].irq_name;
-		irq = platform_get_irq_byname(pdev, name);
+		if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
+			/* all mspi, bspi intrs muxed to one L1 intr */
+			irq = platform_get_irq(pdev, 0);
+			of_property_read_string(dev->of_node,
+						"interrupt-names",
+						&name);
+		}
+
+		if (qspi_irq_tab[val].irq_source == SINGLE_L2)
+			/* get the l2 interrupts */
+			irq = platform_get_irq_byname(pdev, name);
 
 		if (irq  >= 0) {
 			ret = devm_request_irq(&pdev->dev, irq,
@@ -1257,6 +1333,17 @@ int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc)
 		goto err2;
 	}
 
+	/*
+	 * Some SoCs integrate spi controller (e.g., its interrupt bits)
+	 * in specific ways
+	 */
+	if (soc) {
+		qspi->soc = soc;
+		soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
+	} else {
+		qspi->soc = NULL;
+	}
+
 	qspi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(qspi->clk)) {
 		dev_warn(dev, "unable to get clock\n");
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h
index e0a354a..407059c 100644
--- a/drivers/spi/spi-bcm-qspi.h
+++ b/drivers/spi/spi-bcm-qspi.h
@@ -48,10 +48,25 @@
 	(INTR_MSPI_DONE_MASK |		       \
 	 INTR_MSPI_HALTED_MASK)
 
+#define QSPI_INTERRUPTS_ALL                    \
+	(MSPI_INTERRUPTS_ALL |		       \
+	 BSPI_LR_INTERRUPTS_ALL)
+
 struct platform_device;
 struct dev_pm_ops;
 
-struct bcm_qspi_soc;
+enum {
+	MSPI_DONE = 0x1,
+	BSPI_DONE = 0x2,
+	BSPI_ERR = 0x4,
+	MSPI_BSPI_DONE = 0x7
+};
+
+struct bcm_qspi_soc {
+	void (*bcm_qspi_int_ack)(struct bcm_qspi_soc *soc, int type);
+	void (*bcm_qspi_int_set)(struct bcm_qspi_soc *soc, int type, bool en);
+	u32 (*bcm_qspi_get_int_status)(struct bcm_qspi_soc *soc);
+};
 
 /* Read controller register*/
 static inline u32 bcm_qspi_readl(struct platform_device *pdev,
@@ -73,6 +88,22 @@ static inline void bcm_qspi_writel(struct platform_device *pdev,
 		writel_relaxed(data, addr);
 }
 
+static inline u32 get_qspi_mask(int type)
+{
+	switch (type) {
+	case MSPI_DONE:
+		return INTR_MSPI_DONE_MASK;
+	case BSPI_DONE:
+		return BSPI_LR_INTERRUPTS_ALL;
+	case MSPI_BSPI_DONE:
+		return QSPI_INTERRUPTS_ALL;
+	case BSPI_ERR:
+		return BSPI_LR_INTERRUPTS_ERROR;
+	}
+
+	return 0;
+}
+
 int bcm_qspi_probe(struct platform_device *pdev, struct bcm_qspi_soc *soc);
 int bcm_qspi_remove(struct platform_device *pdev);
 
diff --git a/drivers/spi/spi-nsp-qspi.c b/drivers/spi/spi-nsp-qspi.c
new file mode 100644
index 0000000..2a4e052
--- /dev/null
+++ b/drivers/spi/spi-nsp-qspi.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2016 Broadcom Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "spi-bcm-qspi.h"
+
+#define INTR_BASE_BIT_SHIFT			0x02
+#define INTR_COUNT				0x07
+
+struct bcm_nsp_soc {
+	struct bcm_qspi_soc soc;
+	struct platform_device *pdev;
+	void __iomem *int_reg;
+	void __iomem *int_status_reg;
+	spinlock_t soclock;
+};
+
+static u32 bcm_nsp_qspi_get_l2_int_status(struct bcm_qspi_soc *soc)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_status_reg;
+	int i;
+	u32 val = 0, sts = 0;
+
+	for (i = 0; i < INTR_COUNT; i++) {
+		if (bcm_qspi_readl(priv->pdev, mmio + (i * 4)))
+			val |= 1UL << i;
+	}
+
+	if (val & INTR_MSPI_DONE_MASK)
+		sts |= MSPI_DONE;
+
+	if (val & BSPI_LR_INTERRUPTS_ALL)
+		sts |= BSPI_DONE;
+
+	if (val & BSPI_LR_INTERRUPTS_ERROR)
+		sts |= BSPI_ERR;
+
+	return sts;
+}
+
+static void bcm_nsp_qspi_int_ack(struct bcm_qspi_soc *soc, int type)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_status_reg;
+	u32 mask = get_qspi_mask(type);
+	int i;
+
+	for (i = 0; i < INTR_COUNT; i++) {
+		if (mask & (1UL << i))
+			bcm_qspi_writel(priv->pdev, 1, mmio + (i * 4));
+	}
+}
+
+static void bcm_nsp_qspi_int_set(struct bcm_qspi_soc *soc, int type, bool en)
+{
+	struct bcm_nsp_soc *priv =
+			container_of(soc, struct bcm_nsp_soc, soc);
+	void __iomem *mmio = priv->int_reg;
+	u32 mask = get_qspi_mask(type);
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->soclock, flags);
+
+	val = bcm_qspi_readl(priv->pdev, mmio);
+
+	if (en)
+		val = val | (mask << INTR_BASE_BIT_SHIFT);
+	else
+		val = val & ~(mask << INTR_BASE_BIT_SHIFT);
+
+	bcm_qspi_writel(priv->pdev, val, mmio);
+
+	spin_unlock_irqrestore(&priv->soclock, flags);
+}
+
+static int bcm_nsp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm_nsp_soc *priv;
+	struct bcm_qspi_soc *soc;
+	struct resource *res;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	soc = &priv->soc;
+	priv->pdev = pdev;
+
+	spin_lock_init(&priv->soclock);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr_regs");
+	priv->int_reg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->int_reg))
+		return PTR_ERR(priv->int_reg);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "intr_status_reg");
+	priv->int_status_reg = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->int_status_reg))
+		return PTR_ERR(priv->int_status_reg);
+
+	bcm_nsp_qspi_int_ack(soc, MSPI_BSPI_DONE);
+	bcm_nsp_qspi_int_set(soc, MSPI_BSPI_DONE, false);
+
+	soc->bcm_qspi_int_ack = bcm_nsp_qspi_int_ack;
+	soc->bcm_qspi_int_set = bcm_nsp_qspi_int_set;
+	soc->bcm_qspi_get_int_status = bcm_nsp_qspi_get_l2_int_status;
+
+	return bcm_qspi_probe(pdev, soc);
+}
+
+static int bcm_nsp_remove(struct platform_device *pdev)
+{
+	return bcm_qspi_remove(pdev);
+}
+
+static const struct of_device_id bcm_nsp_of_match[] = {
+	{ .compatible = "brcm,spi-nsp-qspi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm_nsp_of_match);
+
+static struct platform_driver bcm_nsp_driver = {
+	.probe			= bcm_nsp_probe,
+	.remove			= bcm_nsp_remove,
+	.driver = {
+		.name		= "bcm_nsp",
+		.pm		= &bcm_qspi_pm_ops,
+		.of_match_table = bcm_nsp_of_match,
+	}
+};
+module_platform_driver(bcm_nsp_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Kamal Dasu");
+MODULE_DESCRIPTION("SPI flash driver for Broadcom NSP, NS2, Cygnus SoCs");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-01 15:09       ` Jonas Gorski
  -1 siblings, 0 replies; 54+ messages in thread
From: Jonas Gorski @ 2016-08-01 15:09 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: Florian Fainelli, Jayachandran C, vigneshr, linux-spi,
	Yendapally Reddy Dhananjaya Reddy, Mark Brown,
	bcm-kernel-feedback-list, MTD Maling List, jon.mason,
	vikram.prakash, andy.fung

Hi,

On 30 July 2016 at 00:13, Kamal Dasu <kdasu.kdev@gmail.com> wrote:
> Adding qspi node compatible with the new spi-bcm-qspi
> driver for the broadcom's northstar SoC.
>
> Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
> Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
> ---
>  arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
>  arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
>  2 files changed, 63 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> index 6a40ed7..26c863e 100644
> --- a/arch/arm/boot/dts/bcm-nsp.dtsi
> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> @@ -160,7 +160,7 @@
>
>         axi {
>                 compatible = "simple-bus";
> -               ranges = <0x00000000 0x18000000 0x0011ba08>;
> +               ranges = <0x00000000 0x18000000 0x0011c40a>;
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>
> @@ -206,9 +206,34 @@
>                         brcm,nand-has-wp;
>                 };
>
> -               rng: rng@33000 {
> -                       compatible = "brcm,bcm-nsp-rng";
> -                       reg = <0x33000 0x14>;

You remove the rng node, is this intentional?

> +               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 {
> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> index 2d84226..ab7ba8f 100644
> --- a/arch/arm/boot/dts/bcm958625k.dts
> +++ b/arch/arm/boot/dts/bcm958625k.dts
> @@ -126,3 +126,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>;
> +               };

these should be enclosed by a partitions node with compatible
"fixed-partitions", see
Documentation/devicetree/bindings/mtd/partition.txt.

> +
> +               partition@1 {

The address is 0xa0000 so this should be partition@a0000.

> +                       label = "env";
> +                       reg = <0x000a0000 0x00060000>;
> +               };
> +
> +               partition@2 {

likewise.

> +                       label = "system";
> +                       reg = <0x00100000 0x00600000>;
> +               };
> +
> +               partition@3 {

etc.

> +                       label = "rootfs";
> +                       reg = <0x00700000 0x01900000>;
> +               };
> +       };
> +};


Regards
Jonas

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
@ 2016-08-01 15:09       ` Jonas Gorski
  0 siblings, 0 replies; 54+ messages in thread
From: Jonas Gorski @ 2016-08-01 15:09 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: Mark Brown, linux-spi, MTD Maling List, vigneshr,
	Florian Fainelli, bcm-kernel-feedback-list, vikram.prakash,
	andy.fung, jon.mason, Jayachandran C,
	Yendapally Reddy Dhananjaya Reddy

Hi,

On 30 July 2016 at 00:13, Kamal Dasu <kdasu.kdev@gmail.com> wrote:
> Adding qspi node compatible with the new spi-bcm-qspi
> driver for the broadcom's northstar SoC.
>
> Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
> Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
> ---
>  arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
>  arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
>  2 files changed, 63 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> index 6a40ed7..26c863e 100644
> --- a/arch/arm/boot/dts/bcm-nsp.dtsi
> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> @@ -160,7 +160,7 @@
>
>         axi {
>                 compatible = "simple-bus";
> -               ranges = <0x00000000 0x18000000 0x0011ba08>;
> +               ranges = <0x00000000 0x18000000 0x0011c40a>;
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>
> @@ -206,9 +206,34 @@
>                         brcm,nand-has-wp;
>                 };
>
> -               rng: rng@33000 {
> -                       compatible = "brcm,bcm-nsp-rng";
> -                       reg = <0x33000 0x14>;

You remove the rng node, is this intentional?

> +               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 {
> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> index 2d84226..ab7ba8f 100644
> --- a/arch/arm/boot/dts/bcm958625k.dts
> +++ b/arch/arm/boot/dts/bcm958625k.dts
> @@ -126,3 +126,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>;
> +               };

these should be enclosed by a partitions node with compatible
"fixed-partitions", see
Documentation/devicetree/bindings/mtd/partition.txt.

> +
> +               partition@1 {

The address is 0xa0000 so this should be partition@a0000.

> +                       label = "env";
> +                       reg = <0x000a0000 0x00060000>;
> +               };
> +
> +               partition@2 {

likewise.

> +                       label = "system";
> +                       reg = <0x00100000 0x00600000>;
> +               };
> +
> +               partition@3 {

etc.

> +                       label = "rootfs";
> +                       reg = <0x00700000 0x01900000>;
> +               };
> +       };
> +};


Regards
Jonas

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
  2016-08-01 15:09       ` Jonas Gorski
@ 2016-08-02 19:51           ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-02 19:51 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli, bcm-kernel-feedback-list,
	Vikram Prakash, Andy Fung, Jon Mason, Jayachandran C,
	Yendapally Reddy Dhananjaya Reddy

Jonas,

"You remove the rng node, is this intentional?"

Not intentional,  was a bad rebase merge to the latest sources, will
fix this in next version of the patch.

"The address is 0xa0000 so this should be partition@a0000.
 etc."

Will fix this as well.

Thanks
Kamal

On Mon, Aug 1, 2016 at 11:09 AM, Jonas Gorski <jonas.gorski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi,
>
> On 30 July 2016 at 00:13, Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Adding qspi node compatible with the new spi-bcm-qspi
>> driver for the broadcom's northstar SoC.
>>
>> Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>> ---
>>  arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
>>  arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 63 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
>> index 6a40ed7..26c863e 100644
>> --- a/arch/arm/boot/dts/bcm-nsp.dtsi
>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>> @@ -160,7 +160,7 @@
>>
>>         axi {
>>                 compatible = "simple-bus";
>> -               ranges = <0x00000000 0x18000000 0x0011ba08>;
>> +               ranges = <0x00000000 0x18000000 0x0011c40a>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>>
>> @@ -206,9 +206,34 @@
>>                         brcm,nand-has-wp;
>>                 };
>>
>> -               rng: rng@33000 {
>> -                       compatible = "brcm,bcm-nsp-rng";
>> -                       reg = <0x33000 0x14>;
>
> You remove the rng node, is this intentional?
>
>> +               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 {
>> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
>> index 2d84226..ab7ba8f 100644
>> --- a/arch/arm/boot/dts/bcm958625k.dts
>> +++ b/arch/arm/boot/dts/bcm958625k.dts
>> @@ -126,3 +126,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>;
>> +               };
>
> these should be enclosed by a partitions node with compatible
> "fixed-partitions", see
> Documentation/devicetree/bindings/mtd/partition.txt.
>
>> +
>> +               partition@1 {
>
> The address is 0xa0000 so this should be partition@a0000.
>
>> +                       label = "env";
>> +                       reg = <0x000a0000 0x00060000>;
>> +               };
>> +
>> +               partition@2 {
>
> likewise.
>
>> +                       label = "system";
>> +                       reg = <0x00100000 0x00600000>;
>> +               };
>> +
>> +               partition@3 {
>
> etc.
>
>> +                       label = "rootfs";
>> +                       reg = <0x00700000 0x01900000>;
>> +               };
>> +       };
>> +};
>
>
> Regards
> Jonas
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support
@ 2016-08-02 19:51           ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-02 19:51 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: Mark Brown, linux-spi, MTD Maling List, vigneshr,
	Florian Fainelli, bcm-kernel-feedback-list, Vikram Prakash,
	Andy Fung, Jon Mason, Jayachandran C,
	Yendapally Reddy Dhananjaya Reddy

Jonas,

"You remove the rng node, is this intentional?"

Not intentional,  was a bad rebase merge to the latest sources, will
fix this in next version of the patch.

"The address is 0xa0000 so this should be partition@a0000.
 etc."

Will fix this as well.

Thanks
Kamal

On Mon, Aug 1, 2016 at 11:09 AM, Jonas Gorski <jonas.gorski@gmail.com> wrote:
> Hi,
>
> On 30 July 2016 at 00:13, Kamal Dasu <kdasu.kdev@gmail.com> wrote:
>> Adding qspi node compatible with the new spi-bcm-qspi
>> driver for the broadcom's northstar SoC.
>>
>> Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
>> Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
>> ---
>>  arch/arm/boot/dts/bcm-nsp.dtsi   | 33 +++++++++++++++++++++++++++++----
>>  arch/arm/boot/dts/bcm958625k.dts | 34 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 63 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
>> index 6a40ed7..26c863e 100644
>> --- a/arch/arm/boot/dts/bcm-nsp.dtsi
>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>> @@ -160,7 +160,7 @@
>>
>>         axi {
>>                 compatible = "simple-bus";
>> -               ranges = <0x00000000 0x18000000 0x0011ba08>;
>> +               ranges = <0x00000000 0x18000000 0x0011c40a>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>>
>> @@ -206,9 +206,34 @@
>>                         brcm,nand-has-wp;
>>                 };
>>
>> -               rng: rng@33000 {
>> -                       compatible = "brcm,bcm-nsp-rng";
>> -                       reg = <0x33000 0x14>;
>
> You remove the rng node, is this intentional?
>
>> +               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 {
>> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
>> index 2d84226..ab7ba8f 100644
>> --- a/arch/arm/boot/dts/bcm958625k.dts
>> +++ b/arch/arm/boot/dts/bcm958625k.dts
>> @@ -126,3 +126,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>;
>> +               };
>
> these should be enclosed by a partitions node with compatible
> "fixed-partitions", see
> Documentation/devicetree/bindings/mtd/partition.txt.
>
>> +
>> +               partition@1 {
>
> The address is 0xa0000 so this should be partition@a0000.
>
>> +                       label = "env";
>> +                       reg = <0x000a0000 0x00060000>;
>> +               };
>> +
>> +               partition@2 {
>
> likewise.
>
>> +                       label = "system";
>> +                       reg = <0x00100000 0x00600000>;
>> +               };
>> +
>> +               partition@3 {
>
> etc.
>
>> +                       label = "rootfs";
>> +                       reg = <0x00700000 0x01900000>;
>> +               };
>> +       };
>> +};
>
>
> Regards
> Jonas

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-04 21:06         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-04 21:06 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 460 bytes --]

On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
> Added device tree bindings documentation for SoCs supported by the
> new spi-bcm-qspi, spi-brcmstb-qspi driver.

Please submit patches using subject lines reflecting the style for the
subsystem.  This makes it easier for people to identify relevant
patches.  Look at what existing commits in the area you're changing are
doing and make sure your subject lines visually resemble what they're
doing.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-08-04 21:06         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-04 21:06 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 460 bytes --]

On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
> Added device tree bindings documentation for SoCs supported by the
> new spi-bcm-qspi, spi-brcmstb-qspi driver.

Please submit patches using subject lines reflecting the style for the
subsystem.  This makes it easier for people to identify relevant
patches.  Look at what existing commits in the area you're changing are
doing and make sure your subject lines visually resemble what they're
doing.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-04 21:07         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-04 21:07 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 510 bytes --]

On Fri, Jul 29, 2016 at 06:13:09PM -0400, Kamal Dasu wrote:
> 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.

You need to send this to the MTD maintainers, I see you've CCed the list
but not Brian and any comaintainers he has AFAICT.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
@ 2016-08-04 21:07         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-04 21:07 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 510 bytes --]

On Fri, Jul 29, 2016 at 06:13:09PM -0400, Kamal Dasu wrote:
> 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.

You need to send this to the MTD maintainers, I see you've CCed the list
but not Brian and any comaintainers he has AFAICT.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-08-04 21:06         ` Mark Brown
@ 2016-08-04 22:20             ` Florian Fainelli
  -1 siblings, 0 replies; 54+ messages in thread
From: Florian Fainelli @ 2016-08-04 22:20 UTC (permalink / raw)
  To: Mark Brown, Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

On 08/04/2016 02:06 PM, Mark Brown wrote:
> On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
>> Added device tree bindings documentation for SoCs supported by the
>> new spi-bcm-qspi, spi-brcmstb-qspi driver.
> 
> Please submit patches using subject lines reflecting the style for the
> subsystem.  This makes it easier for people to identify relevant
> patches.  Look at what existing commits in the area you're changing are
> doing and make sure your subject lines visually resemble what they're
> doing.

What's wrong with the subjects being used here? It's not like there is a
consistent subject for DT bindings, is spi/dt what you would expect here?

Can we save Kamal another round of patches and provide feedback on the
patch contents (as well as their form)?
-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-08-04 22:20             ` Florian Fainelli
  0 siblings, 0 replies; 54+ messages in thread
From: Florian Fainelli @ 2016-08-04 22:20 UTC (permalink / raw)
  To: Mark Brown, Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, bcm-kernel-feedback-list,
	vikram.prakash, andy.fung, jon.mason, jchandra

On 08/04/2016 02:06 PM, Mark Brown wrote:
> On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
>> Added device tree bindings documentation for SoCs supported by the
>> new spi-bcm-qspi, spi-brcmstb-qspi driver.
> 
> Please submit patches using subject lines reflecting the style for the
> subsystem.  This makes it easier for people to identify relevant
> patches.  Look at what existing commits in the area you're changing are
> doing and make sure your subject lines visually resemble what they're
> doing.

What's wrong with the subjects being used here? It's not like there is a
consistent subject for DT bindings, is spi/dt what you would expect here?

Can we save Kamal another round of patches and provide feedback on the
patch contents (as well as their form)?
-- 
Florian

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-08-04 22:20             ` Florian Fainelli
@ 2016-08-05 11:03                 ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-05 11:03 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Kamal Dasu, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 880 bytes --]

On Thu, Aug 04, 2016 at 03:20:17PM -0700, Florian Fainelli wrote:

> What's wrong with the subjects being used here? It's not like there is a
> consistent subject for DT bindings, is spi/dt what you would expect here?

As a quick look at the git log for the SPI DT bindings should show you
I'm looking for something in the same style as the drivers which at
least starts with "spi".  A *vanishingly* small number of them start
with Documentation which ought to be a bit of a warning sign.

> Can we save Kamal another round of patches and provide feedback on the
> patch contents (as well as their form)?

I will look at them when I have time, this is the result of the triage
where I work out if the patches are in some way relevant to me or I can
just delete them.  Please don't chase me for faster review unless
there's some strong reason, it tends to result in slower review.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-08-05 11:03                 ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-05 11:03 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Kamal Dasu, linux-spi, linux-mtd, vigneshr,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 880 bytes --]

On Thu, Aug 04, 2016 at 03:20:17PM -0700, Florian Fainelli wrote:

> What's wrong with the subjects being used here? It's not like there is a
> consistent subject for DT bindings, is spi/dt what you would expect here?

As a quick look at the git log for the SPI DT bindings should show you
I'm looking for something in the same style as the drivers which at
least starts with "spi".  A *vanishingly* small number of them start
with Documentation which ought to be a bit of a warning sign.

> Can we save Kamal another round of patches and provide feedback on the
> patch contents (as well as their form)?

I will look at them when I have time, this is the result of the triage
where I work out if the patches are in some way relevant to me or I can
just delete them.  Please don't chase me for faster review unless
there's some strong reason, it tends to result in slower review.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-16 18:15         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:15 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w,
	Yendapally Reddy Dhananjaya Reddy

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

On Fri, Jul 29, 2016 at 06:13:07PM -0400, Kamal Dasu wrote:

> +static int bcm_qspi_transfer_one(struct spi_master *master,

> +		if (qspi->next_udelay) {
> +			udelay(qspi->next_udelay);
> +			qspi->next_udelay = 0;
> +		}

Why is the driver manually implementing delays in a transfer_one()
function?  The core will add any required delays between transfers, this
will result in us delaying twice.

> +		read_from_hw(qspi, slots);
> +		if (qspi->cs_change) {
> +			usleep_range(10, 20);
> +			qspi->cs_change = 0;
> +		}

Similarly here, the core will do chip select changes.

> +	if (spi_transfer_is_last(master, trans))
> +		hw_stop(qspi);

The only thing I can see that looks like it might make a difference here
is this hw_stop() operation but all that does is update an internal
state machine so there's no limitation on it needing to be done before
the above operations that I can see.

> +	ret = clk_prepare_enable(qspi->clk);
> +	if (ret) {
> +		dev_err(dev, "failed to prepare clock\n");
> +		goto err2;

Please use named labels rather than numbered, it makes life a lot easier
if anything gets changed.

> +EXPORT_SYMBOL_GPL(bcm_qspi_probe);

This needs some explanation or to be added along with the user.

> diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
> new file mode 100644
> index 0000000..c7df92e
> --- /dev/null
> +++ b/drivers/spi/spi-brcmstb-qspi.c

This should really be a separate patch, it's a separate driver and very
surprising to find it here.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
@ 2016-08-16 18:15         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:15 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Yendapally Reddy Dhananjaya Reddy

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

On Fri, Jul 29, 2016 at 06:13:07PM -0400, Kamal Dasu wrote:

> +static int bcm_qspi_transfer_one(struct spi_master *master,

> +		if (qspi->next_udelay) {
> +			udelay(qspi->next_udelay);
> +			qspi->next_udelay = 0;
> +		}

Why is the driver manually implementing delays in a transfer_one()
function?  The core will add any required delays between transfers, this
will result in us delaying twice.

> +		read_from_hw(qspi, slots);
> +		if (qspi->cs_change) {
> +			usleep_range(10, 20);
> +			qspi->cs_change = 0;
> +		}

Similarly here, the core will do chip select changes.

> +	if (spi_transfer_is_last(master, trans))
> +		hw_stop(qspi);

The only thing I can see that looks like it might make a difference here
is this hw_stop() operation but all that does is update an internal
state machine so there's no limitation on it needing to be done before
the above operations that I can see.

> +	ret = clk_prepare_enable(qspi->clk);
> +	if (ret) {
> +		dev_err(dev, "failed to prepare clock\n");
> +		goto err2;

Please use named labels rather than numbered, it makes life a lot easier
if anything gets changed.

> +EXPORT_SYMBOL_GPL(bcm_qspi_probe);

This needs some explanation or to be added along with the user.

> diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
> new file mode 100644
> index 0000000..c7df92e
> --- /dev/null
> +++ b/drivers/spi/spi-brcmstb-qspi.c

This should really be a separate patch, it's a separate driver and very
surprising to find it here.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-16 18:19         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:19 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 389 bytes --]

On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
> Added device tree bindings documentation for SoCs supported by the
> new spi-bcm-qspi, spi-brcmstb-qspi driver.

This doesn't document the clock-frequency property the driver
implements.  However I'd recommend just dropping that since it appears
to duplicate the existing facilities for setting the bus speed per slave
device.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-08-16 18:19         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:19 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 389 bytes --]

On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
> Added device tree bindings documentation for SoCs supported by the
> new spi-bcm-qspi, spi-brcmstb-qspi driver.

This doesn't document the clock-frequency property the driver
implements.  However I'd recommend just dropping that since it appears
to duplicate the existing facilities for setting the bus speed per slave
device.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-16 18:31         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:31 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w,
	Yendapally Reddy Dhananjaya Reddy

[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]

On Fri, Jul 29, 2016 at 06:13:08PM -0400, Kamal Dasu wrote:

> +	bcm_qspi_bspi_lr_start(qspi);
> +	/* Must flush previous writes before starting BSPI operation */
> +	mb();
> +	if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {

The comment suggests that the memory barrier is misplaced or that
there's something missing?

> +		if (retry--)
> +			goto retry;

Please write loops using normal C looping constructs rather than goto
statements, it makes life a lot easier.  I'm not convinced that the loop
is safe as is with the completion reinitializaiton and so on, we should
at least be turning off the hardware before we reinitialize the
completion to avoid races with slow hardware.

> +	io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;

Normal if statements please.

> +static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
> +{
> +	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
> +	struct bcm_qspi *qspi = qspi_dev_id->dev;
> +
> +	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
> +		qspi_dev_id->irqp->mask);

I'd expect this to be dev_err() or something, but then the message
claims this an error status and it doesn't seem to actually read that
from the hardware.

> +#ifdef  QSPI_INT_DEBUG
> +	/* this interrupt is for debug purposes only, dont request irq */
> +	{
> +		.irq_name = "spi_lr_overread",
> +		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
> +		.mask = INTR_BSPI_LR_OVERREAD_MASK,
> +	},
> +#endif

Why not?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
@ 2016-08-16 18:31         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:31 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Yendapally Reddy Dhananjaya Reddy

[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]

On Fri, Jul 29, 2016 at 06:13:08PM -0400, Kamal Dasu wrote:

> +	bcm_qspi_bspi_lr_start(qspi);
> +	/* Must flush previous writes before starting BSPI operation */
> +	mb();
> +	if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {

The comment suggests that the memory barrier is misplaced or that
there's something missing?

> +		if (retry--)
> +			goto retry;

Please write loops using normal C looping constructs rather than goto
statements, it makes life a lot easier.  I'm not convinced that the loop
is safe as is with the completion reinitializaiton and so on, we should
at least be turning off the hardware before we reinitialize the
completion to avoid races with slow hardware.

> +	io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;

Normal if statements please.

> +static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
> +{
> +	struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
> +	struct bcm_qspi *qspi = qspi_dev_id->dev;
> +
> +	dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
> +		qspi_dev_id->irqp->mask);

I'd expect this to be dev_err() or something, but then the message
claims this an error status and it doesn't seem to actually read that
from the hardware.

> +#ifdef  QSPI_INT_DEBUG
> +	/* this interrupt is for debug purposes only, dont request irq */
> +	{
> +		.irq_name = "spi_lr_overread",
> +		.irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
> +		.mask = INTR_BSPI_LR_OVERREAD_MASK,
> +	},
> +#endif

Why not?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 5/8] Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-16 18:32         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:32 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

On Fri, Jul 29, 2016 at 06:13:10PM -0400, Kamal Dasu wrote:

>   BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
> -        for flash reads and be configured to do single, double, quad lane
> -        io with 3-byte and 4-byte addressing support.
> +	for flash reads and be configured to do single, double, quad lane
> +	io with 3-byte and 4-byte addressing support.

Please squash this and the other reindentation into the commit adding
the binding in the first place.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 5/8] Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings
@ 2016-08-16 18:32         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:32 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

On Fri, Jul 29, 2016 at 06:13:10PM -0400, Kamal Dasu wrote:

>   BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
> -        for flash reads and be configured to do single, double, quad lane
> -        io with 3-byte and 4-byte addressing support.
> +	for flash reads and be configured to do single, double, quad lane
> +	io with 3-byte and 4-byte addressing support.

Please squash this and the other reindentation into the commit adding
the binding in the first place.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
  2016-07-29 22:13     ` Kamal Dasu
@ 2016-08-16 18:40         ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:40 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w

[-- Attachment #1: Type: text/plain, Size: 772 bytes --]

On Fri, Jul 29, 2016 at 06:13:13PM -0400, Kamal Dasu wrote:

> -		irq = platform_get_irq_byname(pdev, name);
> +		if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
> +			/* all mspi, bspi intrs muxed to one L1 intr */
> +			irq = platform_get_irq(pdev, 0);
> +			of_property_read_string(dev->of_node,
> +						"interrupt-names",
> +						&name);
> +		}

I am confused why we are parsing the interrupt-names property here?

> +	/*
> +	 * Some SoCs integrate spi controller (e.g., its interrupt bits)
> +	 * in specific ways
> +	 */
> +	if (soc) {
> +		qspi->soc = soc;
> +		soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
> +	} else {
> +		qspi->soc = NULL;
> +	}

The variable name "soc" here doesn't seem hugely descriptive when it's
just for the interrupt controller.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
@ 2016-08-16 18:40         ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-16 18:40 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, linux-mtd, vigneshr, f.fainelli,
	bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra

[-- Attachment #1: Type: text/plain, Size: 772 bytes --]

On Fri, Jul 29, 2016 at 06:13:13PM -0400, Kamal Dasu wrote:

> -		irq = platform_get_irq_byname(pdev, name);
> +		if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
> +			/* all mspi, bspi intrs muxed to one L1 intr */
> +			irq = platform_get_irq(pdev, 0);
> +			of_property_read_string(dev->of_node,
> +						"interrupt-names",
> +						&name);
> +		}

I am confused why we are parsing the interrupt-names property here?

> +	/*
> +	 * Some SoCs integrate spi controller (e.g., its interrupt bits)
> +	 * in specific ways
> +	 */
> +	if (soc) {
> +		qspi->soc = soc;
> +		soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
> +	} else {
> +		qspi->soc = NULL;
> +	}

The variable name "soc" here doesn't seem hugely descriptive when it's
just for the interrupt controller.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
  2016-08-04 21:07         ` Mark Brown
@ 2016-08-19 14:59             ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 14:59 UTC (permalink / raw)
  To: Mark Brown, Brian Norris
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list

Adding Brian for this particular patch since its in the mtd domain. I
will specifically  add him as well in the next  patch set.  I do have
Vignesh in the list who added the spi_flash_read() in the list.

Kamal

On Thu, Aug 4, 2016 at 5:07 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:09PM -0400, Kamal Dasu wrote:
>> 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.
>
> You need to send this to the MTD maintainers, I see you've CCed the list
> but not Brian and any comaintainers he has AFAICT.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer
@ 2016-08-19 14:59             ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 14:59 UTC (permalink / raw)
  To: Mark Brown, Brian Norris
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list

Adding Brian for this particular patch since its in the mtd domain. I
will specifically  add him as well in the next  patch set.  I do have
Vignesh in the list who added the spi_flash_read() in the list.

Kamal

On Thu, Aug 4, 2016 at 5:07 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:09PM -0400, Kamal Dasu wrote:
>> 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.
>
> You need to send this to the MTD maintainers, I see you've CCed the list
> but not Brian and any comaintainers he has AFAICT.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-08-16 18:19         ` Mark Brown
@ 2016-08-19 15:07             ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:07 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list

On Tue, Aug 16, 2016 at 2:19 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
>> Added device tree bindings documentation for SoCs supported by the
>> new spi-bcm-qspi, spi-brcmstb-qspi driver.
>
> This doesn't document the clock-frequency property the driver
> implements.  However I'd recommend just dropping that since it appears
> to duplicate the existing facilities for setting the bus speed per slave
> device.

Will fix this and the subject for the patch.

Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-08-19 15:07             ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:07 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list

On Tue, Aug 16, 2016 at 2:19 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:06PM -0400, Kamal Dasu wrote:
>> Added device tree bindings documentation for SoCs supported by the
>> new spi-bcm-qspi, spi-brcmstb-qspi driver.
>
> This doesn't document the clock-frequency property the driver
> implements.  However I'd recommend just dropping that since it appears
> to duplicate the existing facilities for setting the bus speed per slave
> device.

Will fix this and the subject for the patch.

Kamal

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
  2016-08-16 18:15         ` Mark Brown
@ 2016-08-19 15:20             ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:20 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Yendapally Reddy Dhananjaya Reddy

On Tue, Aug 16, 2016 at 2:15 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:07PM -0400, Kamal Dasu wrote:
>
>> +static int bcm_qspi_transfer_one(struct spi_master *master,
>
>> +             if (qspi->next_udelay) {
>> +                     udelay(qspi->next_udelay);
>> +                     qspi->next_udelay = 0;
>> +             }
>
> Why is the driver manually implementing delays in a transfer_one()
> function?  The core will add any required delays between transfers, this
> will result in us delaying twice.
>
>> +             read_from_hw(qspi, slots);
>> +             if (qspi->cs_change) {
>> +                     usleep_range(10, 20);
>> +                     qspi->cs_change = 0;
>> +             }
>
> Similarly here, the core will do chip select changes.
>
>> +     if (spi_transfer_is_last(master, trans))
>> +             hw_stop(qspi);
>
> The only thing I can see that looks like it might make a difference here
> is this hw_stop() operation but all that does is update an internal
> state machine so there's no limitation on it needing to be done before
> the above operations that I can see.


I will cleanup  above 3 areas of redundant code.

>> +     ret = clk_prepare_enable(qspi->clk);
>> +     if (ret) {
>> +             dev_err(dev, "failed to prepare clock\n");
>> +             goto err2;
>
> Please use named labels rather than numbered, it makes life a lot easier
> if anything gets changed.
>

Ok will make this change as well

>> +EXPORT_SYMBOL_GPL(bcm_qspi_probe);
>
> This needs some explanation or to be added along with the user.
>

Will add appropriate comments for the user.

>> diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
>> new file mode 100644
>> index 0000000..c7df92e
>> --- /dev/null
>> +++ b/drivers/spi/spi-brcmstb-qspi.c
>
> This should really be a separate patch, it's a separate driver and very
> surprising to find it here.

Its very specific to the spi-block and hence is here, I will separate the patch,

Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver
@ 2016-08-19 15:20             ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:20 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Yendapally Reddy Dhananjaya Reddy

On Tue, Aug 16, 2016 at 2:15 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:07PM -0400, Kamal Dasu wrote:
>
>> +static int bcm_qspi_transfer_one(struct spi_master *master,
>
>> +             if (qspi->next_udelay) {
>> +                     udelay(qspi->next_udelay);
>> +                     qspi->next_udelay = 0;
>> +             }
>
> Why is the driver manually implementing delays in a transfer_one()
> function?  The core will add any required delays between transfers, this
> will result in us delaying twice.
>
>> +             read_from_hw(qspi, slots);
>> +             if (qspi->cs_change) {
>> +                     usleep_range(10, 20);
>> +                     qspi->cs_change = 0;
>> +             }
>
> Similarly here, the core will do chip select changes.
>
>> +     if (spi_transfer_is_last(master, trans))
>> +             hw_stop(qspi);
>
> The only thing I can see that looks like it might make a difference here
> is this hw_stop() operation but all that does is update an internal
> state machine so there's no limitation on it needing to be done before
> the above operations that I can see.


I will cleanup  above 3 areas of redundant code.

>> +     ret = clk_prepare_enable(qspi->clk);
>> +     if (ret) {
>> +             dev_err(dev, "failed to prepare clock\n");
>> +             goto err2;
>
> Please use named labels rather than numbered, it makes life a lot easier
> if anything gets changed.
>

Ok will make this change as well

>> +EXPORT_SYMBOL_GPL(bcm_qspi_probe);
>
> This needs some explanation or to be added along with the user.
>

Will add appropriate comments for the user.

>> diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c
>> new file mode 100644
>> index 0000000..c7df92e
>> --- /dev/null
>> +++ b/drivers/spi/spi-brcmstb-qspi.c
>
> This should really be a separate patch, it's a separate driver and very
> surprising to find it here.

Its very specific to the spi-block and hence is here, I will separate the patch,

Kamal

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
  2016-08-16 18:31         ` Mark Brown
@ 2016-08-19 15:33             ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:33 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Yendapally Reddy Dhananjaya Reddy

On Tue, Aug 16, 2016 at 2:31 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:08PM -0400, Kamal Dasu wrote:
>
>> +     bcm_qspi_bspi_lr_start(qspi);
>> +     /* Must flush previous writes before starting BSPI operation */
>> +     mb();
>> +     if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
>
> The comment suggests that the memory barrier is misplaced or that
> there's something missing?
>

Yes it got misplaced during refactoring the code. will move it to the
right place.

>> +             if (retry--)
>> +                     goto retry;
>
> Please write loops using normal C looping constructs rather than goto
> statements, it makes life a lot easier.  I'm not convinced that the loop
> is safe as is with the completion reinitializaiton and so on, we should
> at least be turning off the hardware before we reinitialize the
> completion to avoid races with slow hardware.
>

Actually will get rid of the retry logic.

>> +     io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
>
> Normal if statements please.
>

Ok will fix this.

>> +static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
>> +{
>> +     struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
>> +     struct bcm_qspi *qspi = qspi_dev_id->dev;
>> +
>> +     dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
>> +             qspi_dev_id->irqp->mask);
>
> I'd expect this to be dev_err() or something, but then the message
> claims this an error status and it doesn't seem to actually read that
> from the hardware.
>

Agreed will change this.

>> +#ifdef  QSPI_INT_DEBUG
>> +     /* this interrupt is for debug purposes only, dont request irq */
>> +     {
>> +             .irq_name = "spi_lr_overread",
>> +             .irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
>> +             .mask = INTR_BSPI_LR_OVERREAD_MASK,
>> +     },
>> +#endif
>
> Why not?

Is there in the HW block but will never get triggered,  will never get
triggered in the current driver. But kept it for completeness.

Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver
@ 2016-08-19 15:33             ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:33 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Yendapally Reddy Dhananjaya Reddy

On Tue, Aug 16, 2016 at 2:31 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:08PM -0400, Kamal Dasu wrote:
>
>> +     bcm_qspi_bspi_lr_start(qspi);
>> +     /* Must flush previous writes before starting BSPI operation */
>> +     mb();
>> +     if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) {
>
> The comment suggests that the memory barrier is misplaced or that
> there's something missing?
>

Yes it got misplaced during refactoring the code. will move it to the
right place.

>> +             if (retry--)
>> +                     goto retry;
>
> Please write loops using normal C looping constructs rather than goto
> statements, it makes life a lot easier.  I'm not convinced that the loop
> is safe as is with the completion reinitializaiton and so on, we should
> at least be turning off the hardware before we reinitialize the
> completion to avoid races with slow hardware.
>

Actually will get rid of the retry logic.

>> +     io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE;
>
> Normal if statements please.
>

Ok will fix this.

>> +static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
>> +{
>> +     struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
>> +     struct bcm_qspi *qspi = qspi_dev_id->dev;
>> +
>> +     dev_dbg(&qspi->pdev->dev, "BSPI INT error status %x\n",
>> +             qspi_dev_id->irqp->mask);
>
> I'd expect this to be dev_err() or something, but then the message
> claims this an error status and it doesn't seem to actually read that
> from the hardware.
>

Agreed will change this.

>> +#ifdef  QSPI_INT_DEBUG
>> +     /* this interrupt is for debug purposes only, dont request irq */
>> +     {
>> +             .irq_name = "spi_lr_overread",
>> +             .irq_handler = bcm_qspi_bspi_lr_err_l2_isr,
>> +             .mask = INTR_BSPI_LR_OVERREAD_MASK,
>> +     },
>> +#endif
>
> Why not?

Is there in the HW block but will never get triggered,  will never get
triggered in the current driver. But kept it for completeness.

Kamal

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
  2016-08-16 18:40         ` Mark Brown
@ 2016-08-19 15:43             ` Kamal Dasu
  -1 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list

On Tue, Aug 16, 2016 at 2:40 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:13PM -0400, Kamal Dasu wrote:
>
>> -             irq = platform_get_irq_byname(pdev, name);
>> +             if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
>> +                     /* all mspi, bspi intrs muxed to one L1 intr */
>> +                     irq = platform_get_irq(pdev, 0);
>> +                     of_property_read_string(dev->of_node,
>> +                                             "interrupt-names",
>> +                                             &name);
>> +             }
>
> I am confused why we are parsing the interrupt-names property here?
>

For Muxed L1 single source interrupt, there is only one irq, and  SoCs
could use a different different name wanted to use that name. But I
could force a name as well.

>> +     /*
>> +      * Some SoCs integrate spi controller (e.g., its interrupt bits)
>> +      * in specific ways
>> +      */
>> +     if (soc) {
>> +             qspi->soc = soc;
>> +             soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
>> +     } else {
>> +             qspi->soc = NULL;
>> +     }
>
> The variable name "soc" here doesn't seem hugely descriptive when it's
> just for the interrupt controller.

Named it that way since it could potentially have other SoC specific
settings for spi master bus needed in future.

Kamal
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
@ 2016-08-19 15:43             ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-08-19 15:43 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list

On Tue, Aug 16, 2016 at 2:40 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Jul 29, 2016 at 06:13:13PM -0400, Kamal Dasu wrote:
>
>> -             irq = platform_get_irq_byname(pdev, name);
>> +             if (soc && qspi_irq_tab[val].irq_source == MUXED_L1) {
>> +                     /* all mspi, bspi intrs muxed to one L1 intr */
>> +                     irq = platform_get_irq(pdev, 0);
>> +                     of_property_read_string(dev->of_node,
>> +                                             "interrupt-names",
>> +                                             &name);
>> +             }
>
> I am confused why we are parsing the interrupt-names property here?
>

For Muxed L1 single source interrupt, there is only one irq, and  SoCs
could use a different different name wanted to use that name. But I
could force a name as well.

>> +     /*
>> +      * Some SoCs integrate spi controller (e.g., its interrupt bits)
>> +      * in specific ways
>> +      */
>> +     if (soc) {
>> +             qspi->soc = soc;
>> +             soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
>> +     } else {
>> +             qspi->soc = NULL;
>> +     }
>
> The variable name "soc" here doesn't seem hugely descriptive when it's
> just for the interrupt controller.

Named it that way since it could potentially have other SoC specific
settings for spi master bus needed in future.

Kamal

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
  2016-08-19 15:43             ` Kamal Dasu
@ 2016-08-19 16:42                 ` Mark Brown
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-19 16:42 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, MTD Maling List,
	vigneshr-l0cyMroinI0, Florian Fainelli,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C
	<jchandra-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>,
	bcm-kernel-feedback-list

[-- Attachment #1: Type: text/plain, Size: 1230 bytes --]

On Fri, Aug 19, 2016 at 11:43:24AM -0400, Kamal Dasu wrote:
> On Tue, Aug 16, 2016 at 2:40 PM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

> > I am confused why we are parsing the interrupt-names property here?

> For Muxed L1 single source interrupt, there is only one irq, and  SoCs
> could use a different different name wanted to use that name. But I
> could force a name as well.

Either don't use names or force a name, trying to mix the two is just
messy.

> >> +     /*
> >> +      * Some SoCs integrate spi controller (e.g., its interrupt bits)
> >> +      * in specific ways
> >> +      */
> >> +     if (soc) {
> >> +             qspi->soc = soc;
> >> +             soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
> >> +     } else {
> >> +             qspi->soc = NULL;
> >> +     }

> > The variable name "soc" here doesn't seem hugely descriptive when it's
> > just for the interrupt controller.

> Named it that way since it could potentially have other SoC specific
> settings for spi master bus needed in future.

But then that'll break this code - if it's going to be a feature flag
bitmask or something like that it should have an appropriate name and be
used in a way that reflects this.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus SoC support
@ 2016-08-19 16:42                 ` Mark Brown
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Brown @ 2016-08-19 16:42 UTC (permalink / raw)
  To: Kamal Dasu
  Cc: linux-spi, MTD Maling List, vigneshr, Florian Fainelli,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list, Vikram Prakash, Andy Fung, Jon Mason,
	Jayachandran C <jchandra@broadcom.com>,
	bcm-kernel-feedback-list

[-- Attachment #1: Type: text/plain, Size: 1201 bytes --]

On Fri, Aug 19, 2016 at 11:43:24AM -0400, Kamal Dasu wrote:
> On Tue, Aug 16, 2016 at 2:40 PM, Mark Brown <broonie@kernel.org> wrote:

> > I am confused why we are parsing the interrupt-names property here?

> For Muxed L1 single source interrupt, there is only one irq, and  SoCs
> could use a different different name wanted to use that name. But I
> could force a name as well.

Either don't use names or force a name, trying to mix the two is just
messy.

> >> +     /*
> >> +      * Some SoCs integrate spi controller (e.g., its interrupt bits)
> >> +      * in specific ways
> >> +      */
> >> +     if (soc) {
> >> +             qspi->soc = soc;
> >> +             soc->bcm_qspi_int_set(soc, MSPI_DONE, true);
> >> +     } else {
> >> +             qspi->soc = NULL;
> >> +     }

> > The variable name "soc" here doesn't seem hugely descriptive when it's
> > just for the interrupt controller.

> Named it that way since it could potentially have other SoC specific
> settings for spi master bus needed in future.

But then that'll break this code - if it's going to be a feature flag
bitmask or something like that it should have an appropriate name and be
used in a way that reflects this.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
  2016-07-29 22:12 [PATCH v5 0/8] Broadcom stb, nsp, ns2, cygnus QSPI driver Kamal Dasu
@ 2016-07-29 22:12     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:12 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, vigneshr-l0cyMroinI0,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w
  Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	vikram.prakash-dY08KVG/lbpWk0Htik3J/w,
	andy.fung-dY08KVG/lbpWk0Htik3J/w,
	jon.mason-dY08KVG/lbpWk0Htik3J/w,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Kamal Dasu

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

Signed-off-by: Kamal Dasu <kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 145 +++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
new file mode 100644
index 0000000..bbae763
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -0,0 +1,145 @@
+Broadcom SPI controller
+
+The Broadcom SPI controller is a SPI master found on various SOCs, including
+BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
+of :
+ MSPI : SPI master controller can read and write to a SPI slave device
+ BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
+        for flash reads and be configured to do single, double, quad lane
+        io with 3-byte and 4-byte addressing support.
+
+ Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
+ MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
+ of a MSPI master without the BSPI to use with non flash slave devices that
+ use SPI protocol.
+
+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-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
+						   BRCMSTB  SoCs
+
+- reg:
+    Define the bases and ranges of the associated I/O address spaces.
+    The required range is MSPI controller registers.
+
+- 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, not required with compatible
+                   "spi-brcmstb-mspi"
+    - "mspi_regs": MSPI register range is required for compatible strings
+
+- interrupts
+    The interrupts used by the MSPI and/or BSPI controller.
+
+- interrupt-names:
+    Names of interrupts associated with MSPI
+    - "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
+
+- clocks:
+    A phandle to the reference clock for this block.
+
+Optional properties:
+
+
+- native-endian
+    Defined when using BE SoC and device uses BE register read/write
+
+Recommended optional m25p80 properties:
+- spi-rx-bus-width: Definition as per
+                    Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Examples:
+
+BRCMSTB SoC Example:
+
+  SPI Master (MSPI+BSPI) for SPI-NOR access:
+
+    spi@f03e3400 {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-qspi";
+		reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>;
+		reg-names = "cs_reg", "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 = <&hif_spi>;
+		clock-names = "sw_spi";
+
+		m25p80@0 {
+			#size-cells = <0x2>;
+			#address-cells = <0x2>;
+			compatible = "m25p80";
+			reg = <0x0>;
+			spi-max-frequency = <0x2625a00>;
+			spi-cpol;
+			spi-cpha;
+			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 for any SPI device :
+
+	spi@f0416000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&upg_fixed>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-mspi";
+		reg = <0xf0416000 0x180>;
+		reg-names = "mspi";
+		interrupts = <0x14>;
+		interrupt-parent = <&irq0_aon_intc>;
+		interrupt-names = "mspi_done";
+	};
+
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings
@ 2016-07-29 22:12     ` Kamal Dasu
  0 siblings, 0 replies; 54+ messages in thread
From: Kamal Dasu @ 2016-07-29 22:12 UTC (permalink / raw)
  To: broonie, linux-spi, linux-mtd, vigneshr, f.fainelli
  Cc: bcm-kernel-feedback-list, vikram.prakash, andy.fung, jon.mason,
	jchandra, Kamal Dasu

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

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
---
 .../devicetree/bindings/spi/brcm,spi-bcm-qspi.txt  | 145 +++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt

diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
new file mode 100644
index 0000000..bbae763
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt
@@ -0,0 +1,145 @@
+Broadcom SPI controller
+
+The Broadcom SPI controller is a SPI master found on various SOCs, including
+BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits
+of :
+ MSPI : SPI master controller can read and write to a SPI slave device
+ BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration
+        for flash reads and be configured to do single, double, quad lane
+        io with 3-byte and 4-byte addressing support.
+
+ Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP.
+ MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance
+ of a MSPI master without the BSPI to use with non flash slave devices that
+ use SPI protocol.
+
+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-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs
+    "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI
+						   BRCMSTB  SoCs
+
+- reg:
+    Define the bases and ranges of the associated I/O address spaces.
+    The required range is MSPI controller registers.
+
+- 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, not required with compatible
+                   "spi-brcmstb-mspi"
+    - "mspi_regs": MSPI register range is required for compatible strings
+
+- interrupts
+    The interrupts used by the MSPI and/or BSPI controller.
+
+- interrupt-names:
+    Names of interrupts associated with MSPI
+    - "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
+
+- clocks:
+    A phandle to the reference clock for this block.
+
+Optional properties:
+
+
+- native-endian
+    Defined when using BE SoC and device uses BE register read/write
+
+Recommended optional m25p80 properties:
+- spi-rx-bus-width: Definition as per
+                    Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Examples:
+
+BRCMSTB SoC Example:
+
+  SPI Master (MSPI+BSPI) for SPI-NOR access:
+
+    spi@f03e3400 {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-qspi";
+		reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>;
+		reg-names = "cs_reg", "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 = <&hif_spi>;
+		clock-names = "sw_spi";
+
+		m25p80@0 {
+			#size-cells = <0x2>;
+			#address-cells = <0x2>;
+			compatible = "m25p80";
+			reg = <0x0>;
+			spi-max-frequency = <0x2625a00>;
+			spi-cpol;
+			spi-cpha;
+			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 for any SPI device :
+
+	spi@f0416000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&upg_fixed>;
+		compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-mspi";
+		reg = <0xf0416000 0x180>;
+		reg-names = "mspi";
+		interrupts = <0x14>;
+		interrupt-parent = <&irq0_aon_intc>;
+		interrupt-names = "mspi_done";
+	};
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2016-08-19 16:43 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-29 22:13 [PATCH v5 0/8] Broadcom stb, nsp, ns2, cygnus QSPI driver Kamal Dasu
2016-07-29 22:13 ` Kamal Dasu
     [not found] ` <1469830393-13295-1-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-07-29 22:13   ` [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-2-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-04 21:06       ` Mark Brown
2016-08-04 21:06         ` Mark Brown
     [not found]         ` <20160804210634.GM10383-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-04 22:20           ` Florian Fainelli
2016-08-04 22:20             ` Florian Fainelli
     [not found]             ` <1fddf72d-cbc1-225f-b482-d6ba99dab823-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-05 11:03               ` Mark Brown
2016-08-05 11:03                 ` Mark Brown
2016-08-16 18:19       ` Mark Brown
2016-08-16 18:19         ` Mark Brown
     [not found]         ` <20160816181944.GY9347-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-19 15:07           ` Kamal Dasu
2016-08-19 15:07             ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 2/8] spi: bcm-qspi: Add Broadcom MSPI driver Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-3-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-16 18:15       ` Mark Brown
2016-08-16 18:15         ` Mark Brown
     [not found]         ` <20160816181536.GX9347-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-19 15:20           ` Kamal Dasu
2016-08-19 15:20             ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 3/8] spi: bcm-qspi: Add BSPI spi-nor flash controller driver Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-4-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-16 18:31       ` Mark Brown
2016-08-16 18:31         ` Mark Brown
     [not found]         ` <20160816183148.GZ9347-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-19 15:33           ` Kamal Dasu
2016-08-19 15:33             ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 4/8] mtd: m25p80: Let m25p80_read() fallback to spi transfer Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-5-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-04 21:07       ` Mark Brown
2016-08-04 21:07         ` Mark Brown
     [not found]         ` <20160804210747.GN10383-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-19 14:59           ` Kamal Dasu
2016-08-19 14:59             ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 5/8] Documentation: dt: spi: Add Broadcom NSP, NS2 SoC bindings Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-6-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-16 18:32       ` Mark Brown
2016-08-16 18:32         ` Mark Brown
2016-07-29 22:13   ` [PATCH v5 6/8] arm: dts: Add bcm-nsp and bcm958625k support Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
2016-08-01 15:09     ` Jonas Gorski
2016-08-01 15:09       ` Jonas Gorski
     [not found]       ` <CAOiHx=n8a64d-2LGGFHuyBQBg3Cz=ALVXEbvPRHxTyzFjWRMXA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-02 19:51         ` Kamal Dasu
2016-08-02 19:51           ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 7/8] arm64: dts: Add ns2 SoC support Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
2016-07-29 22:13   ` [PATCH v5 8/8] spi: nsp-qspi: Add Broadcom NSP, NS2, Cygnus " Kamal Dasu
2016-07-29 22:13     ` Kamal Dasu
     [not found]     ` <1469830393-13295-9-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-08-16 18:40       ` Mark Brown
2016-08-16 18:40         ` Mark Brown
     [not found]         ` <20160816184030.GB9347-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-08-19 15:43           ` Kamal Dasu
2016-08-19 15:43             ` Kamal Dasu
     [not found]             ` <CAC=U0a31LOphD=21-tBtiCxN-JqxSArxqhQ4_=fXwH-vEKnbHA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-19 16:42               ` Mark Brown
2016-08-19 16:42                 ` Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2016-07-29 22:12 [PATCH v5 0/8] Broadcom stb, nsp, ns2, cygnus QSPI driver Kamal Dasu
     [not found] ` <1469830341-13244-1-git-send-email-kdasu.kdev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-07-29 22:12   ` [PATCH v5 1/8] Documentation: dt: spi: Add BRCMSTB SoC bindings Kamal Dasu
2016-07-29 22:12     ` Kamal Dasu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.