From b89c81929e462e66e953dddd91429be49c69e439 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Sun, 17 Jun 2012 16:17:29 +0000
Subject: [PATCH] fix SPI message control handling for BCM6338/6348

BCM6338 and BCM6338 have their MSG_CONTROL register width of 8-bits instead of
16-bits. We were previously using a 16-bits write which corrupted the first
byte of the TX FIFO. Also the message type was always set to Full-duplex even
in the case of half-duplex messages.

SVN-Revision: 32409
---
 .../016-spi-bcm63xx-fix-bcm6348-38.patch      | 128 ++++++++++++++++++
 ...63XX-add-TRNG-peripheral-definitions.patch |   2 +-
 ...3XX-add-MISC-register-set-definition.patch |   2 +-
 ...XX-Add-PCIe-register-set-definitions.patch |   4 +-
 ...9-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch |   2 +-
 5 files changed, 133 insertions(+), 5 deletions(-)
 create mode 100644 target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch

diff --git a/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch b/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch
new file mode 100644
index 0000000000..ce532571d2
--- /dev/null
+++ b/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch
@@ -0,0 +1,128 @@
+--- a/arch/mips/bcm63xx/dev-spi.c
++++ b/arch/mips/bcm63xx/dev-spi.c
+@@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void)
+ 	if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+ 		spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
+ 		spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
++		spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT;
++		spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
+ 	}
+ 
+ 	if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ 		spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
+ 		spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
++		spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
++		spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
+ 	}
+ 
+ 	bcm63xx_spi_regs_init();
+--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
+@@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void);
+ 
+ struct bcm63xx_spi_pdata {
+ 	unsigned int	fifo_size;
++	unsigned int	msg_type_shift;
++	unsigned int	msg_ctl_width;
+ 	int		bus_num;
+ 	int		num_chipselect;
+ 	u32		speed_hz;
+--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+@@ -987,7 +987,8 @@
+ #define SPI_6338_FILL_BYTE		0x07
+ #define SPI_6338_MSG_TAIL		0x09
+ #define SPI_6338_RX_TAIL		0x0b
+-#define SPI_6338_MSG_CTL		0x40
++#define SPI_6338_MSG_CTL		0x40	/* 8-bits register */
++#define SPI_6338_MSG_CTL_WIDTH		8
+ #define SPI_6338_MSG_DATA		0x41
+ #define SPI_6338_MSG_DATA_SIZE		0x3f
+ #define SPI_6338_RX_DATA		0x80
+@@ -1003,7 +1004,8 @@
+ #define SPI_6348_FILL_BYTE		0x07
+ #define SPI_6348_MSG_TAIL		0x09
+ #define SPI_6348_RX_TAIL		0x0b
+-#define SPI_6348_MSG_CTL		0x40
++#define SPI_6348_MSG_CTL		0x40	/* 8-bits register */
++#define SPI_6348_MSG_CTL_WIDTH		8
+ #define SPI_6348_MSG_DATA		0x41
+ #define SPI_6348_MSG_DATA_SIZE		0x3f
+ #define SPI_6348_RX_DATA		0x80
+@@ -1011,6 +1013,7 @@
+ 
+ /* BCM 6358 SPI core */
+ #define SPI_6358_MSG_CTL		0x00	/* 16-bits register */
++#define SPI_6358_MSG_CTL_WIDTH		16
+ #define SPI_6358_MSG_DATA		0x02
+ #define SPI_6358_MSG_DATA_SIZE		0x21e
+ #define SPI_6358_RX_DATA		0x400
+@@ -1027,6 +1030,7 @@
+ 
+ /* BCM 6358 SPI core */
+ #define SPI_6368_MSG_CTL		0x00	/* 16-bits register */
++#define SPI_6368_MSG_CTL_WIDTH		16
+ #define SPI_6368_MSG_DATA		0x02
+ #define SPI_6368_MSG_DATA_SIZE		0x21e
+ #define SPI_6368_RX_DATA		0x400
+@@ -1048,7 +1052,10 @@
+ #define SPI_HD_W			0x01
+ #define SPI_HD_R			0x02
+ #define SPI_BYTE_CNT_SHIFT		0
+-#define SPI_MSG_TYPE_SHIFT		14
++#define SPI_6338_MSG_TYPE_SHIFT		6
++#define SPI_6348_MSG_TYPE_SHIFT		6
++#define SPI_6358_MSG_TYPE_SHIFT		14
++#define SPI_6368_MSG_TYPE_SHIFT		14
+ 
+ /* Command */
+ #define SPI_CMD_NOOP			0x00
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -47,6 +47,8 @@ struct bcm63xx_spi {
+ 	/* Platform data */
+ 	u32			speed_hz;
+ 	unsigned		fifo_size;
++	unsigned int		msg_type_shift;
++	unsigned int		msg_ctl_width;
+ 
+ 	/* Data buffers */
+ 	const unsigned char	*tx_ptr;
+@@ -221,13 +223,24 @@ static unsigned int bcm63xx_txrx_bufs(st
+ 	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
+ 
+ 	if (t->rx_buf && t->tx_buf)
+-		msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
++		msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
+ 	else if (t->rx_buf)
+-		msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT);
++		msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
+ 	else if (t->tx_buf)
+-		msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT);
++		msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
+ 
+-	bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
++	switch (bs->msg_ctl_width) {
++	case 8:
++		bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
++		break;
++	case 16:
++		bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
++		break;
++	default:
++		dev_err(&spi->dev, "unknown MSG_CTL width: %d\n",
++			bs->msg_ctl_width);
++		return 0;
++	}
+ 
+ 	/* Issue the transfer */
+ 	cmd = SPI_CMD_START_IMMEDIATE;
+@@ -406,6 +419,8 @@ static int __devinit bcm63xx_spi_probe(s
+ 	master->transfer_one_message = bcm63xx_spi_transfer_one;
+ 	master->mode_bits = MODEBITS;
+ 	bs->speed_hz = pdata->speed_hz;
++	bs->msg_type_shift = pdata->msg_type_shift;
++	bs->msg_ctl_width = pdata->msg_ctl_width;
+ 	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
+ 	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
+ 
diff --git a/target/linux/brcm63xx/patches-3.3/103-MIPS-BCM63XX-add-TRNG-peripheral-definitions.patch b/target/linux/brcm63xx/patches-3.3/103-MIPS-BCM63XX-add-TRNG-peripheral-definitions.patch
index 5c77585ed7..a656de6c77 100644
--- a/target/linux/brcm63xx/patches-3.3/103-MIPS-BCM63XX-add-TRNG-peripheral-definitions.patch
+++ b/target/linux/brcm63xx/patches-3.3/103-MIPS-BCM63XX-add-TRNG-peripheral-definitions.patch
@@ -85,7 +85,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
  static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
-@@ -1092,4 +1092,18 @@
+@@ -1099,4 +1099,18 @@
  #define SPI_SSOFFTIME_SHIFT		3
  #define SPI_BYTE_SWAP			0x80
  
diff --git a/target/linux/brcm63xx/patches-3.3/311-MIPS-BCM63XX-add-MISC-register-set-definition.patch b/target/linux/brcm63xx/patches-3.3/311-MIPS-BCM63XX-add-MISC-register-set-definition.patch
index 83ccf62b9c..8d2d9b9da1 100644
--- a/target/linux/brcm63xx/patches-3.3/311-MIPS-BCM63XX-add-MISC-register-set-definition.patch
+++ b/target/linux/brcm63xx/patches-3.3/311-MIPS-BCM63XX-add-MISC-register-set-definition.patch
@@ -90,7 +90,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  #endif /* ! BCM63XX_IO_H_ */
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
-@@ -1116,4 +1116,14 @@
+@@ -1123,4 +1123,14 @@
  #define TRNG_THRES			0x0c
  #define TRNG_MASK			0x10
  
diff --git a/target/linux/brcm63xx/patches-3.3/316-MIPS-BCM63XX-Add-PCIe-register-set-definitions.patch b/target/linux/brcm63xx/patches-3.3/316-MIPS-BCM63XX-Add-PCIe-register-set-definitions.patch
index cabb9bd04b..b561bf143f 100644
--- a/target/linux/brcm63xx/patches-3.3/316-MIPS-BCM63XX-Add-PCIe-register-set-definitions.patch
+++ b/target/linux/brcm63xx/patches-3.3/316-MIPS-BCM63XX-Add-PCIe-register-set-definitions.patch
@@ -108,7 +108,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  #define bcm_memc_readl(o)	bcm_rset_readl(RSET_MEMC, (o))
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
-@@ -1163,6 +1163,9 @@
+@@ -1170,6 +1170,9 @@
  /*************************************************************************
   * _REG relative to RSET_MISC
   *************************************************************************/
@@ -118,7 +118,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  
  #define MISC_STRAPBUS_6328_REG		0x240
  #define STRAPBUS_6328_FCVO_SHIFT	7
-@@ -1170,4 +1173,55 @@
+@@ -1177,4 +1180,55 @@
  #define STRAPBUS_6328_BOOT_SEL_SERIAL	(1 << 28)
  #define STRAPBUS_6328_BOOT_SEL_NAND	(0 << 28)
  
diff --git a/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch b/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch
index 94c9eee603..44e6958738 100644
--- a/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch
+++ b/target/linux/brcm63xx/patches-3.3/419-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch
@@ -174,7 +174,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  #endif /* BCM63XX_DEV_HSSPI_H */
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
-@@ -1276,4 +1276,51 @@
+@@ -1283,4 +1283,51 @@
  
  #define PCIE_DEVICE_OFFSET		0x8000
  
-- 
GitLab