spi: mxc: fix sf probe when using mxc_spi

MXC SPI driver has a feature whereas a GPIO line can be used to force CS high
across multiple transactions. This is set up by embedding the GPIO information
in the CS value:

cs = (cs | gpio << 8)

This merge of cs and gpio data into one value breaks the sf probe command:
if the use of gpio is required, invoking "sf probe <cs>" will not work, because
the CS argument doesn't have the GPIO information in it. Instead, the user must
use "sf probe <cs | gpio << 8>". For example, if bank 2 gpio 30 is used to force
cs high on cs 0, bus 0, then instead of typing "sf probe 0" the user now must
type "sf probe 15872".

This is inconsistent with the description of the sf probe command, and forces
the user to be aware of implementaiton details.

Fix this by introducing a new board function: board_spi_cs_gpio(), which will
accept a naked CS value, and provide the driver with the relevant GPIO, if one
is necessary.

Cc: Eric Nelson <eric.nelson@boundarydevices.com>
Cc: Eric Benard <eric@eukrea.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Tim Harvey <tharvey@gateworks.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Tom Rini <trini@ti.com>
Cc: Marek Vasut <marex@denx.de>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
This commit is contained in:
Nikita Kiryanov 2014-08-20 15:08:50 +03:00 committed by Jagannadha Sutradharudu Teki
parent 01d2aaf61b
commit 155fa9af95
16 changed files with 79 additions and 33 deletions

View file

@ -328,6 +328,11 @@ int board_mmc_init(bd_t *bis)
#endif
#ifdef CONFIG_MXC_SPI
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
}
iomux_v3_cfg_t const ecspi1_pads[] = {
/* SS1 */
MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),

View file

@ -285,6 +285,11 @@ iomux_v3_cfg_t const ecspi1_pads[] = {
MX6_PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(2, 30)) : -1;
}
static void setup_spi(void)
{
imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));

View file

@ -259,6 +259,13 @@ int board_init(void)
return 0;
}
#ifdef CONFIG_MXC_SPI
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
}
#endif
#ifdef CONFIG_CMD_BMODE
static const struct boot_mode board_boot_modes[] = {
/* 4 bit bus width */

View file

@ -513,6 +513,13 @@ static int pfuze_init(void)
return 0;
}
#ifdef CONFIG_MXC_SPI
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
}
#endif
#ifdef CONFIG_CMD_BMODE
static const struct boot_mode board_boot_modes[] = {
/* 4 bit bus width */

View file

@ -82,6 +82,11 @@ static iomux_v3_cfg_t ecspi1_pads[] = {
MX6_PAD_ECSPI1_SS0__GPIO4_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 11)) : -1;
}
static void setup_spi(void)
{
imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));

View file

@ -356,9 +356,14 @@ iomux_v3_cfg_t const ecspi1_pads[] = {
IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
};
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
}
static void setup_spi(void)
{
gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
gpio_direction_output(IMX_GPIO_NR(3, 19), 1);
SETUP_IOMUX_PADS(ecspi1_pads);
}
#endif

View file

@ -152,6 +152,11 @@ static iomux_v3_cfg_t const efikamx_spi_pads[] = {
* PMIC configuration
*/
#ifdef CONFIG_MXC_SPI
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 1) ? 121 : -1;
}
static void power_init(void)
{
unsigned int val;

View file

@ -144,6 +144,11 @@ static void setup_uart(void)
}
#ifdef CONFIG_MXC_SPI
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 1) ? 121 : -1;
}
void spi_io_init(void)
{
static const iomux_v3_cfg_t spi_pads[] = {

View file

@ -25,6 +25,11 @@ static unsigned long spi_bases[] = {
MXC_SPI_BASE_ADDRESSES
};
__weak int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return -1;
}
#define OUT MXC_GPIO_DIRECTION_OUT
#define reg_read readl
@ -371,31 +376,30 @@ void spi_init(void)
{
}
static int decode_cs(struct mxc_spi_slave *mxcs, unsigned int cs)
/*
* Some SPI devices require active chip-select over multiple
* transactions, we achieve this using a GPIO. Still, the SPI
* controller has to be configured to use one of its own chipselects.
* To use this feature you have to implement board_spi_cs_gpio() to assign
* a gpio value for each cs (-1 if cs doesn't need to use gpio).
* You must use some unused on this SPI controller cs between 0 and 3.
*/
static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
unsigned int bus, unsigned int cs)
{
int ret;
/*
* Some SPI devices require active chip-select over multiple
* transactions, we achieve this using a GPIO. Still, the SPI
* controller has to be configured to use one of its own chipselects.
* To use this feature you have to call spi_setup_slave() with
* cs = internal_cs | (gpio << 8), and you have to use some unused
* on this SPI controller cs between 0 and 3.
*/
if (cs > 3) {
mxcs->gpio = cs >> 8;
cs &= 3;
ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
if (ret) {
printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
return -EINVAL;
}
} else {
mxcs->gpio = -1;
mxcs->gpio = board_spi_cs_gpio(bus, cs);
if (mxcs->gpio == -1)
return 0;
ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
if (ret) {
printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
return -EINVAL;
}
return cs;
return 0;
}
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
@ -415,14 +419,12 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
ret = decode_cs(mxcs, cs);
ret = setup_cs_gpio(mxcs, bus, cs);
if (ret < 0) {
free(mxcs);
return NULL;
}
cs = ret;
mxcs->base = spi_bases[bus];
ret = spi_cfg_mxc(mxcs, cs, max_hz, mode);

View file

@ -102,7 +102,7 @@
#define CONFIG_SPI_FLASH_SST
#define CONFIG_MXC_SPI
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0 | (IMX_GPIO_NR(2, 30) << 8))
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_SPEED 20000000
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#endif

View file

@ -61,7 +61,7 @@
#define CONFIG_SPI_FLASH_BAR
#define CONFIG_SPI_FLASH_WINBOND
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0|(IMX_GPIO_NR(3, 19)<<8))
#define CONFIG_SF_DEFAULT_CS 0
/* GPIO 3-19 (21248) */
#define CONFIG_SF_DEFAULT_SPEED 30000000
#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)

View file

@ -96,11 +96,11 @@
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_SST
#define CONFIG_SF_DEFAULT_CS (1 | 121 << 8)
#define CONFIG_SF_DEFAULT_CS 1
#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_ENV_SPI_CS (1 | 121 << 8)
#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
#define CONFIG_ENV_SPI_BUS 0
#define CONFIG_ENV_SPI_MAX_HZ 25000000
#define CONFIG_ENV_SPI_MODE (SPI_MODE_0)

View file

@ -74,7 +74,7 @@
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_MXC_SPI
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0 | (IMX_GPIO_NR(4, 9) << 8))
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_SPEED 20000000
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#endif

View file

@ -205,7 +205,7 @@
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_MXC_SPI
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0 | (IMX_GPIO_NR(4, 11) << 8))
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_SPEED 20000000
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#endif

View file

@ -53,7 +53,7 @@
#define CONFIG_SPI_FLASH_SST
#define CONFIG_MXC_SPI
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0|(IMX_GPIO_NR(3, 19)<<8))
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
#endif

View file

@ -57,11 +57,11 @@
* Use gpio 4 pin 25 as chip select for SPI flash
* This corresponds to gpio 121
*/
#define CONFIG_SF_DEFAULT_CS (1 | (121 << 8))
#define CONFIG_SF_DEFAULT_CS 1
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_ENV_SPI_CS (1 | (121 << 8))
#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
#define CONFIG_ENV_SPI_BUS 0
#define CONFIG_ENV_SPI_MAX_HZ 25000000
#define CONFIG_ENV_SPI_MODE SPI_MODE_0