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) |  static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | ||||||
| --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | ||||||
| +++ b/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_SSOFFTIME_SHIFT		3 | ||||||
|  #define SPI_BYTE_SWAP			0x80 |  #define SPI_BYTE_SWAP			0x80 | ||||||
|   |   | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | |||||||
|  #endif /* ! BCM63XX_IO_H_ */ |  #endif /* ! BCM63XX_IO_H_ */ | ||||||
| --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | ||||||
| +++ b/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_THRES			0x0c | ||||||
|  #define TRNG_MASK			0x10 |  #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)) |  #define bcm_memc_readl(o)	bcm_rset_readl(RSET_MEMC, (o)) | ||||||
| --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | ||||||
| +++ b/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 |   * _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 MISC_STRAPBUS_6328_REG		0x240 | ||||||
|  #define STRAPBUS_6328_FCVO_SHIFT	7 |  #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_SERIAL	(1 << 28) | ||||||
|  #define STRAPBUS_6328_BOOT_SEL_NAND	(0 << 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 */ |  #endif /* BCM63XX_DEV_HSSPI_H */ | ||||||
| --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | ||||||
| +++ b/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 |  #define PCIE_DEVICE_OFFSET		0x8000 | ||||||
|   |   | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Florian Fainelli
					Florian Fainelli