浏览代码

Merge git://git.denx.de/u-boot-spi

Tom Rini 7 年之前
父节点
当前提交
1d12a7c8cd
共有 79 个文件被更改,包括 1616 次插入519 次删除
  1. 37 38
      arch/arm/dts/keystone-k2g-evm.dts
  2. 3 2
      arch/arm/dts/keystone-k2g.dtsi
  3. 3 2
      arch/arm/dts/socfpga.dtsi
  4. 2 2
      arch/arm/dts/socfpga_arria10.dtsi
  5. 4 5
      arch/arm/dts/socfpga_arria5_socdk.dts
  6. 4 5
      arch/arm/dts/socfpga_cyclone5_is1.dts
  7. 4 5
      arch/arm/dts/socfpga_cyclone5_socdk.dts
  8. 4 5
      arch/arm/dts/socfpga_cyclone5_sockit.dts
  9. 4 5
      arch/arm/dts/socfpga_cyclone5_socrates.dts
  10. 4 5
      arch/arm/dts/socfpga_cyclone5_sr1500.dts
  11. 8 10
      arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
  12. 7 5
      arch/arm/dts/stv0991.dts
  13. 6 0
      arch/arm/include/asm/arch-mvebu/spi.h
  14. 11 11
      arch/arm/mach-imx/mx6/ddr.c
  15. 2 2
      arch/arm/mach-socfpga/clock_manager.c
  16. 9 0
      arch/arm/mach-socfpga/clock_manager_arria10.c
  17. 11 4
      arch/arm/mach-socfpga/clock_manager_gen5.c
  18. 18 18
      arch/arm/mach-socfpga/reset_manager_arria10.c
  19. 17 0
      arch/mips/dts/brcm,bcm3380.dtsi
  20. 38 0
      arch/mips/dts/brcm,bcm63268.dtsi
  21. 24 0
      arch/mips/dts/brcm,bcm6328.dtsi
  22. 17 0
      arch/mips/dts/brcm,bcm6338.dtsi
  23. 17 0
      arch/mips/dts/brcm,bcm6348.dtsi
  24. 17 0
      arch/mips/dts/brcm,bcm6358.dtsi
  25. 12 0
      arch/mips/dts/comtrend,ar-5387un.dts
  26. 12 0
      arch/mips/dts/netgear,cg3100d.dts
  27. 12 0
      arch/mips/dts/sagem,f@st1704.dts
  28. 1 1
      arch/mips/mach-ath79/ar934x/clk.c
  29. 2 2
      board/samtec/vining_2000/vining_2000.c
  30. 8 0
      configs/comtrend_ar5387un_ram_defconfig
  31. 8 0
      configs/netgear_cg3100d_ram_defconfig
  32. 8 0
      configs/sagem_f@st1704_ram_defconfig
  33. 14 10
      doc/device-tree-bindings/spi/soft-spi.txt
  34. 8 5
      doc/device-tree-bindings/spi/spi-cadence.txt
  35. 6 6
      drivers/clk/clk_pic32.c
  36. 2 2
      drivers/clk/renesas/clk-rcar-gen3.c
  37. 4 4
      drivers/ddr/microchip/ddr2.c
  38. 7 10
      drivers/fpga/socfpga_arria10.c
  39. 4 4
      drivers/mmc/msm_sdhci.c
  40. 2 2
      drivers/mtd/pic32_flash.c
  41. 8 26
      drivers/mtd/spi/sf_probe.c
  42. 4 1
      drivers/mtd/spi/spi_flash.c
  43. 8 8
      drivers/net/ag7xxx.c
  44. 9 8
      drivers/net/dwc_eth_qos.c
  45. 4 4
      drivers/net/ethoc.c
  46. 6 6
      drivers/net/pic32_eth.c
  47. 14 14
      drivers/net/pic32_mdio.c
  48. 2 2
      drivers/net/ravb.c
  49. 2 2
      drivers/net/xilinx_axi_emac.c
  50. 6 6
      drivers/net/zynq_gem.c
  51. 2 2
      drivers/reset/sti-reset.c
  52. 2 2
      drivers/serial/serial_pic32.c
  53. 16 0
      drivers/spi/Kconfig
  54. 2 0
      drivers/spi/Makefile
  55. 2 2
      drivers/spi/atmel_spi.c
  56. 414 0
      drivers/spi/bcm63xx_hsspi.c
  57. 433 0
      drivers/spi/bcm63xx_spi.c
  58. 12 8
      drivers/spi/cadence_qspi.c
  59. 5 1
      drivers/spi/cadence_qspi.h
  60. 37 45
      drivers/spi/cadence_qspi_apb.c
  61. 43 2
      drivers/spi/designware_spi.c
  62. 10 10
      drivers/spi/fsl_qspi.c
  63. 66 3
      drivers/spi/kirkwood_spi.c
  64. 11 9
      drivers/spi/mvebu_a3700_spi.c
  65. 2 19
      drivers/spi/spi-uclass.c
  66. 4 23
      drivers/spi/spi.c
  67. 12 12
      drivers/usb/host/dwc2.c
  68. 1 2
      drivers/usb/host/ehci-msm.c
  69. 2 3
      drivers/usb/host/ehci-mx6.c
  70. 6 6
      drivers/usb/host/ohci-lpc32xx.c
  71. 6 6
      drivers/usb/host/xhci-rcar.c
  72. 32 32
      drivers/video/atmel_hlcdfb.c
  73. 0 2
      include/configs/k2g_evm.h
  74. 0 2
      include/configs/socfpga_common.h
  75. 0 2
      include/configs/stv0991.h
  76. 4 28
      include/spi.h
  77. 0 12
      include/spi_flash.h
  78. 48 37
      include/wait_bit.h
  79. 0 2
      scripts/config_whitelist.txt

+ 37 - 38
arch/arm/dts/keystone-k2g-evm.dts

@@ -68,46 +68,45 @@
 &qspi {
 	status = "okay";
 
-        flash0: m25p80@0 {
-                compatible = "s25fl512s","spi-flash";
-                reg = <0>;
-                spi-tx-bus-width = <1>;
-                spi-rx-bus-width = <4>;
-                spi-max-frequency = <96000000>;
-                #address-cells = <1>;
-                #size-cells = <1>;
-                tshsl-ns = <392>;
-                tsd2d-ns = <392>;
-                tchsh-ns = <100>;
-                tslch-ns = <100>;
+	flash0: m25p80@0 {
+		compatible = "s25fl512s","spi-flash";
+		reg = <0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <96000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		cdns,tshsl-ns = <392>;
+		cdns,tsd2d-ns = <392>;
+		cdns,tchsh-ns = <100>;
+		cdns,tslch-ns = <100>;
 		block-size = <18>;
 
-
-                partition@0 {
-                        label = "QSPI.u-boot-spl-os";
-                        reg = <0x00000000 0x00100000>;
-                };
-                partition@1 {
-                        label = "QSPI.u-boot-env";
-                        reg = <0x00100000 0x00040000>;
-                };
-                partition@2 {
-                        label = "QSPI.skern";
-                        reg = <0x00140000 0x0040000>;
-                };
-                partition@3 {
-                        label = "QSPI.pmmc-firmware";
-                        reg = <0x00180000 0x0040000>;
-                };
-                partition@4 {
-                        label = "QSPI.kernel";
-                        reg = <0x001C0000 0x0800000>;
-                };
-                partition@5 {
-                        label = "QSPI.file-system";
-                        reg = <0x009C0000 0x3640000>;
-                };
-        };
+		partition@0 {
+			label = "QSPI.u-boot-spl-os";
+			reg = <0x00000000 0x00100000>;
+		};
+		partition@1 {
+			label = "QSPI.u-boot-env";
+			reg = <0x00100000 0x00040000>;
+		};
+		partition@2 {
+			label = "QSPI.skern";
+			reg = <0x00140000 0x0040000>;
+		};
+		partition@3 {
+			label = "QSPI.pmmc-firmware";
+			reg = <0x00180000 0x0040000>;
+		};
+		partition@4 {
+			label = "QSPI.kernel";
+			reg = <0x001C0000 0x0800000>;
+		};
+		partition@5 {
+			label = "QSPI.file-system";
+			reg = <0x009C0000 0x3640000>;
+		};
+	};
 };
 
 &mmc0 {

+ 3 - 2
arch/arm/dts/keystone-k2g.dtsi

@@ -92,8 +92,9 @@
 			      <0x24000000 0x4000000>;
 			interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>;
 			num-cs = <4>;
-			fifo-depth = <256>;
-			sram-size = <256>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x24000000>;
 			status = "disabled";
 		};
 

+ 3 - 2
arch/arm/dts/socfpga.dtsi

@@ -644,8 +644,9 @@
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
 			num-cs = <4>;
-			fifo-depth = <128>;
-			sram-size = <128>;
+			cdns,fifo-depth = <128>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x00000000>;
 			bus-num = <2>;
 			status = "disabled";
 		};

+ 2 - 2
arch/arm/dts/socfpga_arria10.dtsi

@@ -734,8 +734,8 @@
 			clocks = <&l4_main_clk>;
 			ext-decoder = <0>;  /* external decoder */
 			num-chipselect = <4>;
-			fifo-depth = <128>;
-			sram-size = <512>;
+			cdns,fifo-depth = <128>;
+			cdns,fifo-width = <4>;
 			bus-num = <2>;
 			status = "disabled";
 		};

+ 4 - 5
arch/arm/dts/socfpga_arria5_socdk.dts

@@ -94,10 +94,9 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };

+ 4 - 5
arch/arm/dts/socfpga_cyclone5_is1.dts

@@ -93,11 +93,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };
 

+ 4 - 5
arch/arm/dts/socfpga_cyclone5_socdk.dts

@@ -104,11 +104,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };
 

+ 4 - 5
arch/arm/dts/socfpga_cyclone5_sockit.dts

@@ -84,11 +84,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };
 

+ 4 - 5
arch/arm/dts/socfpga_cyclone5_socrates.dts

@@ -74,11 +74,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };
 

+ 4 - 5
arch/arm/dts/socfpga_cyclone5_sr1500.dts

@@ -92,10 +92,9 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };

+ 8 - 10
arch/arm/dts/socfpga_cyclone5_vining_fpga.dts

@@ -79,11 +79,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 
 	flash1: n25q00@1 {
@@ -96,11 +95,10 @@
 		m25p,fast-read;
 		page-size = <256>;
 		block-size = <16>; /* 2^16, 64KB */
-		read-delay = <4>;  /* delay value in read data capture register */
-		tshsl-ns = <50>;
-		tsd2d-ns = <50>;
-		tchsh-ns = <4>;
-		tslch-ns = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
 	};
 };
 

+ 7 - 5
arch/arm/dts/stv0991.dts

@@ -32,7 +32,9 @@
 			reg = <0x80203000 0x100>,
 				<0x40000000 0x1000000>;
 			clocks = <3750000>;
-			sram-size = <256>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x40000000>;
 			status = "okay";
 
 			flash0: n25q32@0 {
@@ -44,10 +46,10 @@
 				m25p,fast-read;
 				page-size = <256>;
 				block-size = <16>; 	/* 2^16, 64KB */
-				tshsl-ns = <50>;
-				tsd2d-ns = <50>;
-				tchsh-ns = <4>;
-				tslch-ns = <4>;
+				cdns,tshsl-ns = <50>;
+				cdns,tsd2d-ns = <50>;
+				cdns,tchsh-ns = <4>;
+				cdns,tslch-ns = <4>;
 			};
 	};
 };

+ 6 - 0
arch/arm/include/asm/arch-mvebu/spi.h

@@ -57,6 +57,12 @@ struct kwspi_registers {
 #define KWSPI_TXLSBF		(1 << 13)
 #define KWSPI_RXLSBF		(1 << 14)
 
+/* Timing Parameters 1 Register */
+#define KW_SPI_TMISO_SAMPLE_OFFSET	6
+#define KW_SPI_TMISO_SAMPLE_MASK	(0x3 << KW_SPI_TMISO_SAMPLE_OFFSET)
+#define KW_SPI_TMISO_SAMPLE_1		(1 << KW_SPI_TMISO_SAMPLE_OFFSET)
+#define KW_SPI_TMISO_SAMPLE_2		(2 << KW_SPI_TMISO_SAMPLE_OFFSET)
+
 #define KWSPI_IRQUNMASK		1 /* unmask SPI interrupt */
 #define KWSPI_IRQMASK		0 /* mask SPI interrupt */
 #define KWSPI_SMEMRDIRQ		1 /* SerMem data xfer ready irq */

+ 11 - 11
arch/arm/mach-imx/mx6/ddr.c

@@ -21,10 +21,10 @@ static void reset_read_data_fifos(void)
 
 	/* Reset data FIFOs twice. */
 	setbits_le32(&mmdc0->mpdgctrl0, 1 << 31);
-	wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
 
 	setbits_le32(&mmdc0->mpdgctrl0, 1 << 31);
-	wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0);
 }
 
 static void precharge_all(const bool cs0_enable, const bool cs1_enable)
@@ -39,12 +39,12 @@ static void precharge_all(const bool cs0_enable, const bool cs1_enable)
 	 */
 	if (cs0_enable) { /* CS0 */
 		writel(0x04008050, &mmdc0->mdscr);
-		wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+		wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
 	}
 
 	if (cs1_enable) { /* CS1 */
 		writel(0x04008058, &mmdc0->mdscr);
-		wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+		wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
 	}
 }
 
@@ -146,7 +146,7 @@ int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	 * 7. Upon completion of this process the MMDC de-asserts
 	 * the MPWLGCR[HW_WL_EN]
 	 */
-	wait_for_bit("MMDC", &mmdc0->mpwlgcr, 1 << 0, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpwlgcr, 1 << 0, 0, 100, 0);
 
 	/*
 	 * 8. check for any errors: check both PHYs for x64 configuration,
@@ -278,7 +278,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 		writel(0x00008028, &mmdc0->mdscr);
 
 	/* poll to make sure the con_ack bit was asserted */
-	wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0);
+	wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 1, 100, 0);
 
 	/*
 	 * Check MDMISC register CALIB_PER_CS to see which CS calibration
@@ -312,7 +312,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	 * this bit until it clears to indicate completion of the write access.
 	 */
 	setbits_le32(&mmdc0->mpswdar0, 1);
-	wait_for_bit("MMDC", &mmdc0->mpswdar0, 1 << 0, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpswdar0, 1 << 0, 0, 100, 0);
 
 	/* Set the RD_DL_ABS# bits to their default values
 	 * (will be calibrated later in the read delay-line calibration).
@@ -359,7 +359,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	setbits_le32(&mmdc0->mpdgctrl0, 5 << 28);
 
 	/* Poll for completion.  MPDGCTRL0[HW_DG_EN] should be 0 */
-	wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 28, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpdgctrl0, 1 << 28, 0, 100, 0);
 
 	/*
 	 * Check to see if any errors were encountered during calibration
@@ -423,7 +423,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	 * setting MPRDDLHWCTL[HW_RD_DL_EN] = 0.   Also, ensure that
 	 * no error bits were set.
 	 */
-	wait_for_bit("MMDC", &mmdc0->mprddlhwctl, 1 << 4, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mprddlhwctl, 1 << 4, 0, 100, 0);
 
 	/* check both PHYs for x64 configuration, if x32, check only PHY0 */
 	if (readl(&mmdc0->mprddlhwctl) & 0x0000000f)
@@ -477,7 +477,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	 * by setting MPWRDLHWCTL[HW_WR_DL_EN] = 0.
 	 * Also, ensure that no error bits were set.
 	 */
-	wait_for_bit("MMDC", &mmdc0->mpwrdlhwctl, 1 << 4, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mpwrdlhwctl, 1 << 4, 0, 100, 0);
 
 	/* Check both PHYs for x64 configuration, if x32, check only PHY0 */
 	if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f)
@@ -526,7 +526,7 @@ int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 	writel(0x0, &mmdc0->mdscr);	/* CS0 */
 
 	/* Poll to make sure the con_ack bit is clear */
-	wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 0, 100, 0);
+	wait_for_bit_le32(&mmdc0->mdscr, 1 << 14, 0, 100, 0);
 
 	/*
 	 * Print out the registers that were updated as a result

+ 2 - 2
arch/arm/mach-socfpga/clock_manager.c

@@ -37,8 +37,8 @@ void cm_wait_for_lock(u32 mask)
 /* function to poll in the fsm busy bit */
 int cm_wait_for_fsm(void)
 {
-	return wait_for_bit(__func__, (const u32 *)&clock_manager_base->stat,
-			    CLKMGR_STAT_BUSY, false, 20000, false);
+	return wait_for_bit_le32(&clock_manager_base->stat,
+				 CLKMGR_STAT_BUSY, false, 20000, false);
 }
 
 int set_cpu_clk_info(void)

+ 9 - 0
arch/arm/mach-socfpga/clock_manager_arria10.c

@@ -7,6 +7,7 @@
 #include <common.h>
 #include <fdtdec.h>
 #include <asm/io.h>
+#include <dm.h>
 #include <asm/arch/clock_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -1076,6 +1077,14 @@ unsigned int cm_get_qspi_controller_clk_hz(void)
 	return  cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
 }
 
+/* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
+int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+	*rate = cm_get_spi_controller_clk_hz();
+
+	return 0;
+}
+
 void cm_print_clock_quick_summary(void)
 {
 	printf("MPU       %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);

+ 11 - 4
arch/arm/mach-socfpga/clock_manager_gen5.c

@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <dm.h>
 #include <asm/arch/clock_manager.h>
 #include <wait_bit.h>
 
@@ -37,15 +38,13 @@ static int cm_write_with_phase(u32 value, u32 reg_address, u32 mask)
 	int ret;
 
 	/* poll until phase is zero */
-	ret = wait_for_bit(__func__, (const u32 *)reg_address, mask,
-			   false, 20000, false);
+	ret = wait_for_bit_le32(reg_address, mask, false, 20000, false);
 	if (ret)
 		return ret;
 
 	writel(value, reg_address);
 
-	return wait_for_bit(__func__, (const u32 *)reg_address, mask,
-			    false, 20000, false);
+	return wait_for_bit_le32(reg_address, mask, false, 20000, false);
 }
 
 /*
@@ -509,6 +508,14 @@ unsigned int cm_get_spi_controller_clk_hz(void)
 	return clock;
 }
 
+/* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
+int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+	*rate = cm_get_spi_controller_clk_hz();
+
+	return 0;
+}
+
 void cm_print_clock_quick_summary(void)
 {
 	printf("MPU       %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);

+ 18 - 18
arch/arm/mach-socfpga/reset_manager_arria10.c

@@ -222,8 +222,8 @@ int socfpga_reset_deassert_bridges_handoff(void)
 	clrbits_le32(&reset_manager_base->brgmodrst, mask_rstmgr);
 
 	/* Poll until all idleack to 0, timeout at 1000ms */
-	return wait_for_bit(__func__, &sysmgr_regs->noc_idleack, mask_noc,
-			    false, 1000, false);
+	return wait_for_bit_le32(&sysmgr_regs->noc_idleack, mask_noc,
+				 false, 1000, false);
 }
 
 void socfpga_reset_assert_fpga_connected_peripherals(void)
@@ -343,26 +343,26 @@ int socfpga_bridges_reset(void)
 	writel(ALT_SYSMGR_NOC_TMO_EN_SET_MSK, &sysmgr_regs->noc_timeout);
 
 	/* Poll until all idleack to 1 */
-	ret = wait_for_bit(__func__, &sysmgr_regs->noc_idleack,
-		     ALT_SYSMGR_NOC_H2F_SET_MSK |
-		     ALT_SYSMGR_NOC_LWH2F_SET_MSK |
-		     ALT_SYSMGR_NOC_F2H_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
-		     true, 10000, false);
+	ret = wait_for_bit_le32(&sysmgr_regs->noc_idleack,
+				ALT_SYSMGR_NOC_H2F_SET_MSK |
+				ALT_SYSMGR_NOC_LWH2F_SET_MSK |
+				ALT_SYSMGR_NOC_F2H_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
+				true, 10000, false);
 	if (ret)
 		return ret;
 
 	/* Poll until all idlestatus to 1 */
-	ret = wait_for_bit(__func__, &sysmgr_regs->noc_idlestatus,
-		     ALT_SYSMGR_NOC_H2F_SET_MSK |
-		     ALT_SYSMGR_NOC_LWH2F_SET_MSK |
-		     ALT_SYSMGR_NOC_F2H_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
-		     ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
-		     true, 10000, false);
+	ret = wait_for_bit_le32(&sysmgr_regs->noc_idlestatus,
+				ALT_SYSMGR_NOC_H2F_SET_MSK |
+				ALT_SYSMGR_NOC_LWH2F_SET_MSK |
+				ALT_SYSMGR_NOC_F2H_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
+				ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
+				true, 10000, false);
 	if (ret)
 		return ret;
 

+ 17 - 0
arch/mips/dts/brcm,bcm3380.dtsi

@@ -12,6 +12,10 @@
 / {
 	compatible = "brcm,bcm3380";
 
+	aliases {
+		spi0 = &spi;
+	};
+
 	cpus {
 		reg = <0x14e00000 0x4>;
 		#address-cells = <1>;
@@ -142,6 +146,19 @@
 			status = "disabled";
 		};
 
+		spi: spi@14e02000 {
+			compatible = "brcm,bcm6358-spi";
+			reg = <0x14e02000 0x70c>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&periph_clk0 BCM3380_CLK0_SPI>;
+			resets = <&periph_rst0 BCM3380_RST0_SPI>;
+			spi-max-frequency = <25000000>;
+			num-cs = <6>;
+
+			status = "disabled";
+		};
+
 		leds: led-controller@14e00f00 {
 			compatible = "brcm,bcm6328-leds";
 			reg = <0x14e00f00 0x1c>;

+ 38 - 0
arch/mips/dts/brcm,bcm63268.dtsi

@@ -13,6 +13,11 @@
 / {
 	compatible = "brcm,bcm63268";
 
+	aliases {
+		spi0 = &lsspi;
+		spi1 = &hsspi;
+	};
+
 	cpus {
 		reg = <0x10000000 0x4>;
 		#address-cells = <1>;
@@ -40,6 +45,12 @@
 		#size-cells = <1>;
 		u-boot,dm-pre-reloc;
 
+		hsspi_pll: hsspi-pll {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <400000000>;
+		};
+
 		periph_osc: periph-osc {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
@@ -136,6 +147,33 @@
 			#power-domain-cells = <1>;
 		};
 
+		lsspi: spi@10000800 {
+			compatible = "brcm,bcm6358-spi";
+			reg = <0x10000800 0x70c>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&periph_clk BCM63268_CLK_SPI>;
+			resets = <&periph_rst BCM63268_RST_SPI>;
+			spi-max-frequency = <20000000>;
+			num-cs = <8>;
+
+			status = "disabled";
+		};
+
+		hsspi: spi@10001000 {
+			compatible = "brcm,bcm6328-hsspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10001000 0x600>;
+			clocks = <&periph_clk BCM63268_CLK_HSSPI>, <&hsspi_pll>;
+			clock-names = "hsspi", "pll";
+			resets = <&periph_rst BCM63268_RST_SPI>;
+			spi-max-frequency = <50000000>;
+			num-cs = <8>;
+
+			status = "disabled";
+		};
+
 		leds: led-controller@10001900 {
 			compatible = "brcm,bcm6328-leds";
 			reg = <0x10001900 0x24>;

+ 24 - 0
arch/mips/dts/brcm,bcm6328.dtsi

@@ -13,6 +13,10 @@
 / {
 	compatible = "brcm,bcm6328";
 
+	aliases {
+		spi0 = &spi;
+	};
+
 	cpus {
 		reg = <0x10000000 0x4>;
 		#address-cells = <1>;
@@ -40,6 +44,12 @@
 		#size-cells = <1>;
 		u-boot,dm-pre-reloc;
 
+		hsspi_pll: hsspi-pll {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <133333333>;
+		};
+
 		periph_osc: periph-osc {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
@@ -123,6 +133,20 @@
 			status = "disabled";
 		};
 
+		spi: spi@10001000 {
+			compatible = "brcm,bcm6328-hsspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x10001000 0x600>;
+			clocks = <&periph_clk BCM6328_CLK_HSSPI>, <&hsspi_pll>;
+			clock-names = "hsspi", "pll";
+			resets = <&periph_rst BCM6328_RST_SPI>;
+			spi-max-frequency = <33333334>;
+			num-cs = <3>;
+
+			status = "disabled";
+		};
+
 		periph_pwr: power-controller@10001848 {
 			compatible = "brcm,bcm6328-power-domain";
 			reg = <0x10001848 0x4>;

+ 17 - 0
arch/mips/dts/brcm,bcm6338.dtsi

@@ -12,6 +12,10 @@
 / {
 	compatible = "brcm,bcm6338";
 
+	aliases {
+		spi0 = &spi;
+	};
+
 	cpus {
 		reg = <0xfffe0000 0x4>;
 		#address-cells = <1>;
@@ -109,6 +113,19 @@
 			status = "disabled";
 		};
 
+		spi: spi@fffe0c00 {
+			compatible = "brcm,bcm6348-spi";
+			reg = <0xfffe0c00 0xc0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&periph_clk BCM6338_CLK_SPI>;
+			resets = <&periph_rst BCM6338_RST_SPI>;
+			spi-max-frequency = <20000000>;
+			num-cs = <4>;
+
+			status = "disabled";
+		};
+
 		memory-controller@fffe3100 {
 			compatible = "brcm,bcm6338-mc";
 			reg = <0xfffe3100 0x38>;

+ 17 - 0
arch/mips/dts/brcm,bcm6348.dtsi

@@ -12,6 +12,10 @@
 / {
 	compatible = "brcm,bcm6348";
 
+	aliases {
+		spi0 = &spi;
+	};
+
 	cpus {
 		reg = <0xfffe0000 0x4>;
 		#address-cells = <1>;
@@ -118,6 +122,19 @@
 			status = "disabled";
 		};
 
+		spi: spi@fffe0c00 {
+			compatible = "brcm,bcm6348-spi";
+			reg = <0xfffe0c00 0xc0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&periph_clk BCM6348_CLK_SPI>;
+			resets = <&periph_rst BCM6348_RST_SPI>;
+			spi-max-frequency = <20000000>;
+			num-cs = <4>;
+
+			status = "disabled";
+		};
+
 		memory-controller@fffe2300 {
 			compatible = "brcm,bcm6338-mc";
 			reg = <0xfffe2300 0x38>;

+ 17 - 0
arch/mips/dts/brcm,bcm6358.dtsi

@@ -12,6 +12,10 @@
 / {
 	compatible = "brcm,bcm6358";
 
+	aliases {
+		spi0 = &spi;
+	};
+
 	cpus {
 		reg = <0xfffe0000 0x4>;
 		#address-cells = <1>;
@@ -142,6 +146,19 @@
 			status = "disabled";
 		};
 
+		spi: spi@fffe0800 {
+			compatible = "brcm,bcm6358-spi";
+			reg = <0xfffe0800 0x70c>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&periph_clk BCM6358_CLK_SPI>;
+			resets = <&periph_rst BCM6358_RST_SPI>;
+			spi-max-frequency = <20000000>;
+			num-cs = <4>;
+
+			status = "disabled";
+		};
+
 		memory-controller@fffe1200 {
 			compatible = "brcm,bcm6358-mc";
 			reg = <0xfffe1200 0x4c>;

+ 12 - 0
arch/mips/dts/comtrend,ar-5387un.dts

@@ -51,6 +51,18 @@
 	};
 };
 
+&spi {
+	status = "okay";
+
+	spi-flash@0 {
+		compatible = "spi-flash";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <33333334>;
+	};
+};
+
 &uart0 {
 	u-boot,dm-pre-reloc;
 	status = "okay";

+ 12 - 0
arch/mips/dts/netgear,cg3100d.dts

@@ -90,6 +90,18 @@
 	status = "okay";
 };
 
+&spi {
+	status = "okay";
+
+	spi-flash@0 {
+		compatible = "spi-flash";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <25000000>;
+	};
+};
+
 &uart0 {
 	u-boot,dm-pre-reloc;
 	status = "okay";

+ 12 - 0
arch/mips/dts/sagem,f@st1704.dts

@@ -44,6 +44,18 @@
 	status = "okay";
 };
 
+&spi {
+	status = "okay";
+
+	spi-flash@0 {
+		compatible = "spi-flash";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		spi-max-frequency = <20000000>;
+	};
+};
+
 &uart0 {
 	u-boot,dm-pre-reloc;
 	status = "okay";

+ 1 - 1
arch/mips/mach-ath79/ar934x/clk.c

@@ -90,7 +90,7 @@ static void ar934x_srif_pll_cfg(void __iomem *pll_reg_base, const u32 srif_val)
 		setbits_be32(pll_reg_base + 0x8, BIT(30));
 		udelay(5);
 
-		wait_for_bit("clk", pll_reg_base + 0xc, BIT(3), 1, 10, 0);
+		wait_for_bit_le32(pll_reg_base + 0xc, BIT(3), 1, 10, 0);
 
 		clrbits_be32(pll_reg_base + 0x8, BIT(30));
 		udelay(5);

+ 2 - 2
board/samtec/vining_2000/vining_2000.c

@@ -378,7 +378,7 @@ static int read_adc(u32 *val)
 
 	/* start auto calibration */
 	setbits_le32(b + ADCx_GC, ADCx_GC_CAL);
-	ret = wait_for_bit("ADC", b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0);
+	ret = wait_for_bit_le32(b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0);
 	if (ret)
 		goto adc_exit;
 
@@ -386,7 +386,7 @@ static int read_adc(u32 *val)
 	writel(0, b + ADCx_HC0);
 
 	/* wait for conversion */
-	ret = wait_for_bit("ADC", b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0);
+	ret = wait_for_bit_le32(b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0);
 	if (ret)
 		goto adc_exit;
 

+ 8 - 0
configs/comtrend_ar5387un_ram_defconfig

@@ -26,6 +26,8 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
 # CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
 # CONFIG_CMD_NET is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
@@ -34,6 +36,10 @@ CONFIG_DM_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_POWER_DOMAIN=y
 CONFIG_BCM6328_POWER_DOMAIN=y
 CONFIG_DM_RESET=y
@@ -41,3 +47,5 @@ CONFIG_RESET_BCM6345=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
 CONFIG_DM_SERIAL=y
 CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_HSSPI=y

+ 8 - 0
configs/netgear_cg3100d_ram_defconfig

@@ -25,6 +25,8 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
 # CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
 # CONFIG_CMD_NET is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
@@ -35,9 +37,15 @@ CONFIG_LED=y
 CONFIG_LED_BCM6328=y
 CONFIG_LED_BLINK=y
 CONFIG_LED_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_BCM6345=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
 CONFIG_DM_SERIAL=y
 CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_SPI=y
 CONFIG_WDT_BCM6345=y

+ 8 - 0
configs/sagem_f@st1704_ram_defconfig

@@ -26,6 +26,8 @@ CONFIG_CMD_MEMINFO=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
 # CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
 # CONFIG_CMD_NET is not set
 # CONFIG_CMD_NFS is not set
 # CONFIG_CMD_MISC is not set
@@ -34,8 +36,14 @@ CONFIG_DM_GPIO=y
 CONFIG_BCM6345_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_BCM6345=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
 CONFIG_DM_SERIAL=y
 CONFIG_BCM6345_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_BCM63XX_SPI=y

+ 14 - 10
doc/device-tree-bindings/spi/soft-spi.txt

@@ -6,11 +6,15 @@ performance will typically be much lower than a real SPI bus.
 
 The soft SPI node requires the following properties:
 
-compatible: "u-boot,soft-spi"
-soft_spi_cs: GPIO number to use for SPI chip select (output)
-soft_spi_sclk: GPIO number to use for SPI clock (output)
-soft_spi_mosi: GPIO number to use for SPI MOSI line (output)
-soft_spi_miso GPIO number to use for SPI MISO line (input)
+Mandatory properties:
+compatible: "spi-gpio"
+cs-gpios: GPIOs to use for SPI chip select (output)
+gpio-sck: GPIO to use for SPI clock (output)
+And at least one of:
+gpio-mosi: GPIO to use for SPI MOSI line (output)
+gpio-miso: GPIO to use for SPI MISO line (input)
+
+Optional propertie:
 spi-delay-us: Number of microseconds of delay between each CS transition
 
 The GPIOs should be specified as required by the GPIO controller referenced.
@@ -21,11 +25,11 @@ typically holds the GPIO number.
 Example:
 
 	soft-spi {
-		compatible = "u-boot,soft-spi";
-		cs-gpio = <&gpio 235 0>;	/* Y43 */
-		sclk-gpio = <&gpio 225 0>;	/* Y31 */
-		mosi-gpio = <&gpio 227 0>;	/* Y33 */
-		miso-gpio = <&gpio 224 0>;	/* Y30 */
+		compatible = "spi-gpio";
+		cs-gpios = <&gpio 235 0>;	/* Y43 */
+		gpio-sck = <&gpio 225 0>;	/* Y31 */
+		gpio-mosi = <&gpio 227 0>;	/* Y33 */
+		gpio-miso = <&gpio 224 0>;	/* Y30 */
 		spi-delay-us = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;

+ 8 - 5
doc/device-tree-bindings/spi/spi-cadence.txt

@@ -6,7 +6,10 @@ Required properties:
 - reg			: 1.Physical base address and size of SPI registers map.
 			  2. Physical base address & size of NOR Flash.
 - clocks		: Clock phandles (see clock bindings for details).
-- sram-size		: spi controller sram size.
+- cdns,fifo-depth	: Size of the data FIFO in words.
+- cdns,fifo-width	: Bus width of the data FIFO in bytes.
+- cdns,trigger-address	: 32-bit indirect AHB trigger address.
+- cdns,is-decoded-cs	: Flag to indicate whether decoder is used or not.
 - status		: enable in requried dts.
 
 connected flash properties
@@ -15,14 +18,14 @@ connected flash properties
 - spi-max-frequency	: Max supported spi frequency.
 - page-size		: Flash page size.
 - block-size		: Flash memory block size.
-- tshsl-ns		: Added delay in master reference clocks (ref_clk) for
+- cdns,tshsl-ns		: Added delay in master reference clocks (ref_clk) for
 			  the length that the master mode chip select outputs
 			  are de-asserted between transactions.
-- tsd2d-ns		: Delay in master reference clocks (ref_clk) between one
+- cdns,tsd2d-ns		: Delay in master reference clocks (ref_clk) between one
 			  chip select being de-activated and the activation of
 			  another.
-- tchsh-ns		: Delay in master reference clocks between last bit of
+- cdns,tchsh-ns		: Delay in master reference clocks between last bit of
 			  current transaction and de-asserting the device chip
 			  select (n_ss_out).
-- tslch-ns		: Delay in master reference clocks between setting
+- cdns,tslch-ns		: Delay in master reference clocks between setting
 			  n_ss_out low and first bit transfer

+ 6 - 6
drivers/clk/clk_pic32.c

@@ -197,8 +197,8 @@ static ulong pic32_set_refclk(struct pic32_clk_priv *priv, int periph,
 	writel(REFO_ON | REFO_OE, reg + _CLR_OFFSET);
 
 	/* wait till previous src change is active */
-	wait_for_bit(__func__, reg, REFO_DIVSW_EN | REFO_ACTIVE,
-		     false, CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(reg, REFO_DIVSW_EN | REFO_ACTIVE,
+			  false, CONFIG_SYS_HZ, false);
 
 	/* parent_id */
 	v = readl(reg);
@@ -223,8 +223,8 @@ static ulong pic32_set_refclk(struct pic32_clk_priv *priv, int periph,
 	writel(REFO_DIVSW_EN, reg + _SET_OFFSET);
 
 	/* wait for divider switching to complete */
-	return wait_for_bit(__func__, reg, REFO_DIVSW_EN, false,
-			    CONFIG_SYS_HZ, false);
+	return wait_for_bit_le32(reg, REFO_DIVSW_EN, false,
+				 CONFIG_SYS_HZ, false);
 }
 
 static ulong pic32_get_refclk(struct pic32_clk_priv *priv, int periph)
@@ -311,8 +311,8 @@ static int pic32_mpll_init(struct pic32_clk_priv *priv)
 
 	/* Wait for ready */
 	mask = MPLL_RDY | MPLL_VREG_RDY;
-	return wait_for_bit(__func__, priv->syscfg_base + CFGMPLL, mask,
-			    true, get_tbclk(), false);
+	return wait_for_bit_le32(priv->syscfg_base + CFGMPLL, mask,
+				 true, get_tbclk(), false);
 }
 
 static void pic32_clk_init(struct udevice *dev)

+ 2 - 2
drivers/clk/renesas/clk-rcar-gen3.c

@@ -1046,8 +1046,8 @@ static int gen3_clk_endisable(struct clk *clk, bool enable)
 		if (ret)
 			return ret;
 		clrbits_le32(priv->base + SMSTPCR(reg), bitmask);
-		return wait_for_bit("MSTP", priv->base + MSTPSR(reg),
-				    bitmask, 0, 100, 0);
+		return wait_for_bit_le32(priv->base + MSTPSR(reg),
+					 bitmask, 0, 100, 0);
 	} else {
 		setbits_le32(priv->base + SMSTPCR(reg), bitmask);
 		return 0;

+ 4 - 4
drivers/ddr/microchip/ddr2.c

@@ -57,8 +57,8 @@ static int ddr2_phy_calib_start(void)
 	writel(SCL_START | SCL_EN, &ddr2_phy->scl_start);
 
 	/* Wait for SCL for data byte to pass */
-	return wait_for_bit(__func__, &ddr2_phy->scl_start, SCL_LUBPASS,
-			    true, CONFIG_SYS_HZ, false);
+	return wait_for_bit_le32(&ddr2_phy->scl_start, SCL_LUBPASS,
+				 true, CONFIG_SYS_HZ, false);
 }
 
 /* DDR2 Controller initialization */
@@ -256,8 +256,8 @@ void ddr2_ctrl_init(void)
 	writel(INIT_START, &ctrl->memcon);
 
 	/* wait for all host cmds to be transmitted */
-	wait_for_bit(__func__, &ctrl->cmdissue, CMD_VALID, false,
-		     CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(&ctrl->cmdissue, CMD_VALID, false,
+			  CONFIG_SYS_HZ, false);
 
 	/* inform all cmds issued, ready for normal operation */
 	writel(INIT_START | INIT_DONE, &ctrl->memcon);

+ 7 - 10
drivers/fpga/socfpga_arria10.c

@@ -62,8 +62,7 @@ int is_fpgamgr_user_mode(void)
 
 static int wait_for_user_mode(void)
 {
-	return wait_for_bit(__func__,
-		&fpga_manager_base->imgcfg_stat,
+	return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
 		ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK,
 		1, FPGA_TIMEOUT_MSEC, false);
 }
@@ -115,19 +114,17 @@ static int wait_for_nconfig_pin_and_nstatus_pin(void)
 	/* Poll until f2s_nconfig_pin and f2s_nstatus_pin; loop until de-asserted,
 	 * timeout at 1000ms
 	 */
-	return wait_for_bit(__func__,
-			    &fpga_manager_base->imgcfg_stat,
-			    mask,
-			    false, FPGA_TIMEOUT_MSEC, false);
+	return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
+		mask,
+		false, FPGA_TIMEOUT_MSEC, false);
 }
 
 static int wait_for_f2s_nstatus_pin(unsigned long value)
 {
 	/* Poll until f2s to specific value, timeout at 1000ms */
-	return wait_for_bit(__func__,
-			    &fpga_manager_base->imgcfg_stat,
-			    ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK,
-			    value, FPGA_TIMEOUT_MSEC, false);
+	return wait_for_bit_le32(&fpga_manager_base->imgcfg_stat,
+		ALT_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN_SET_MSK,
+		value, FPGA_TIMEOUT_MSEC, false);
 }
 
 /* set CD ratio */

+ 4 - 4
drivers/mmc/msm_sdhci.c

@@ -109,15 +109,15 @@ static int msm_sdc_probe(struct udevice *dev)
 
 
 	/* Wait for reset to be written to register */
-	if (wait_for_bit(__func__, prv->base + SDCC_MCI_STATUS2,
-			 SDCC_MCI_STATUS2_MCI_ACT, false, 10, false)) {
+	if (wait_for_bit_le32(prv->base + SDCC_MCI_STATUS2,
+			      SDCC_MCI_STATUS2_MCI_ACT, false, 10, false)) {
 		printf("msm_sdhci: reset request failed\n");
 		return -EIO;
 	}
 
 	/* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
-	if (wait_for_bit(__func__, prv->base + SDCC_MCI_POWER,
-			 SDCC_MCI_POWER_SW_RST, false, 2, false)) {
+	if (wait_for_bit_le32(prv->base + SDCC_MCI_POWER,
+			      SDCC_MCI_POWER_SW_RST, false, 2, false)) {
 		printf("msm_sdhci: stuck in reset\n");
 		return -ETIMEDOUT;
 	}

+ 2 - 2
drivers/mtd/pic32_flash.c

@@ -66,8 +66,8 @@ static inline void flash_initiate_operation(u32 nvmop)
 
 static int flash_wait_till_busy(const char *func, ulong timeout)
 {
-	int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw,
-			       NVM_WR, false, timeout, false);
+	int ret = wait_for_bit_le32(&nvm_regs_p->ctrl.raw,
+				    NVM_WR, false, timeout, false);
 
 	return ret ? ERR_TIMOUT : ERR_OK;
 }

+ 8 - 26
drivers/mtd/spi/sf_probe.c

@@ -55,10 +55,16 @@ err_read_id:
 }
 
 #ifndef CONFIG_DM_SPI_FLASH
-static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
+struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
+				  unsigned int max_hz, unsigned int spi_mode)
 {
+	struct spi_slave *bus;
 	struct spi_flash *flash;
 
+	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
+	if (!bus)
+		return NULL;
+
 	/* Allocate space if needed (not used by sf-uclass */
 	flash = calloc(1, sizeof(*flash));
 	if (!flash) {
@@ -76,30 +82,6 @@ static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
 	return flash;
 }
 
-struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
-		unsigned int max_hz, unsigned int spi_mode)
-{
-	struct spi_slave *bus;
-
-	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
-	if (!bus)
-		return NULL;
-	return spi_flash_probe_tail(bus);
-}
-
-#ifdef CONFIG_OF_SPI_FLASH
-struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
-				      int spi_node)
-{
-	struct spi_slave *bus;
-
-	bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
-	if (!bus)
-		return NULL;
-	return spi_flash_probe_tail(bus);
-}
-#endif
-
 void spi_flash_free(struct spi_flash *flash)
 {
 #ifdef CONFIG_SPI_FLASH_MTD
@@ -120,7 +102,7 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
 }
 
 static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
-			const void *buf)
+			       const void *buf)
 {
 	struct spi_flash *flash = dev_get_uclass_priv(dev);
 

+ 4 - 1
drivers/mtd/spi/spi_flash.c

@@ -405,7 +405,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 
 		if (spi->max_write_size)
 			chunk_len = min(chunk_len,
-					(size_t)spi->max_write_size);
+					spi->max_write_size - sizeof(cmd));
 
 		spi_flash_addr(write_addr, cmd);
 
@@ -516,6 +516,9 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		else
 			read_len = remain_len;
 
+		if (spi->max_read_size)
+			read_len = min(read_len, spi->max_read_size);
+
 		spi_flash_addr(read_addr, cmd);
 
 		ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);

+ 8 - 8
drivers/net/ag7xxx.c

@@ -164,8 +164,8 @@ static int ag7xxx_switch_read(struct mii_dev *bus, int addr, int reg, u16 *val)
 	writel(AG7XXX_ETH_MII_MGMT_CMD_READ,
 	       regs + AG7XXX_ETH_MII_MGMT_CMD);
 
-	ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
-			   AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
+	ret = wait_for_bit_le32(regs + AG7XXX_ETH_MII_MGMT_IND,
+				AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
 	if (ret)
 		return ret;
 
@@ -185,8 +185,8 @@ static int ag7xxx_switch_write(struct mii_dev *bus, int addr, int reg, u16 val)
 	       regs + AG7XXX_ETH_MII_MGMT_ADDRESS);
 	writel(val, regs + AG7XXX_ETH_MII_MGMT_CTRL);
 
-	ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND,
-			   AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
+	ret = wait_for_bit_le32(regs + AG7XXX_ETH_MII_MGMT_IND,
+				AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0);
 
 	return ret;
 }
@@ -510,13 +510,13 @@ static void ag7xxx_eth_stop(struct udevice *dev)
 
 	/* Stop the TX DMA. */
 	writel(0, priv->regs + AG7XXX_ETH_DMA_TX_CTRL);
-	wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0,
-		     1000, 0);
+	wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0,
+			  1000, 0);
 
 	/* Stop the RX DMA. */
 	writel(0, priv->regs + AG7XXX_ETH_DMA_RX_CTRL);
-	wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0,
-		     1000, 0);
+	wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0,
+			  1000, 0);
 }
 
 /*

+ 9 - 8
drivers/net/dwc_eth_qos.c

@@ -361,8 +361,9 @@ static void eqos_flush_buffer(void *buf, size_t size)
 
 static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
 {
-	return wait_for_bit(__func__, &eqos->mac_regs->mdio_address,
-			    EQOS_MAC_MDIO_ADDRESS_GB, false, 1000000, true);
+	return wait_for_bit_le32(&eqos->mac_regs->mdio_address,
+				 EQOS_MAC_MDIO_ADDRESS_GB, false,
+				 1000000, true);
 }
 
 static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
@@ -588,15 +589,15 @@ static int eqos_calibrate_pads_tegra186(struct udevice *dev)
 	setbits_le32(&eqos->tegra186_regs->auto_cal_config,
 		     EQOS_AUTO_CAL_CONFIG_START | EQOS_AUTO_CAL_CONFIG_ENABLE);
 
-	ret = wait_for_bit(__func__, &eqos->tegra186_regs->auto_cal_status,
-			   EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
+	ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
+				EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
 	if (ret) {
 		pr_err("calibrate didn't start");
 		goto failed;
 	}
 
-	ret = wait_for_bit(__func__, &eqos->tegra186_regs->auto_cal_status,
-			   EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
+	ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
+				EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
 	if (ret) {
 		pr_err("calibrate didn't finish");
 		goto failed;
@@ -862,8 +863,8 @@ static int eqos_start(struct udevice *dev)
 
 	eqos->reg_access_ok = true;
 
-	ret = wait_for_bit(__func__, &eqos->dma_regs->mode,
-			   EQOS_DMA_MODE_SWR, false, 10, false);
+	ret = wait_for_bit_le32(&eqos->dma_regs->mode,
+				EQOS_DMA_MODE_SWR, false, 10, false);
 	if (ret) {
 		pr_err("EQOS_DMA_MODE_SWR stuck");
 		goto err_stop_resets;

+ 4 - 4
drivers/net/ethoc.c

@@ -548,8 +548,8 @@ static int ethoc_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 	ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(addr, reg));
 	ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
 
-	rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
-			  MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
+	rc = wait_for_bit_le32(ethoc_reg(priv, MIISTATUS),
+			       MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
 
 	if (rc == 0) {
 		u32 data = ethoc_read(priv, MIIRX_DATA);
@@ -571,8 +571,8 @@ static int ethoc_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 	ethoc_write(priv, MIITX_DATA, val);
 	ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
 
-	rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
-			  MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
+	rc = wait_for_bit_le32(ethoc_reg(priv, MIISTATUS),
+			       MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
 
 	if (rc == 0) {
 		/* reset MII command register */

+ 6 - 6
drivers/net/pic32_eth.c

@@ -64,8 +64,8 @@ static int pic32_mii_init(struct pic32eth_dev *priv)
 	writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr);
 
 	/* wait till busy */
-	wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
-		     CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+			  CONFIG_SYS_HZ, false);
 
 	/* turn controller ON to access PHY over MII */
 	writel(ETHCON_ON, &ectl_p->con1.set);
@@ -239,8 +239,8 @@ static void pic32_ctrl_reset(struct pic32eth_dev *priv)
 	writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr);
 
 	/* wait till busy */
-	wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
-		     CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+			  CONFIG_SYS_HZ, false);
 	/* decrement received buffcnt to zero. */
 	while (readl(&ectl_p->stat.raw) & ETHSTAT_BUFCNT)
 		writel(ETHCON_BUFCDEC, &ectl_p->con1.set);
@@ -375,8 +375,8 @@ static void pic32_eth_stop(struct udevice *dev)
 	mdelay(10);
 
 	/* wait until everything is down */
-	wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false,
-		     2 * CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
+			  2 * CONFIG_SYS_HZ, false);
 
 	/* clear any existing interrupt event */
 	writel(0xffffffff, &ectl_p->irq.clr);

+ 14 - 14
drivers/net/pic32_mdio.c

@@ -22,8 +22,8 @@ static int pic32_mdio_write(struct mii_dev *bus,
 	struct pic32_mii_regs *mii_regs = bus->priv;
 
 	/* Wait for the previous operation to finish */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, true);
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, true);
 
 	/* Put phyaddr and regaddr into MIIMADD */
 	v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
@@ -36,8 +36,8 @@ static int pic32_mdio_write(struct mii_dev *bus,
 	udelay(12);
 
 	/* Wait for write to complete */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, true);
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, true);
 
 	return 0;
 }
@@ -48,8 +48,8 @@ static int pic32_mdio_read(struct mii_dev *bus, int addr, int devaddr, int reg)
 	struct pic32_mii_regs *mii_regs = bus->priv;
 
 	/* Wait for the previous operation to finish */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, true);
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, true);
 
 	/* Put phyaddr and regaddr into MIIMADD */
 	v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
@@ -62,9 +62,9 @@ static int pic32_mdio_read(struct mii_dev *bus, int addr, int devaddr, int reg)
 	udelay(12);
 
 	/* Wait for read to complete */
-	wait_for_bit(__func__, &mii_regs->mind.raw,
-		     MIIMIND_NOTVALID | MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(&mii_regs->mind.raw,
+			  MIIMIND_NOTVALID | MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, false);
 
 	/* Clear the command register */
 	writel(0, &mii_regs->mcmd.raw);
@@ -82,22 +82,22 @@ static int pic32_mdio_reset(struct mii_dev *bus)
 	writel(MIIMCFG_RSTMGMT, &mii_regs->mcfg.raw);
 
 	/* Wait for the operation to finish */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
 		     false, CONFIG_SYS_HZ, true);
 
 	/* Clear reset bit */
 	writel(0, &mii_regs->mcfg);
 
 	/* Wait for the operation to finish */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, true);
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, true);
 
 	/* Set the MII Management Clock (MDC) - no faster than 2.5 MHz */
 	writel(MIIMCFG_CLKSEL_DIV40, &mii_regs->mcfg.raw);
 
 	/* Wait for the operation to finish */
-	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
-		     false, CONFIG_SYS_HZ, true);
+	wait_for_bit_le32(&mii_regs->mind.raw, MIIMIND_BUSY,
+			  false, CONFIG_SYS_HZ, true);
 	return 0;
 }
 

+ 2 - 2
drivers/net/ravb.c

@@ -222,8 +222,8 @@ static int ravb_reset(struct udevice *dev)
 	writel(CCC_OPC_CONFIG, eth->iobase + RAVB_REG_CCC);
 
 	/* Check the operating mode is changed to the config mode. */
-	return wait_for_bit(dev->name, (void *)eth->iobase + RAVB_REG_CSR,
-			    CSR_OPS_CONFIG, true, 100, true);
+	return wait_for_bit_le32(eth->iobase + RAVB_REG_CSR,
+				 CSR_OPS_CONFIG, true, 100, true);
 }
 
 static void ravb_base_desc_init(struct ravb_priv *eth)

+ 2 - 2
drivers/net/xilinx_axi_emac.c

@@ -366,8 +366,8 @@ static int axi_ethernet_init(struct axidma_priv *priv)
 	 * processor mode and hence bypass in this mode
 	 */
 	if (!priv->eth_hasnobuf) {
-		err = wait_for_bit(__func__, (const u32 *)&regs->is,
-				   XAE_INT_MGTRDY_MASK, true, 200, false);
+		err = wait_for_bit_le32(&regs->is, XAE_INT_MGTRDY_MASK,
+					true, 200, false);
 		if (err) {
 			printf("%s: Timeout\n", __func__);
 			return 1;

+ 6 - 6
drivers/net/zynq_gem.c

@@ -192,8 +192,8 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
 	struct zynq_gem_regs *regs = priv->iobase;
 	int err;
 
-	err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
-			    true, 20000, false);
+	err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+				true, 20000, false);
 	if (err)
 		return err;
 
@@ -205,8 +205,8 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
 	/* Write mgtcr and wait for completion */
 	writel(mgtcr, &regs->phymntnc);
 
-	err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
-			    true, 20000, false);
+	err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+				true, 20000, false);
 	if (err)
 		return err;
 
@@ -514,8 +514,8 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
 	if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
 		printf("TX buffers exhausted in mid frame\n");
 
-	return wait_for_bit(__func__, &regs->txsr, ZYNQ_GEM_TSR_DONE,
-			    true, 20000, true);
+	return wait_for_bit_le32(&regs->txsr, ZYNQ_GEM_TSR_DONE,
+				 true, 20000, true);
 }
 
 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */

+ 2 - 2
drivers/reset/sti-reset.c

@@ -266,8 +266,8 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
 		return 0;
 
 	reg = (void __iomem *)base + ch->ack_offset;
-	if (wait_for_bit(__func__, reg, BIT(ch->ack_bit), ctrl_val,
-			 1000, false)) {
+	if (wait_for_bit_le32(reg, BIT(ch->ack_bit), ctrl_val,
+			      1000, false)) {
 		pr_err("Stuck on waiting ack reset_ctl=%p dev=%p id=%lu\n",
 		      reset_ctl, reset_ctl->dev, reset_ctl->id);
 

+ 2 - 2
drivers/serial/serial_pic32.c

@@ -51,8 +51,8 @@ static int pic32_serial_init(void __iomem *base, ulong clk, u32 baudrate)
 	u32 div = DIV_ROUND_CLOSEST(clk, baudrate * 16);
 
 	/* wait for TX FIFO to empty */
-	wait_for_bit(__func__, base + U_STA, UART_TX_EMPTY,
-		     true, CONFIG_SYS_HZ, false);
+	wait_for_bit_le32(base + U_STA, UART_TX_EMPTY,
+			  true, CONFIG_SYS_HZ, false);
 
 	/* send break */
 	writel(UART_TX_BRK, base + U_STASET);

+ 16 - 0
drivers/spi/Kconfig

@@ -40,6 +40,22 @@ config ATMEL_SPI
 	  many AT91 (ARM) chips. This driver can be used to access
 	  the SPI Flash, such as AT25DF321.
 
+config BCM63XX_HSSPI
+	bool "BCM63XX HSSPI driver"
+	depends on ARCH_BMIPS
+	help
+	  Enable the BCM6328 HSSPI driver. This driver can be used to
+	  access the SPI NOR flash on platforms embedding this Broadcom
+	  SPI core.
+
+config BCM63XX_SPI
+	bool "BCM6348 SPI driver"
+	depends on ARCH_BMIPS
+	help
+	  Enable the BCM6348/BCM6358 SPI driver. This driver can be used to
+	  access the SPI NOR flash on platforms embedding these Broadcom
+	  SPI cores.
+
 config CADENCE_QSPI
 	bool "Cadence QSPI driver"
 	help

+ 2 - 0
drivers/spi/Makefile

@@ -18,6 +18,8 @@ endif
 obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
 obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
+obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o
+obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_CF_SPI) += cf_spi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o

+ 2 - 2
drivers/spi/atmel_spi.c

@@ -394,8 +394,8 @@ out:
 		 * Wait until the transfer is completely done before
 		 * we deactivate CS.
 		 */
-		wait_for_bit(__func__, &reg_base->sr,
-			     ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
+		wait_for_bit_le32(&reg_base->sr,
+				  ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
 
 		atmel_spi_cs_deactivate(dev);
 	}

+ 414 - 0
drivers/spi/bcm63xx_hsspi.c

@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/spi/spi-bcm63xx-hsspi.c:
+ *	Copyright (C) 2000-2010 Broadcom Corporation
+ *	Copyright (C) 2012-2013 Jonas Gorski <jogo@openwrt.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <spi.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define HSSPI_PP			0
+
+#define SPI_MAX_SYNC_CLOCK		30000000
+
+/* SPI Control register */
+#define SPI_CTL_REG			0x000
+#define SPI_CTL_CS_POL_SHIFT		0
+#define SPI_CTL_CS_POL_MASK		(0xff << SPI_CTL_CS_POL_SHIFT)
+#define SPI_CTL_CLK_GATE_SHIFT		16
+#define SPI_CTL_CLK_GATE_MASK		(1 << SPI_CTL_CLK_GATE_SHIFT)
+#define SPI_CTL_CLK_POL_SHIFT		17
+#define SPI_CTL_CLK_POL_MASK		(1 << SPI_CTL_CLK_POL_SHIFT)
+
+/* SPI Interrupts registers */
+#define SPI_IR_STAT_REG			0x008
+#define SPI_IR_ST_MASK_REG		0x00c
+#define SPI_IR_MASK_REG			0x010
+
+#define SPI_IR_CLEAR_ALL		0xff001f1f
+
+/* SPI Ping-Pong Command registers */
+#define SPI_CMD_REG			(0x080 + (0x40 * (HSSPI_PP)) + 0x00)
+#define SPI_CMD_OP_SHIFT		0
+#define SPI_CMD_OP_START		(0x1 << SPI_CMD_OP_SHIFT)
+#define SPI_CMD_PFL_SHIFT		8
+#define SPI_CMD_PFL_MASK		(0x7 << SPI_CMD_PFL_SHIFT)
+#define SPI_CMD_SLAVE_SHIFT		12
+#define SPI_CMD_SLAVE_MASK		(0x7 << SPI_CMD_SLAVE_SHIFT)
+
+/* SPI Ping-Pong Status registers */
+#define SPI_STAT_REG			(0x080 + (0x40 * (HSSPI_PP)) + 0x04)
+#define SPI_STAT_SRCBUSY_SHIFT		1
+#define SPI_STAT_SRCBUSY_MASK		(1 << SPI_STAT_SRCBUSY_SHIFT)
+
+/* SPI Profile Clock registers */
+#define SPI_PFL_CLK_REG(x)		(0x100 + (0x20 * (x)) + 0x00)
+#define SPI_PFL_CLK_FREQ_SHIFT		0
+#define SPI_PFL_CLK_FREQ_MASK		(0x3fff << SPI_PFL_CLK_FREQ_SHIFT)
+#define SPI_PFL_CLK_RSTLOOP_SHIFT	15
+#define SPI_PFL_CLK_RSTLOOP_MASK	(1 << SPI_PFL_CLK_RSTLOOP_SHIFT)
+
+/* SPI Profile Signal registers */
+#define SPI_PFL_SIG_REG(x)		(0x100 + (0x20 * (x)) + 0x04)
+#define SPI_PFL_SIG_LATCHRIS_SHIFT	12
+#define SPI_PFL_SIG_LATCHRIS_MASK	(1 << SPI_PFL_SIG_LATCHRIS_SHIFT)
+#define SPI_PFL_SIG_LAUNCHRIS_SHIFT	13
+#define SPI_PFL_SIG_LAUNCHRIS_MASK	(1 << SPI_PFL_SIG_LAUNCHRIS_SHIFT)
+#define SPI_PFL_SIG_ASYNCIN_SHIFT	16
+#define SPI_PFL_SIG_ASYNCIN_MASK	(1 << SPI_PFL_SIG_ASYNCIN_SHIFT)
+
+/* SPI Profile Mode registers */
+#define SPI_PFL_MODE_REG(x)		(0x100 + (0x20 * (x)) + 0x08)
+#define SPI_PFL_MODE_FILL_SHIFT		0
+#define SPI_PFL_MODE_FILL_MASK		(0xff << SPI_PFL_MODE_FILL_SHIFT)
+#define SPI_PFL_MODE_MDRDSZ_SHIFT	16
+#define SPI_PFL_MODE_MDRDSZ_MASK	(1 << SPI_PFL_MODE_MDRDSZ_SHIFT)
+#define SPI_PFL_MODE_MDWRSZ_SHIFT	18
+#define SPI_PFL_MODE_MDWRSZ_MASK	(1 << SPI_PFL_MODE_MDWRSZ_SHIFT)
+#define SPI_PFL_MODE_3WIRE_SHIFT	20
+#define SPI_PFL_MODE_3WIRE_MASK		(1 << SPI_PFL_MODE_3WIRE_SHIFT)
+
+/* SPI Ping-Pong FIFO registers */
+#define HSSPI_FIFO_SIZE			0x200
+#define HSSPI_FIFO_BASE			(0x200 + \
+					 (HSSPI_FIFO_SIZE * HSSPI_PP))
+
+/* SPI Ping-Pong FIFO OP register */
+#define HSSPI_FIFO_OP_SIZE		0x2
+#define HSSPI_FIFO_OP_REG		(HSSPI_FIFO_BASE + 0x00)
+#define HSSPI_FIFO_OP_BYTES_SHIFT	0
+#define HSSPI_FIFO_OP_BYTES_MASK	(0x3ff << HSSPI_FIFO_OP_BYTES_SHIFT)
+#define HSSPI_FIFO_OP_MBIT_SHIFT	11
+#define HSSPI_FIFO_OP_MBIT_MASK		(1 << HSSPI_FIFO_OP_MBIT_SHIFT)
+#define HSSPI_FIFO_OP_CODE_SHIFT	13
+#define HSSPI_FIFO_OP_READ_WRITE	(1 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_W		(2 << HSSPI_FIFO_OP_CODE_SHIFT)
+#define HSSPI_FIFO_OP_CODE_R		(3 << HSSPI_FIFO_OP_CODE_SHIFT)
+
+struct bcm63xx_hsspi_priv {
+	void __iomem *regs;
+	ulong clk_rate;
+	uint8_t num_cs;
+	uint8_t cs_pols;
+	uint speed;
+};
+
+static int bcm63xx_hsspi_cs_info(struct udevice *bus, uint cs,
+			   struct spi_cs_info *info)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+	if (cs >= priv->num_cs) {
+		printf("no cs %u\n", cs);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int bcm63xx_hsspi_set_mode(struct udevice *bus, uint mode)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+	/* clock polarity */
+	if (mode & SPI_CPOL)
+		setbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+	else
+		clrbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_POL_MASK);
+
+	return 0;
+}
+
+static int bcm63xx_hsspi_set_speed(struct udevice *bus, uint speed)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(bus);
+
+	priv->speed = speed;
+
+	return 0;
+}
+
+static void bcm63xx_hsspi_activate_cs(struct bcm63xx_hsspi_priv *priv,
+				   struct dm_spi_slave_platdata *plat)
+{
+	uint32_t clr, set;
+
+	/* profile clock */
+	set = DIV_ROUND_UP(priv->clk_rate, priv->speed);
+	set = DIV_ROUND_UP(2048, set);
+	set &= SPI_PFL_CLK_FREQ_MASK;
+	set |= SPI_PFL_CLK_RSTLOOP_MASK;
+	writel_be(set, priv->regs + SPI_PFL_CLK_REG(plat->cs));
+
+	/* profile signal */
+	set = 0;
+	clr = SPI_PFL_SIG_LAUNCHRIS_MASK |
+	      SPI_PFL_SIG_LATCHRIS_MASK |
+	      SPI_PFL_SIG_ASYNCIN_MASK;
+
+	/* latch/launch config */
+	if (plat->mode & SPI_CPHA)
+		set |= SPI_PFL_SIG_LAUNCHRIS_MASK;
+	else
+		set |= SPI_PFL_SIG_LATCHRIS_MASK;
+
+	/* async clk */
+	if (priv->speed > SPI_MAX_SYNC_CLOCK)
+		set |= SPI_PFL_SIG_ASYNCIN_MASK;
+
+	clrsetbits_be32(priv->regs + SPI_PFL_SIG_REG(plat->cs), clr, set);
+
+	/* global control */
+	set = 0;
+	clr = 0;
+
+	/* invert cs polarity */
+	if (priv->cs_pols & BIT(plat->cs))
+		clr |= BIT(plat->cs);
+	else
+		set |= BIT(plat->cs);
+
+	/* invert dummy cs polarity */
+	if (priv->cs_pols & BIT(!plat->cs))
+		clr |= BIT(!plat->cs);
+	else
+		set |= BIT(!plat->cs);
+
+	clrsetbits_be32(priv->regs + SPI_CTL_REG, clr, set);
+}
+
+static void bcm63xx_hsspi_deactivate_cs(struct bcm63xx_hsspi_priv *priv)
+{
+	/* restore cs polarities */
+	clrsetbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CS_POL_MASK,
+			priv->cs_pols);
+}
+
+/*
+ * BCM63xx HSSPI driver doesn't allow keeping CS active between transfers
+ * because they are controlled by HW.
+ * However, it provides a mechanism to prepend write transfers prior to read
+ * transfers (with a maximum prepend of 15 bytes), which is usually enough for
+ * SPI-connected flashes since reading requires prepending a write transfer of
+ * 5 bytes. On the other hand it also provides a way to invert each CS
+ * polarity, not only between transfers like the older BCM63xx SPI driver, but
+ * also the rest of the time.
+ *
+ * Instead of using the prepend mechanism, this implementation inverts the
+ * polarity of both the desired CS and another dummy CS when the bus is
+ * claimed. This way, the dummy CS is restored to its inactive value when
+ * transfers are issued and the desired CS is preserved in its active value
+ * all the time. This hack is also used in the upstream linux driver and
+ * allows keeping CS active between trasnfers even if the HW doesn't give
+ * this possibility.
+ */
+static int bcm63xx_hsspi_xfer(struct udevice *dev, unsigned int bitlen,
+		const void *dout, void *din, unsigned long flags)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+	size_t data_bytes = bitlen / 8;
+	size_t step_size = HSSPI_FIFO_SIZE;
+	uint16_t opcode = 0;
+	uint32_t val;
+	const uint8_t *tx = dout;
+	uint8_t *rx = din;
+
+	if (flags & SPI_XFER_BEGIN)
+		bcm63xx_hsspi_activate_cs(priv, plat);
+
+	/* fifo operation */
+	if (tx && rx)
+		opcode = HSSPI_FIFO_OP_READ_WRITE;
+	else if (rx)
+		opcode = HSSPI_FIFO_OP_CODE_R;
+	else if (tx)
+		opcode = HSSPI_FIFO_OP_CODE_W;
+
+	if (opcode != HSSPI_FIFO_OP_CODE_R)
+		step_size -= HSSPI_FIFO_OP_SIZE;
+
+	/* dual mode */
+	if ((opcode == HSSPI_FIFO_OP_CODE_R && plat->mode == SPI_RX_DUAL) ||
+	    (opcode == HSSPI_FIFO_OP_CODE_W && plat->mode == SPI_TX_DUAL))
+		opcode |= HSSPI_FIFO_OP_MBIT_MASK;
+
+	/* profile mode */
+	val = SPI_PFL_MODE_FILL_MASK |
+	      SPI_PFL_MODE_MDRDSZ_MASK |
+	      SPI_PFL_MODE_MDWRSZ_MASK;
+	if (plat->mode & SPI_3WIRE)
+		val |= SPI_PFL_MODE_3WIRE_MASK;
+	writel_be(val, priv->regs + SPI_PFL_MODE_REG(plat->cs));
+
+	/* transfer loop */
+	while (data_bytes > 0) {
+		size_t curr_step = min(step_size, data_bytes);
+		int ret;
+
+		/* copy tx data */
+		if (tx) {
+			memcpy_toio(priv->regs + HSSPI_FIFO_BASE +
+				    HSSPI_FIFO_OP_SIZE, tx, curr_step);
+			tx += curr_step;
+		}
+
+		/* set fifo operation */
+		writew_be(opcode | (curr_step & HSSPI_FIFO_OP_BYTES_MASK),
+			  priv->regs + HSSPI_FIFO_OP_REG);
+
+		/* issue the transfer */
+		val = SPI_CMD_OP_START;
+		val |= (plat->cs << SPI_CMD_PFL_SHIFT) &
+		       SPI_CMD_PFL_MASK;
+		val |= (!plat->cs << SPI_CMD_SLAVE_SHIFT) &
+		       SPI_CMD_SLAVE_MASK;
+		writel_be(val, priv->regs + SPI_CMD_REG);
+
+		/* wait for completion */
+		ret = wait_for_bit_be32(priv->regs + SPI_STAT_REG,
+					SPI_STAT_SRCBUSY_MASK, false,
+					1000, false);
+		if (ret) {
+			printf("interrupt timeout\n");
+			return ret;
+		}
+
+		/* copy rx data */
+		if (rx) {
+			memcpy_fromio(rx, priv->regs + HSSPI_FIFO_BASE,
+				      curr_step);
+			rx += curr_step;
+		}
+
+		data_bytes -= curr_step;
+	}
+
+	if (flags & SPI_XFER_END)
+		bcm63xx_hsspi_deactivate_cs(priv);
+
+	return 0;
+}
+
+static const struct dm_spi_ops bcm63xx_hsspi_ops = {
+	.cs_info = bcm63xx_hsspi_cs_info,
+	.set_mode = bcm63xx_hsspi_set_mode,
+	.set_speed = bcm63xx_hsspi_set_speed,
+	.xfer = bcm63xx_hsspi_xfer,
+};
+
+static const struct udevice_id bcm63xx_hsspi_ids[] = {
+	{ .compatible = "brcm,bcm6328-hsspi", },
+	{ /* sentinel */ }
+};
+
+static int bcm63xx_hsspi_child_pre_probe(struct udevice *dev)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev->parent);
+	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+
+	/* check cs */
+	if (plat->cs >= priv->num_cs) {
+		printf("no cs %u\n", plat->cs);
+		return -ENODEV;
+	}
+
+	/* cs polarity */
+	if (plat->mode & SPI_CS_HIGH)
+		priv->cs_pols |= BIT(plat->cs);
+	else
+		priv->cs_pols &= ~BIT(plat->cs);
+
+	return 0;
+}
+
+static int bcm63xx_hsspi_probe(struct udevice *dev)
+{
+	struct bcm63xx_hsspi_priv *priv = dev_get_priv(dev);
+	struct reset_ctl rst_ctl;
+	struct clk clk;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	int ret;
+
+	addr = devfdt_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = ioremap(addr, size);
+	priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+				       "num-cs", 8);
+
+	/* enable clock */
+	ret = clk_get_by_name(dev, "hsspi", &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_free(&clk);
+	if (ret < 0)
+		return ret;
+
+	/* get clock rate */
+	ret = clk_get_by_name(dev, "pll", &clk);
+	if (ret < 0)
+		return ret;
+
+	priv->clk_rate = clk_get_rate(&clk);
+
+	ret = clk_free(&clk);
+	if (ret < 0)
+		return ret;
+
+	/* perform reset */
+	ret = reset_get_by_index(dev, 0, &rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	ret = reset_deassert(&rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	ret = reset_free(&rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	/* initialize hardware */
+	writel_be(0, priv->regs + SPI_IR_MASK_REG);
+
+	/* clear pending interrupts */
+	writel_be(SPI_IR_CLEAR_ALL, priv->regs + SPI_IR_STAT_REG);
+
+	/* enable clk gate */
+	setbits_be32(priv->regs + SPI_CTL_REG, SPI_CTL_CLK_GATE_MASK);
+
+	/* read default cs polarities */
+	priv->cs_pols = readl_be(priv->regs + SPI_CTL_REG) &
+			SPI_CTL_CS_POL_MASK;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(bcm63xx_hsspi) = {
+	.name = "bcm63xx_hsspi",
+	.id = UCLASS_SPI,
+	.of_match = bcm63xx_hsspi_ids,
+	.ops = &bcm63xx_hsspi_ops,
+	.priv_auto_alloc_size = sizeof(struct bcm63xx_hsspi_priv),
+	.child_pre_probe = bcm63xx_hsspi_child_pre_probe,
+	.probe = bcm63xx_hsspi_probe,
+};

+ 433 - 0
drivers/spi/bcm63xx_spi.c

@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/spi/spi-bcm63xx.c:
+ *	Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
+ *	Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <spi.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* BCM6348 SPI core */
+#define SPI_6348_CLK			0x06
+#define SPI_6348_CMD			0x00
+#define SPI_6348_CTL			0x40
+#define SPI_6348_CTL_SHIFT		6
+#define SPI_6348_FILL			0x07
+#define SPI_6348_IR_MASK		0x04
+#define SPI_6348_IR_STAT		0x02
+#define SPI_6348_RX			0x80
+#define SPI_6348_RX_SIZE		0x3f
+#define SPI_6348_TX			0x41
+#define SPI_6348_TX_SIZE		0x3f
+
+/* BCM6358 SPI core */
+#define SPI_6358_CLK			0x706
+#define SPI_6358_CMD			0x700
+#define SPI_6358_CTL			0x000
+#define SPI_6358_CTL_SHIFT		14
+#define SPI_6358_FILL			0x707
+#define SPI_6358_IR_MASK		0x702
+#define SPI_6358_IR_STAT		0x704
+#define SPI_6358_RX			0x400
+#define SPI_6358_RX_SIZE		0x220
+#define SPI_6358_TX			0x002
+#define SPI_6358_TX_SIZE		0x21e
+
+/* SPI Clock register */
+#define SPI_CLK_SHIFT		0
+#define SPI_CLK_20MHZ		(0 << SPI_CLK_SHIFT)
+#define SPI_CLK_0_391MHZ	(1 << SPI_CLK_SHIFT)
+#define SPI_CLK_0_781MHZ	(2 << SPI_CLK_SHIFT)
+#define SPI_CLK_1_563MHZ	(3 << SPI_CLK_SHIFT)
+#define SPI_CLK_3_125MHZ	(4 << SPI_CLK_SHIFT)
+#define SPI_CLK_6_250MHZ	(5 << SPI_CLK_SHIFT)
+#define SPI_CLK_12_50MHZ	(6 << SPI_CLK_SHIFT)
+#define SPI_CLK_25MHZ		(7 << SPI_CLK_SHIFT)
+#define SPI_CLK_MASK		(7 << SPI_CLK_SHIFT)
+#define SPI_CLK_SSOFF_SHIFT	3
+#define SPI_CLK_SSOFF_2		(2 << SPI_CLK_SSOFF_SHIFT)
+#define SPI_CLK_SSOFF_MASK	(7 << SPI_CLK_SSOFF_SHIFT)
+#define SPI_CLK_BSWAP_SHIFT	7
+#define SPI_CLK_BSWAP_MASK	(1 << SPI_CLK_BSWAP_SHIFT)
+
+/* SPI Command register */
+#define SPI_CMD_OP_SHIFT	0
+#define SPI_CMD_OP_START	(0x3 << SPI_CMD_OP_SHIFT)
+#define SPI_CMD_SLAVE_SHIFT	4
+#define SPI_CMD_SLAVE_MASK	(0xf << SPI_CMD_SLAVE_SHIFT)
+#define SPI_CMD_PREPEND_SHIFT	8
+#define SPI_CMD_PREPEND_BYTES	0xf
+#define SPI_CMD_3WIRE_SHIFT	12
+#define SPI_CMD_3WIRE_MASK	(1 << SPI_CMD_3WIRE_SHIFT)
+
+/* SPI Control register */
+#define SPI_CTL_TYPE_FD_RW	0
+#define SPI_CTL_TYPE_HD_W	1
+#define SPI_CTL_TYPE_HD_R	2
+
+/* SPI Interrupt registers */
+#define SPI_IR_DONE_SHIFT	0
+#define SPI_IR_DONE_MASK	(1 << SPI_IR_DONE_SHIFT)
+#define SPI_IR_RXOVER_SHIFT	1
+#define SPI_IR_RXOVER_MASK	(1 << SPI_IR_RXOVER_SHIFT)
+#define SPI_IR_TXUNDER_SHIFT	2
+#define SPI_IR_TXUNDER_MASK	(1 << SPI_IR_TXUNDER_SHIFT)
+#define SPI_IR_TXOVER_SHIFT	3
+#define SPI_IR_TXOVER_MASK	(1 << SPI_IR_TXOVER_SHIFT)
+#define SPI_IR_RXUNDER_SHIFT	4
+#define SPI_IR_RXUNDER_MASK	(1 << SPI_IR_RXUNDER_SHIFT)
+#define SPI_IR_CLEAR_MASK	(SPI_IR_DONE_MASK |\
+				 SPI_IR_RXOVER_MASK |\
+				 SPI_IR_TXUNDER_MASK |\
+				 SPI_IR_TXOVER_MASK |\
+				 SPI_IR_RXUNDER_MASK)
+
+enum bcm63xx_regs_spi {
+	SPI_CLK,
+	SPI_CMD,
+	SPI_CTL,
+	SPI_CTL_SHIFT,
+	SPI_FILL,
+	SPI_IR_MASK,
+	SPI_IR_STAT,
+	SPI_RX,
+	SPI_RX_SIZE,
+	SPI_TX,
+	SPI_TX_SIZE,
+};
+
+struct bcm63xx_spi_priv {
+	const unsigned long *regs;
+	void __iomem *base;
+	size_t tx_bytes;
+	uint8_t num_cs;
+};
+
+#define SPI_CLK_CNT		8
+static const unsigned bcm63xx_spi_freq_table[SPI_CLK_CNT][2] = {
+	{ 25000000, SPI_CLK_25MHZ },
+	{ 20000000, SPI_CLK_20MHZ },
+	{ 12500000, SPI_CLK_12_50MHZ },
+	{  6250000, SPI_CLK_6_250MHZ },
+	{  3125000, SPI_CLK_3_125MHZ },
+	{  1563000, SPI_CLK_1_563MHZ },
+	{   781000, SPI_CLK_0_781MHZ },
+	{   391000, SPI_CLK_0_391MHZ }
+};
+
+static int bcm63xx_spi_cs_info(struct udevice *bus, uint cs,
+			   struct spi_cs_info *info)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+
+	if (cs >= priv->num_cs) {
+		printf("no cs %u\n", cs);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int bcm63xx_spi_set_mode(struct udevice *bus, uint mode)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+	const unsigned long *regs = priv->regs;
+
+	if (mode & SPI_LSB_FIRST)
+		setbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK);
+	else
+		clrbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK);
+
+	return 0;
+}
+
+static int bcm63xx_spi_set_speed(struct udevice *bus, uint speed)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(bus);
+	const unsigned long *regs = priv->regs;
+	uint8_t clk_cfg;
+	int i;
+
+	/* default to lowest clock configuration */
+	clk_cfg = SPI_CLK_0_391MHZ;
+
+	/* find the closest clock configuration */
+	for (i = 0; i < SPI_CLK_CNT; i++) {
+		if (speed >= bcm63xx_spi_freq_table[i][0]) {
+			clk_cfg = bcm63xx_spi_freq_table[i][1];
+			break;
+		}
+	}
+
+	/* write clock configuration */
+	clrsetbits_8(priv->base + regs[SPI_CLK],
+		     SPI_CLK_SSOFF_MASK | SPI_CLK_MASK,
+		     clk_cfg | SPI_CLK_SSOFF_2);
+
+	return 0;
+}
+
+/*
+ * BCM63xx SPI driver doesn't allow keeping CS active between transfers since
+ * they are HW controlled.
+ * However, it provides a mechanism to prepend write transfers prior to read
+ * transfers (with a maximum prepend of 15 bytes), which is usually enough for
+ * SPI-connected flashes since reading requires prepending a write transfer of
+ * 5 bytes.
+ *
+ * This implementation takes advantage of the prepend mechanism and combines
+ * multiple transfers into a single one where possible (single/multiple write
+ * transfer(s) followed by a final read/write transfer).
+ * However, it's not possible to buffer reads, which means that read transfers
+ * should always be done as the final ones.
+ * On the other hand, take into account that combining write transfers into
+ * a single one is just buffering and doesn't require prepend mechanism.
+ */
+static int bcm63xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
+		const void *dout, void *din, unsigned long flags)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent);
+	const unsigned long *regs = priv->regs;
+	size_t data_bytes = bitlen / 8;
+
+	if (flags & SPI_XFER_BEGIN) {
+		/* clear prepends */
+		priv->tx_bytes = 0;
+
+		/* initialize hardware */
+		writeb_be(0, priv->base + regs[SPI_IR_MASK]);
+	}
+
+	if (din) {
+		/* buffering reads not possible since cs is hw controlled */
+		if (!(flags & SPI_XFER_END)) {
+			printf("unable to buffer reads\n");
+			return -EINVAL;
+		}
+
+		/* check rx size */
+		 if (data_bytes > regs[SPI_RX_SIZE]) {
+			printf("max rx bytes exceeded\n");
+			return -EMSGSIZE;
+		}
+	}
+
+	if (dout) {
+		/* check tx size */
+		if (priv->tx_bytes + data_bytes > regs[SPI_TX_SIZE]) {
+			printf("max tx bytes exceeded\n");
+			return -EMSGSIZE;
+		}
+
+		/* copy tx data */
+		memcpy_toio(priv->base + regs[SPI_TX] + priv->tx_bytes,
+			    dout, data_bytes);
+		priv->tx_bytes += data_bytes;
+	}
+
+	if (flags & SPI_XFER_END) {
+		struct dm_spi_slave_platdata *plat =
+			dev_get_parent_platdata(dev);
+		uint16_t val, cmd;
+		int ret;
+
+		/* determine control config */
+		if (dout && !din) {
+			/* buffered write transfers */
+			val = priv->tx_bytes;
+			val |= (SPI_CTL_TYPE_HD_W << regs[SPI_CTL_SHIFT]);
+			priv->tx_bytes = 0;
+		} else {
+			if (dout && din && (flags & SPI_XFER_ONCE)) {
+				/* full duplex read/write */
+				val = data_bytes;
+				val |= (SPI_CTL_TYPE_FD_RW <<
+					regs[SPI_CTL_SHIFT]);
+				priv->tx_bytes = 0;
+			} else {
+				/* prepended write transfer */
+				val = data_bytes;
+				val |= (SPI_CTL_TYPE_HD_R <<
+					regs[SPI_CTL_SHIFT]);
+				if (priv->tx_bytes > SPI_CMD_PREPEND_BYTES) {
+					printf("max prepend bytes exceeded\n");
+					return -EMSGSIZE;
+				}
+			}
+		}
+
+		if (regs[SPI_CTL_SHIFT] >= 8)
+			writew_be(val, priv->base + regs[SPI_CTL]);
+		else
+			writeb_be(val, priv->base + regs[SPI_CTL]);
+
+		/* clear interrupts */
+		writeb_be(SPI_IR_CLEAR_MASK, priv->base + regs[SPI_IR_STAT]);
+
+		/* issue the transfer */
+		cmd = SPI_CMD_OP_START;
+		cmd |= (plat->cs << SPI_CMD_SLAVE_SHIFT) & SPI_CMD_SLAVE_MASK;
+		cmd |= (priv->tx_bytes << SPI_CMD_PREPEND_SHIFT);
+		if (plat->mode & SPI_3WIRE)
+			cmd |= SPI_CMD_3WIRE_MASK;
+		writew_be(cmd, priv->base + regs[SPI_CMD]);
+
+		/* enable interrupts */
+		writeb_be(SPI_IR_DONE_MASK, priv->base + regs[SPI_IR_MASK]);
+
+		ret = wait_for_bit_8(priv->base + regs[SPI_IR_STAT],
+				     SPI_IR_DONE_MASK, true, 1000, false);
+		if (ret) {
+			printf("interrupt timeout\n");
+			return ret;
+		}
+
+		/* copy rx data */
+		if (din)
+			memcpy_fromio(din, priv->base + regs[SPI_RX],
+				      data_bytes);
+	}
+
+	return 0;
+}
+
+static const struct dm_spi_ops bcm63xx_spi_ops = {
+	.cs_info = bcm63xx_spi_cs_info,
+	.set_mode = bcm63xx_spi_set_mode,
+	.set_speed = bcm63xx_spi_set_speed,
+	.xfer = bcm63xx_spi_xfer,
+};
+
+static const unsigned long bcm6348_spi_regs[] = {
+	[SPI_CLK] = SPI_6348_CLK,
+	[SPI_CMD] = SPI_6348_CMD,
+	[SPI_CTL] = SPI_6348_CTL,
+	[SPI_CTL_SHIFT] = SPI_6348_CTL_SHIFT,
+	[SPI_FILL] = SPI_6348_FILL,
+	[SPI_IR_MASK] = SPI_6348_IR_MASK,
+	[SPI_IR_STAT] = SPI_6348_IR_STAT,
+	[SPI_RX] = SPI_6348_RX,
+	[SPI_RX_SIZE] = SPI_6348_RX_SIZE,
+	[SPI_TX] = SPI_6348_TX,
+	[SPI_TX_SIZE] = SPI_6348_TX_SIZE,
+};
+
+static const unsigned long bcm6358_spi_regs[] = {
+	[SPI_CLK] = SPI_6358_CLK,
+	[SPI_CMD] = SPI_6358_CMD,
+	[SPI_CTL] = SPI_6358_CTL,
+	[SPI_CTL_SHIFT] = SPI_6358_CTL_SHIFT,
+	[SPI_FILL] = SPI_6358_FILL,
+	[SPI_IR_MASK] = SPI_6358_IR_MASK,
+	[SPI_IR_STAT] = SPI_6358_IR_STAT,
+	[SPI_RX] = SPI_6358_RX,
+	[SPI_RX_SIZE] = SPI_6358_RX_SIZE,
+	[SPI_TX] = SPI_6358_TX,
+	[SPI_TX_SIZE] = SPI_6358_TX_SIZE,
+};
+
+static const struct udevice_id bcm63xx_spi_ids[] = {
+	{
+		.compatible = "brcm,bcm6348-spi",
+		.data = (ulong)&bcm6348_spi_regs,
+	}, {
+		.compatible = "brcm,bcm6358-spi",
+		.data = (ulong)&bcm6358_spi_regs,
+	}, { /* sentinel */ }
+};
+
+static int bcm63xx_spi_child_pre_probe(struct udevice *dev)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent);
+	const unsigned long *regs = priv->regs;
+	struct spi_slave *slave = dev_get_parent_priv(dev);
+	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+
+	/* check cs */
+	if (plat->cs >= priv->num_cs) {
+		printf("no cs %u\n", plat->cs);
+		return -ENODEV;
+	}
+
+	/* max read/write sizes */
+	slave->max_read_size = regs[SPI_RX_SIZE];
+	slave->max_write_size = regs[SPI_TX_SIZE];
+
+	return 0;
+}
+
+static int bcm63xx_spi_probe(struct udevice *dev)
+{
+	struct bcm63xx_spi_priv *priv = dev_get_priv(dev);
+	const unsigned long *regs =
+		(const unsigned long *)dev_get_driver_data(dev);
+	struct reset_ctl rst_ctl;
+	struct clk clk;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	int ret;
+
+	addr = devfdt_get_addr_size_index(dev, 0, &size);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->regs = regs;
+	priv->base = ioremap(addr, size);
+	priv->num_cs = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+				       "num-cs", 8);
+
+	/* enable clock */
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_free(&clk);
+	if (ret < 0)
+		return ret;
+
+	/* perform reset */
+	ret = reset_get_by_index(dev, 0, &rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	ret = reset_deassert(&rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	ret = reset_free(&rst_ctl);
+	if (ret < 0)
+		return ret;
+
+	/* initialize hardware */
+	writeb_be(0, priv->base + regs[SPI_IR_MASK]);
+
+	/* set fill register */
+	writeb_be(0xff, priv->base + regs[SPI_FILL]);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(bcm63xx_spi) = {
+	.name = "bcm63xx_spi",
+	.id = UCLASS_SPI,
+	.of_match = bcm63xx_spi_ids,
+	.ops = &bcm63xx_spi_ops,
+	.priv_auto_alloc_size = sizeof(struct bcm63xx_spi_priv),
+	.child_pre_probe = bcm63xx_spi_child_pre_probe,
+	.probe = bcm63xx_spi_probe,
+};

+ 12 - 8
drivers/spi/cadence_qspi.c

@@ -212,7 +212,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
 	/* Set Chip select */
 	cadence_qspi_apb_chipselect(base, spi_chip_select(dev),
-				    CONFIG_CQSPI_DECODER);
+				    plat->is_decoded_cs);
 
 	if ((flags & SPI_XFER_END) || (flags == 0)) {
 		if (priv->cmd_len == 0) {
@@ -296,7 +296,11 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 
 	plat->regbase = (void *)data[0];
 	plat->ahbbase = (void *)data[2];
-	plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);
+	plat->is_decoded_cs = fdtdec_get_bool(blob, node, "cdns,is-decoded-cs");
+	plat->fifo_depth = fdtdec_get_uint(blob, node, "cdns,fifo-depth", 128);
+	plat->fifo_width = fdtdec_get_uint(blob, node, "cdns,fifo-width", 4);
+	plat->trigger_address = fdtdec_get_uint(blob, node,
+						"cdns,trigger-address", 0);
 
 	/* All other paramters are embedded in the child node */
 	subnode = fdt_first_subnode(blob, node);
@@ -310,12 +314,12 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 				       500000);
 
 	/* Read other parameters from DT */
-	plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256);
-	plat->block_size = fdtdec_get_int(blob, subnode, "block-size", 16);
-	plat->tshsl_ns = fdtdec_get_int(blob, subnode, "tshsl-ns", 200);
-	plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255);
-	plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20);
-	plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20);
+	plat->page_size = fdtdec_get_uint(blob, subnode, "page-size", 256);
+	plat->block_size = fdtdec_get_uint(blob, subnode, "block-size", 16);
+	plat->tshsl_ns = fdtdec_get_uint(blob, subnode, "cdns,tshsl-ns", 200);
+	plat->tsd2d_ns = fdtdec_get_uint(blob, subnode, "cdns,tsd2d-ns", 255);
+	plat->tchsh_ns = fdtdec_get_uint(blob, subnode, "cdns,tchsh-ns", 20);
+	plat->tslch_ns = fdtdec_get_uint(blob, subnode, "cdns,tslch-ns", 20);
 
 	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
 	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,

+ 5 - 1
drivers/spi/cadence_qspi.h

@@ -18,14 +18,18 @@ struct cadence_spi_platdata {
 	unsigned int	max_hz;
 	void		*regbase;
 	void		*ahbbase;
+	bool		is_decoded_cs;
+	u32		fifo_depth;
+	u32		fifo_width;
+	u32		trigger_address;
 
+	/* Flash parameters */
 	u32		page_size;
 	u32		block_size;
 	u32		tshsl_ns;
 	u32		tsd2d_ns;
 	u32		tchsh_ns;
 	u32		tslch_ns;
-	u32		sram_size;
 };
 
 struct cadence_spi_priv {

+ 37 - 45
drivers/spi/cadence_qspi_apb.c

@@ -30,17 +30,13 @@
 #include <linux/errno.h>
 #include <wait_bit.h>
 #include <spi.h>
-#include <bouncebuf.h>
+#include <malloc.h>
 #include "cadence_qspi.h"
 
 #define CQSPI_REG_POLL_US			1 /* 1us */
 #define CQSPI_REG_RETRY				10000
 #define CQSPI_POLL_IDLE_RETRY			3
 
-#define CQSPI_FIFO_WIDTH			4
-
-#define CQSPI_REG_SRAM_THRESHOLD_WORDS		50
-
 /* Transfer mode */
 #define CQSPI_INST_TYPE_SINGLE			0
 #define CQSPI_INST_TYPE_DUAL			1
@@ -51,9 +47,6 @@
 #define CQSPI_DUMMY_CLKS_PER_BYTE		8
 #define CQSPI_DUMMY_BYTES_MAX			4
 
-#define CQSPI_REG_SRAM_FILL_THRESHOLD	\
-	((CQSPI_REG_SRAM_SIZE_WORD / 2) * CQSPI_FIFO_WIDTH)
-
 /****************************************************************************
  * Controller's configuration and status register (offset from QSPI_BASE)
  ****************************************************************************/
@@ -400,7 +393,7 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat)
 	writel(0, plat->regbase + CQSPI_REG_REMAP);
 
 	/* Indirect mode configurations */
-	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+	writel(plat->fifo_depth / 2, plat->regbase + CQSPI_REG_SRAMPARTITION);
 
 	/* Disable all interrupts */
 	writel(0, plat->regbase + CQSPI_REG_IRQMASK);
@@ -560,7 +553,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
 		addr_bytes = cmdlen - 1;
 
 	/* Setup the indirect trigger address */
-	writel((u32)plat->ahbbase,
+	writel(plat->trigger_address,
 	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
 	/* Configure the opcode */
@@ -634,8 +627,6 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 {
 	unsigned int remaining = n_rx;
 	unsigned int bytes_to_read = 0;
-	struct bounce_buffer bb;
-	u8 *bb_rxbuf;
 	int ret;
 
 	writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES);
@@ -644,11 +635,6 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 	writel(CQSPI_REG_INDIRECTRD_START,
 	       plat->regbase + CQSPI_REG_INDIRECTRD);
 
-	ret = bounce_buffer_start(&bb, (void *)rxbuf, n_rx, GEN_BB_WRITE);
-	if (ret)
-		return ret;
-	bb_rxbuf = bb.bounce_buffer;
-
 	while (remaining > 0) {
 		ret = cadence_qspi_wait_for_data(plat);
 		if (ret < 0) {
@@ -659,24 +645,27 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 		bytes_to_read = ret;
 
 		while (bytes_to_read != 0) {
-			bytes_to_read *= CQSPI_FIFO_WIDTH;
+			bytes_to_read *= plat->fifo_width;
 			bytes_to_read = bytes_to_read > remaining ?
 					remaining : bytes_to_read;
-			readsl(plat->ahbbase, bb_rxbuf, bytes_to_read >> 2);
-			if (bytes_to_read % 4)
-				readsb(plat->ahbbase,
-				       bb_rxbuf + rounddown(bytes_to_read, 4),
-				       bytes_to_read % 4);
-
-			bb_rxbuf += bytes_to_read;
+			/*
+			 * Handle non-4-byte aligned access to avoid
+			 * data abort.
+			 */
+			if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4))
+				readsb(plat->ahbbase, rxbuf, bytes_to_read);
+			else
+				readsl(plat->ahbbase, rxbuf,
+				       bytes_to_read >> 2);
+			rxbuf += bytes_to_read;
 			remaining -= bytes_to_read;
 			bytes_to_read = cadence_qspi_get_rd_sram_level(plat);
 		}
 	}
 
 	/* Check indirect done status */
-	ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTRD,
-			   CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
+	ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD,
+				CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
 	if (ret) {
 		printf("Indirect read completion error (%i)\n", ret);
 		goto failrd;
@@ -685,7 +674,6 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 	/* Clear indirect completion status */
 	writel(CQSPI_REG_INDIRECTRD_DONE,
 	       plat->regbase + CQSPI_REG_INDIRECTRD);
-	bounce_buffer_stop(&bb);
 
 	return 0;
 
@@ -693,7 +681,6 @@ failrd:
 	/* Cancel the indirect read */
 	writel(CQSPI_REG_INDIRECTRD_CANCEL,
 	       plat->regbase + CQSPI_REG_INDIRECTRD);
-	bounce_buffer_stop(&bb);
 	return ret;
 }
 
@@ -710,7 +697,7 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
 		return -EINVAL;
 	}
 	/* Setup the indirect trigger address */
-	writel((u32)plat->ahbbase,
+	writel(plat->trigger_address,
 	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
 	/* Configure the opcode */
@@ -733,19 +720,22 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
 {
 	unsigned int page_size = plat->page_size;
 	unsigned int remaining = n_tx;
+	const u8 *bb_txbuf = txbuf;
+	void *bounce_buf = NULL;
 	unsigned int write_bytes;
 	int ret;
-	struct bounce_buffer bb;
-	u8 *bb_txbuf;
 
 	/*
-	 * Handle non-4-byte aligned accesses via bounce buffer to
-	 * avoid data abort.
+	 * Use bounce buffer for non 32 bit aligned txbuf to avoid data
+	 * aborts
 	 */
-	ret = bounce_buffer_start(&bb, (void *)txbuf, n_tx, GEN_BB_READ);
-	if (ret)
-		return ret;
-	bb_txbuf = bb.bounce_buffer;
+	if ((uintptr_t)txbuf % 4) {
+		bounce_buf = malloc(n_tx);
+		if (!bounce_buf)
+			return -ENOMEM;
+		memcpy(bounce_buf, txbuf, n_tx);
+		bb_txbuf = bounce_buf;
+	}
 
 	/* Configure the indirect read transfer bytes */
 	writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES);
@@ -762,9 +752,9 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
 				bb_txbuf + rounddown(write_bytes, 4),
 				write_bytes % 4);
 
-		ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL,
-				   CQSPI_REG_SDRAMLEVEL_WR_MASK <<
-				   CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
+		ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_SDRAMLEVEL,
+					CQSPI_REG_SDRAMLEVEL_WR_MASK <<
+					CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
 		if (ret) {
 			printf("Indirect write timed out (%i)\n", ret);
 			goto failwr;
@@ -775,24 +765,26 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
 	}
 
 	/* Check indirect done status */
-	ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTWR,
-			   CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
+	ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR,
+				CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
 	if (ret) {
 		printf("Indirect write completion error (%i)\n", ret);
 		goto failwr;
 	}
-	bounce_buffer_stop(&bb);
 
 	/* Clear indirect completion status */
 	writel(CQSPI_REG_INDIRECTWR_DONE,
 	       plat->regbase + CQSPI_REG_INDIRECTWR);
+	if (bounce_buf)
+		free(bounce_buf);
 	return 0;
 
 failwr:
 	/* Cancel the indirect write */
 	writel(CQSPI_REG_INDIRECTWR_CANCEL,
 	       plat->regbase + CQSPI_REG_INDIRECTWR);
-	bounce_buffer_stop(&bb);
+	if (bounce_buf)
+		free(bounce_buf);
 	return ret;
 }
 

+ 43 - 2
drivers/spi/designware_spi.c

@@ -11,6 +11,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <errno.h>
 #include <malloc.h>
@@ -18,7 +19,6 @@
 #include <fdtdec.h>
 #include <linux/compat.h>
 #include <asm/io.h>
-#include <asm/arch/clock_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -94,6 +94,8 @@ struct dw_spi_priv {
 	void __iomem *regs;
 	unsigned int freq;		/* Default frequency */
 	unsigned int mode;
+	struct clk clk;
+	unsigned long bus_clk_rate;
 
 	int bits_per_word;
 	u8 cs;			/* chip select pin */
@@ -176,14 +178,53 @@ static void spi_hw_init(struct dw_spi_priv *priv)
 	debug("%s: fifo_len=%d\n", __func__, priv->fifo_len);
 }
 
+/*
+ * We define dw_spi_get_clk function as 'weak' as some targets
+ * (like SOCFPGA_GEN5 and SOCFPGA_ARRIA10) don't use standard clock API
+ * and implement dw_spi_get_clk their own way in their clock manager.
+ */
+__weak int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+{
+	struct dw_spi_priv *priv = dev_get_priv(bus);
+	int ret;
+
+	ret = clk_get_by_index(bus, 0, &priv->clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
+		return ret;
+
+	*rate = clk_get_rate(&priv->clk);
+	if (!*rate)
+		goto err_rate;
+
+	debug("%s: get spi controller clk via device tree: %lu Hz\n",
+	      __func__, *rate);
+
+	return 0;
+
+err_rate:
+	clk_disable(&priv->clk);
+	clk_free(&priv->clk);
+
+	return -EINVAL;
+}
+
 static int dw_spi_probe(struct udevice *bus)
 {
 	struct dw_spi_platdata *plat = dev_get_platdata(bus);
 	struct dw_spi_priv *priv = dev_get_priv(bus);
+	int ret;
 
 	priv->regs = plat->regs;
 	priv->freq = plat->frequency;
 
+	ret = dw_spi_get_clk(bus, &priv->bus_clk_rate);
+	if (ret)
+		return ret;
+
 	/* Currently only bits_per_word == 8 supported */
 	priv->bits_per_word = 8;
 
@@ -369,7 +410,7 @@ static int dw_spi_set_speed(struct udevice *bus, uint speed)
 	spi_enable_chip(priv, 0);
 
 	/* clk_div doesn't support odd number */
-	clk_div = cm_get_spi_controller_clk_hz() / speed;
+	clk_div = priv->bus_clk_rate / speed;
 	clk_div = (clk_div + 1) & 0xfffe;
 	dw_writel(priv, DW_SPI_BAUDR, clk_div);
 

+ 10 - 10
drivers/spi/fsl_qspi.c

@@ -1018,11 +1018,11 @@ static int fsl_qspi_probe(struct udevice *bus)
 	priv->num_chipselect = plat->num_chipselect;
 
 	/* make sure controller is not busy anywhere */
-	ret = wait_for_bit(__func__, &priv->regs->sr,
-			   QSPI_SR_BUSY_MASK |
-			   QSPI_SR_AHB_ACC_MASK |
-			   QSPI_SR_IP_ACC_MASK,
-			   false, 100, false);
+	ret = wait_for_bit_le32(&priv->regs->sr,
+				QSPI_SR_BUSY_MASK |
+				QSPI_SR_AHB_ACC_MASK |
+				QSPI_SR_IP_ACC_MASK,
+				false, 100, false);
 
 	if (ret) {
 		debug("ERROR : The controller is busy\n");
@@ -1185,11 +1185,11 @@ static int fsl_qspi_claim_bus(struct udevice *dev)
 	priv = dev_get_priv(bus);
 
 	/* make sure controller is not busy anywhere */
-	ret = wait_for_bit(__func__, &priv->regs->sr,
-			   QSPI_SR_BUSY_MASK |
-			   QSPI_SR_AHB_ACC_MASK |
-			   QSPI_SR_IP_ACC_MASK,
-			   false, 100, false);
+	ret = wait_for_bit_le32(&priv->regs->sr,
+				QSPI_SR_BUSY_MASK |
+				QSPI_SR_AHB_ACC_MASK |
+				QSPI_SR_IP_ACC_MASK,
+				false, 100, false);
 
 	if (ret) {
 		debug("ERROR : The controller is busy\n");

+ 66 - 3
drivers/spi/kirkwood_spi.c

@@ -243,6 +243,10 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
 /* Here now the DM part */
 
+struct mvebu_spi_dev {
+	bool			is_errata_50mhz_ac;
+};
+
 struct mvebu_spi_platdata {
 	struct kwspi_registers *spireg;
 };
@@ -269,10 +273,44 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)
 	return 0;
 }
 
+static void mvebu_spi_50mhz_ac_timing_erratum(struct udevice *bus, uint mode)
+{
+	struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+	struct kwspi_registers *reg = plat->spireg;
+	u32 data;
+
+	/*
+	 * Erratum description: (Erratum NO. FE-9144572) The device
+	 * SPI interface supports frequencies of up to 50 MHz.
+	 * However, due to this erratum, when the device core clock is
+	 * 250 MHz and the SPI interfaces is configured for 50MHz SPI
+	 * clock and CPOL=CPHA=1 there might occur data corruption on
+	 * reads from the SPI device.
+	 * Erratum Workaround:
+	 * Work in one of the following configurations:
+	 * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration
+	 * Register".
+	 * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1
+	 * Register" before setting the interface.
+	 */
+	data = readl(&reg->timing1);
+	data &= ~KW_SPI_TMISO_SAMPLE_MASK;
+
+	if (CONFIG_SYS_TCLK == 250000000 &&
+	    mode & SPI_CPOL &&
+	    mode & SPI_CPHA)
+		data |= KW_SPI_TMISO_SAMPLE_2;
+	else
+		data |= KW_SPI_TMISO_SAMPLE_1;
+
+	writel(data, &reg->timing1);
+}
+
 static int mvebu_spi_set_mode(struct udevice *bus, uint mode)
 {
 	struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
 	struct kwspi_registers *reg = plat->spireg;
+	const struct mvebu_spi_dev *drvdata;
 	u32 data = readl(&reg->cfg);
 
 	data &= ~(KWSPI_CPHA | KWSPI_CPOL | KWSPI_RXLSBF | KWSPI_TXLSBF);
@@ -286,6 +324,10 @@ static int mvebu_spi_set_mode(struct udevice *bus, uint mode)
 
 	writel(data, &reg->cfg);
 
+	drvdata = (struct mvebu_spi_dev *)dev_get_driver_data(bus);
+	if (drvdata->is_errata_50mhz_ac)
+		mvebu_spi_50mhz_ac_timing_erratum(bus, mode);
+
 	return 0;
 }
 
@@ -343,10 +385,31 @@ static const struct dm_spi_ops mvebu_spi_ops = {
 	 */
 };
 
+static const struct mvebu_spi_dev armada_xp_spi_dev_data = {
+	.is_errata_50mhz_ac = false,
+};
+
+static const struct mvebu_spi_dev armada_375_spi_dev_data = {
+	.is_errata_50mhz_ac = false,
+};
+
+static const struct mvebu_spi_dev armada_380_spi_dev_data = {
+	.is_errata_50mhz_ac = true,
+};
+
 static const struct udevice_id mvebu_spi_ids[] = {
-	{ .compatible = "marvell,armada-375-spi" },
-	{ .compatible = "marvell,armada-380-spi" },
-	{ .compatible = "marvell,armada-xp-spi" },
+	{
+		.compatible = "marvell,armada-375-spi",
+		.data = (ulong)&armada_375_spi_dev_data
+	},
+	{
+		.compatible = "marvell,armada-380-spi",
+		.data = (ulong)&armada_380_spi_dev_data
+	},
+	{
+		.compatible = "marvell,armada-xp-spi",
+		.data = (ulong)&armada_xp_spi_dev_data
+	},
 	{ }
 };
 

+ 11 - 9
drivers/spi/mvebu_a3700_spi.c

@@ -95,8 +95,9 @@ static int spi_legacy_shift_byte(struct spi_reg *reg, unsigned int bytelen,
 	din_8 = din;
 
 	while (bytelen) {
-		ret = wait_for_bit(__func__, &reg->ctrl,
-				   MVEBU_SPI_A3700_XFER_RDY, true, 100, false);
+		ret = wait_for_bit_le32(&reg->ctrl,
+					MVEBU_SPI_A3700_XFER_RDY,
+					true,100, false);
 		if (ret)
 			return ret;
 
@@ -109,9 +110,9 @@ static int spi_legacy_shift_byte(struct spi_reg *reg, unsigned int bytelen,
 		writel(pending_dout, &reg->dout);
 
 		if (din) {
-			ret = wait_for_bit(__func__, &reg->ctrl,
-					   MVEBU_SPI_A3700_XFER_RDY,
-					   true, 100, false);
+			ret = wait_for_bit_le32(&reg->ctrl,
+						MVEBU_SPI_A3700_XFER_RDY,
+						true, 100, false);
 			if (ret)
 				return ret;
 
@@ -160,8 +161,9 @@ static int mvebu_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
 	/* Deactivate CS */
 	if (flags & SPI_XFER_END) {
-		ret = wait_for_bit(__func__, &reg->ctrl,
-				   MVEBU_SPI_A3700_XFER_RDY, true, 100, false);
+		ret = wait_for_bit_le32(&reg->ctrl,
+					MVEBU_SPI_A3700_XFER_RDY,
+					true, 100, false);
 		if (ret)
 			return ret;
 
@@ -231,8 +233,8 @@ static int mvebu_spi_probe(struct udevice *bus)
 	/* Flush read/write FIFO */
 	data = readl(&reg->cfg);
 	writel(data | MVEBU_SPI_A3700_FIFO_FLUSH, &reg->cfg);
-	ret = wait_for_bit(__func__, &reg->cfg, MVEBU_SPI_A3700_FIFO_FLUSH,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&reg->cfg, MVEBU_SPI_A3700_FIFO_FLUSH,
+				false, 1000, false);
 	if (ret)
 		return ret;
 

+ 2 - 19
drivers/spi/spi-uclass.c

@@ -50,7 +50,6 @@ int dm_spi_claim_bus(struct udevice *dev)
 	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 	struct spi_slave *slave = dev_get_parent_priv(dev);
 	int speed;
-	int ret;
 
 	speed = slave->max_hz;
 	if (spi->max_hz) {
@@ -62,7 +61,8 @@ int dm_spi_claim_bus(struct udevice *dev)
 	if (!speed)
 		speed = 100000;
 	if (speed != slave->speed) {
-		ret = spi_set_speed_mode(bus, speed, slave->mode);
+		int ret = spi_set_speed_mode(bus, speed, slave->mode);
+
 		if (ret)
 			return ret;
 		slave->speed = speed;
@@ -129,7 +129,6 @@ static int spi_post_probe(struct udevice *bus)
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 	struct dm_spi_ops *ops = spi_get_ops(bus);
 
-
 	if (ops->claim_bus)
 		ops->claim_bus += gd->reloc_off;
 	if (ops->release_bus)
@@ -347,22 +346,6 @@ err:
 	return ret;
 }
 
-/* Compatibility function - to be removed */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
-				      int bus_node)
-{
-	struct udevice *bus, *dev;
-	int ret;
-
-	ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
-	if (ret)
-		return NULL;
-	ret = device_get_child_by_of_offset(bus, node, &dev);
-	if (ret)
-		return NULL;
-	return dev_get_parent_priv(dev);
-}
-
 /* Compatibility function - to be removed */
 struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
 				  unsigned int speed, unsigned int mode)

+ 4 - 23
drivers/spi/spi.c

@@ -12,7 +12,7 @@
 int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen)
 {
 	if (wordlen == 0 || wordlen > 32) {
-		printf("spi: invalid wordlen %d\n", wordlen);
+		printf("spi: invalid wordlen %u\n", wordlen);
 		return -1;
 	}
 
@@ -24,11 +24,12 @@ int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen)
 void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
 			 unsigned int cs)
 {
-	struct spi_slave *slave;
-	void *ptr;
+	u8 *ptr;
 
 	ptr = malloc(size);
 	if (ptr) {
+		struct spi_slave *slave;
+
 		memset(ptr, '\0', size);
 		slave = (struct spi_slave *)(ptr + offset);
 		slave->bus = bus;
@@ -38,23 +39,3 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
 
 	return ptr;
 }
-
-#ifdef CONFIG_OF_SPI
-struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
-					   int node)
-{
-	int cs, max_hz, mode = 0;
-
-	cs = fdtdec_get_int(blob, node, "reg", -1);
-	max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000);
-	if (fdtdec_get_bool(blob, node, "spi-cpol"))
-		mode |= SPI_CPOL;
-	if (fdtdec_get_bool(blob, node, "spi-cpha"))
-		mode |= SPI_CPHA;
-	if (fdtdec_get_bool(blob, node, "spi-cs-high"))
-		mode |= SPI_CS_HIGH;
-	if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
-		mode |= SPI_PREAMBLE;
-	return spi_setup_slave(busnum, cs, max_hz, mode);
-}
-#endif

+ 12 - 12
drivers/usb/host/dwc2.c

@@ -108,8 +108,8 @@ static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
 
 	writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
 	       &regs->grstctl);
-	ret = wait_for_bit(__func__, &regs->grstctl, DWC2_GRSTCTL_TXFFLSH,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH,
+				false, 1000, false);
 	if (ret)
 		printf("%s: Timeout!\n", __func__);
 
@@ -127,8 +127,8 @@ static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs)
 	int ret;
 
 	writel(DWC2_GRSTCTL_RXFFLSH, &regs->grstctl);
-	ret = wait_for_bit(__func__, &regs->grstctl, DWC2_GRSTCTL_RXFFLSH,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH,
+				false, 1000, false);
 	if (ret)
 		printf("%s: Timeout!\n", __func__);
 
@@ -145,15 +145,15 @@ static void dwc_otg_core_reset(struct dwc2_core_regs *regs)
 	int ret;
 
 	/* Wait for AHB master IDLE state. */
-	ret = wait_for_bit(__func__, &regs->grstctl, DWC2_GRSTCTL_AHBIDLE,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE,
+				true, 1000, false);
 	if (ret)
 		printf("%s: Timeout!\n", __func__);
 
 	/* Core Soft Reset */
 	writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
-	ret = wait_for_bit(__func__, &regs->grstctl, DWC2_GRSTCTL_CSFTRST,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->grstctl, DWC2_GRSTCTL_CSFTRST,
+				false, 1000, false);
 	if (ret)
 		printf("%s: Timeout!\n", __func__);
 
@@ -267,8 +267,8 @@ static void dwc_otg_core_host_init(struct udevice *dev,
 		clrsetbits_le32(&regs->hc_regs[i].hcchar,
 				DWC2_HCCHAR_EPDIR,
 				DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
-		ret = wait_for_bit(__func__, &regs->hc_regs[i].hcchar,
-				   DWC2_HCCHAR_CHEN, false, 1000, false);
+		ret = wait_for_bit_le32(&regs->hc_regs[i].hcchar,
+					DWC2_HCCHAR_CHEN, false, 1000, false);
 		if (ret)
 			printf("%s: Timeout!\n", __func__);
 	}
@@ -783,8 +783,8 @@ int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle)
 	int ret;
 	uint32_t hcint, hctsiz;
 
-	ret = wait_for_bit(__func__, &hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
-			   1000, false);
+	ret = wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
+				1000, false);
 	if (ret)
 		return ret;
 

+ 1 - 2
drivers/usb/host/ehci-msm.c

@@ -133,8 +133,7 @@ static int ehci_usb_remove(struct udevice *dev)
 	setbits_le32(&ehci->usbcmd, CMD_RESET);
 
 	/* Wait for reset */
-	if (wait_for_bit(__func__, &ehci->usbcmd, CMD_RESET, false, 30,
-			 false)) {
+	if (wait_for_bit_le32(&ehci->usbcmd, CMD_RESET, false, 30, false)) {
 		printf("Stuck on USB reset.\n");
 		return -ETIMEDOUT;
 	}

+ 2 - 3
drivers/usb/host/ehci-mx6.c

@@ -142,13 +142,12 @@ static int usb_phy_enable(int index, struct usb_ehci *ehci)
 
 	/* Stop then Reset */
 	clrbits_le32(usb_cmd, UCMD_RUN_STOP);
-	ret = wait_for_bit(__func__, usb_cmd, UCMD_RUN_STOP, false, 10000,
-			   false);
+	ret = wait_for_bit_le32(usb_cmd, UCMD_RUN_STOP, false, 10000, false);
 	if (ret)
 		return ret;
 
 	setbits_le32(usb_cmd, UCMD_RESET);
-	ret = wait_for_bit(__func__, usb_cmd, UCMD_RESET, false, 10000, false);
+	ret = wait_for_bit_le32(usb_cmd, UCMD_RESET, false, 10000, false);
 	if (ret)
 		return ret;
 

+ 6 - 6
drivers/usb/host/ohci-lpc32xx.c

@@ -143,8 +143,8 @@ static int usbpll_setup(void)
 	setbits_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_POSTDIV_2POW(0x01));
 	setbits_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_PWRUP);
 
-	ret = wait_for_bit(__func__, &clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_STS,
-			   true, CONFIG_SYS_HZ, false);
+	ret = wait_for_bit_le32(&clk_pwr->usb_ctrl, CLK_USBCTRL_PLL_STS,
+				true, CONFIG_SYS_HZ, false);
 	if (ret)
 		return ret;
 
@@ -178,8 +178,8 @@ int usb_cpu_init(void)
 
 	/* enable I2C clock */
 	writel(OTG_CLK_I2C_EN, &otg->otg_clk_ctrl);
-	ret = wait_for_bit(__func__, &otg->otg_clk_sts, OTG_CLK_I2C_EN, true,
-			   CONFIG_SYS_HZ, false);
+	ret = wait_for_bit_le32(&otg->otg_clk_sts, OTG_CLK_I2C_EN, true,
+				CONFIG_SYS_HZ, false);
 	if (ret)
 		return ret;
 
@@ -199,8 +199,8 @@ int usb_cpu_init(void)
 			 OTG_CLK_I2C_EN | OTG_CLK_HOST_EN;
 	writel(mask, &otg->otg_clk_ctrl);
 
-	ret = wait_for_bit(__func__, &otg->otg_clk_sts, mask, true,
-			   CONFIG_SYS_HZ, false);
+	ret = wait_for_bit_le32(&otg->otg_clk_sts, mask, true,
+				CONFIG_SYS_HZ, false);
 	if (ret)
 		return ret;
 

+ 6 - 6
drivers/usb/host/xhci-rcar.c

@@ -55,18 +55,18 @@ static int xhci_rcar_download_fw(struct rcar_xhci *ctx, const u32 *fw_data,
 		setbits_le32(regs + RCAR_USB3_DL_CTRL,
 			     RCAR_USB3_DL_CTRL_FW_SET_DATA0);
 
-		ret = wait_for_bit("xhci-rcar", regs + RCAR_USB3_DL_CTRL,
-				   RCAR_USB3_DL_CTRL_FW_SET_DATA0, false,
-				   10, false);
+		ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
+					RCAR_USB3_DL_CTRL_FW_SET_DATA0, false,
+					10, false);
 		if (ret)
 			break;
 	}
 
 	clrbits_le32(regs + RCAR_USB3_DL_CTRL, RCAR_USB3_DL_CTRL_ENABLE);
 
-	ret = wait_for_bit("xhci-rcar", regs + RCAR_USB3_DL_CTRL,
-			   RCAR_USB3_DL_CTRL_FW_SUCCESS, true,
-			   10, false);
+	ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
+				RCAR_USB3_DL_CTRL_FW_SUCCESS, true,
+				10, false);
 
 	return ret;
 }

+ 32 - 32
drivers/video/atmel_hlcdfb.c

@@ -70,26 +70,26 @@ void lcd_ctrl_init(void *lcdbase)
 
 	/* Disable DISP signal */
 	writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable synchronization */
 	writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable pixel clock */
 	writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable PWM */
 	writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 
@@ -215,26 +215,26 @@ void lcd_ctrl_init(void *lcdbase)
 	/* Enable LCD */
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 
@@ -299,26 +299,26 @@ static void atmel_hlcdc_init(struct udevice *dev)
 
 	/* Disable DISP signal */
 	writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable synchronization */
 	writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable pixel clock */
 	writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	/* Disable PWM */
 	writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
-			   false, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+				false, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 
@@ -451,26 +451,26 @@ static void atmel_hlcdc_init(struct udevice *dev)
 	/* Enable LCD */
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 	value = readl(&regs->lcdc_lcden);
 	writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
-	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
-			   true, 1000, false);
+	ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
+				true, 1000, false);
 	if (ret)
 		printf("%s: %d: Timeout!\n", __func__, __LINE__);
 }

+ 0 - 2
include/configs/k2g_evm.h

@@ -95,8 +95,6 @@
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_CADENCE_QSPI
 #define CONFIG_CQSPI_REF_CLK 384000000
-#define CONFIG_CQSPI_DECODER 0x0
-#define CONFIG_BOUNCE_BUFFER
 #endif
 
 #define SPI_MTD_PARTS	KEYSTONE_SPI1_MTD_PARTS

+ 0 - 2
include/configs/socfpga_common.h

@@ -184,8 +184,6 @@ unsigned int cm_get_l4_sp_clk_hz(void);
 unsigned int cm_get_qspi_controller_clk_hz(void);
 #define CONFIG_CQSPI_REF_CLK		cm_get_qspi_controller_clk_hz()
 #endif
-#define CONFIG_CQSPI_DECODER		0
-#define CONFIG_BOUNCE_BUFFER
 
 /*
  * Designware SPI support

+ 0 - 2
include/configs/stv0991.h

@@ -63,9 +63,7 @@
 + * QSPI support
 + */
 #ifdef CONFIG_OF_CONTROL		/* QSPI is controlled via DT */
-#define CONFIG_CQSPI_DECODER		0
 #define CONFIG_CQSPI_REF_CLK		((30/4)/2)*1000*1000
-#define CONFIG_BOUNCE_BUFFER
 
 #endif
 

+ 4 - 28
include/spi.h

@@ -86,8 +86,10 @@ struct dm_spi_slave_platdata {
  * @cs:			ID of the chip select connected to the slave.
  * @mode:		SPI mode to use for this slave (see SPI mode flags)
  * @wordlen:		Size of SPI word in number of bits
+ * @max_read_size:	If non-zero, the maximum number of bytes which can
+ *			be read at once.
  * @max_write_size:	If non-zero, the maximum number of bytes which can
- *			be written at once, excluding command bytes.
+ *			be written at once.
  * @memory_map:		Address of read-only SPI flash access.
  * @flags:		Indication of SPI flags.
  */
@@ -102,6 +104,7 @@ struct spi_slave {
 #endif
 	uint mode;
 	unsigned int wordlen;
+	unsigned int max_read_size;
 	unsigned int max_write_size;
 	void *memory_map;
 
@@ -314,33 +317,6 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte)
 	return ret < 0 ? ret : din[1];
 }
 
-/**
- * Set up a SPI slave for a particular device tree node
- *
- * This calls spi_setup_slave() with the correct bus number. Call
- * spi_free_slave() to free it later.
- *
- * @param blob:		Device tree blob
- * @param slave_node:	Slave node to use
- * @param spi_node:	SPI peripheral node to use
- * @return pointer to new spi_slave structure
- */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
-				      int spi_node);
-
-/**
- * spi_base_setup_slave_fdt() - helper function to set up a SPI slace
- *
- * This decodes SPI properties from the slave node to determine the
- * chip select and SPI parameters.
- *
- * @blob:	Device tree blob
- * @busnum:	Bus number to use
- * @node:	Device tree node for the SPI bus
- */
-struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
-					   int node);
-
 #ifdef CONFIG_DM_SPI
 
 /**

+ 0 - 12
include/spi_flash.h

@@ -194,18 +194,6 @@ void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 		unsigned int max_hz, unsigned int spi_mode);
 
-/**
- * Set up a new SPI flash from an fdt node
- *
- * @param blob		Device tree blob
- * @param slave_node	Pointer to this SPI slave node in the device tree
- * @param spi_node	Cached pointer to the SPI interface this node belongs
- *			to
- * @return 0 if ok, -1 on error
- */
-struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
-				      int spi_node);
-
 void spi_flash_free(struct spi_flash *flash);
 
 static inline int spi_flash_read(struct spi_flash *flash, u32 offset,

+ 48 - 37
include/wait_bit.h

@@ -16,7 +16,7 @@
 #include <asm/io.h>
 
 /**
- * wait_for_bit()	waits for bit set/cleared in register
+ * wait_for_bit_x()	waits for bit set/cleared in register
  *
  * Function polls register waiting for specific bit(s) change
  * (either 0->1 or 1->0). It can fail under two conditions:
@@ -25,49 +25,60 @@
  * Function succeeds only if all bits of masked register are set/cleared
  * (depending on set option).
  *
- * @param prefix	Prefix added to timeout messagge (message visible only
- *			with debug enabled)
- * @param reg		Register that will be read (using readl())
+ * @param reg		Register that will be read (using read_x())
  * @param mask		Bit(s) of register that must be active
  * @param set		Selects wait condition (bit set or clear)
- * @param timeout_ms	Timeout (in miliseconds)
+ * @param timeout_ms	Timeout (in milliseconds)
  * @param breakable	Enables CTRL-C interruption
  * @return		0 on success, -ETIMEDOUT or -EINTR on failure
  */
-static inline int wait_for_bit(const char *prefix, const u32 *reg,
-			       const u32 mask, const bool set,
-			       const unsigned int timeout_ms,
-			       const bool breakable)
-{
-	u32 val;
-	unsigned long start = get_timer(0);
 
-	while (1) {
-		val = readl(reg);
-
-		if (!set)
-			val = ~val;
-
-		if ((val & mask) == mask)
-			return 0;
-
-		if (get_timer(start) > timeout_ms)
-			break;
-
-		if (breakable && ctrlc()) {
-			puts("Abort\n");
-			return -EINTR;
-		}
-
-		udelay(1);
-		WATCHDOG_RESET();
-	}
-
-	debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", prefix, reg, mask,
-	      set);
-
-	return -ETIMEDOUT;
+#define BUILD_WAIT_FOR_BIT(sfx, type, read)				\
+									\
+static inline int wait_for_bit_##sfx(const void *reg,			\
+				     const type mask,			\
+				     const bool set,			\
+				     const unsigned int timeout_ms,	\
+				     const bool breakable)		\
+{									\
+	type val;							\
+	unsigned long start = get_timer(0);				\
+									\
+	while (1) {							\
+		val = read(reg);					\
+									\
+		if (!set)						\
+			val = ~val;					\
+									\
+		if ((val & mask) == mask)				\
+			return 0;					\
+									\
+		if (get_timer(start) > timeout_ms)			\
+			break;						\
+									\
+		if (breakable && ctrlc()) {				\
+			puts("Abort\n");				\
+			return -EINTR;					\
+		}							\
+									\
+		udelay(1);						\
+		WATCHDOG_RESET();					\
+	}								\
+									\
+	debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__,	\
+	      reg, mask, set);						\
+									\
+	return -ETIMEDOUT;						\
 }
 
+BUILD_WAIT_FOR_BIT(8, u8, readb)
+BUILD_WAIT_FOR_BIT(le16, u16, readw)
+#ifdef readw_be
+BUILD_WAIT_FOR_BIT(be16, u16, readw_be)
+#endif
+BUILD_WAIT_FOR_BIT(le32, u32, readl)
+#ifdef readl_be
+BUILD_WAIT_FOR_BIT(be32, u32, readl_be)
+#endif
 
 #endif

+ 0 - 2
scripts/config_whitelist.txt

@@ -1515,8 +1515,6 @@ CONFIG_NUM_PAMU
 CONFIG_ODROID_REV_AIN
 CONFIG_OFF_PADCONF
 CONFIG_OF_
-CONFIG_OF_SPI
-CONFIG_OF_SPI_FLASH
 CONFIG_OF_STDOUT_PATH
 CONFIG_OMAP_EHCI_PHY1_RESET_GPIO
 CONFIG_OMAP_EHCI_PHY2_RESET_GPIO