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
This commit is contained in:
		| @@ -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)); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Florian Fainelli
					Florian Fainelli