Commit 155fa9af authored by Nikita Kiryanov's avatar Nikita Kiryanov Committed by Jagannadha Sutradharudu Teki

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: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarNikita Kiryanov <nikita@compulab.co.il>
Reviewed-by: default avatarJagannadha Sutradharudu Teki <jaganna@xilinx.com>
parent 01d2aaf6
......@@ -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),
......
......@@ -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));
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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));
......
......@@ -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
......
......@@ -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;
......
......@@ -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[] = {
......
......@@ -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);
......
......@@ -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
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment