[U-Boot] [PATCH V4 03/19] spi: mxc: fix sf probe when using mxc_spi
Jagan Teki
jagannadh.teki at gmail.com
Sat Aug 23 09:24:56 CEST 2014
On Wed, Aug 20, 2014 at 5:38 PM, Nikita Kiryanov <nikita at compulab.co.il> wrote:
> 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: Jagannadha Sutradharudu Teki <jagannadh.teki at gmail.com>
> Cc: Eric Nelson <eric.nelson at boundarydevices.com>
> Cc: Eric Benard <eric at eukrea.com>
> Cc: Fabio Estevam <fabio.estevam at freescale.com>
> Cc: Tim Harvey <tharvey at gateworks.com>
> Cc: Stefano Babic <sbabic at denx.de>
> Cc: Tom Rini <trini at ti.com>
> Cc: Marek Vasut <marex at denx.de>
> Reviewed-by: Marek Vasut <marex at denx.de>
> Signed-off-by: Nikita Kiryanov <nikita at compulab.co.il>
> ---
> Changes in V4:
> - No changes.
>
> Changes in V3:
> - No changes.
>
> Changes in V2:
> - Rewrote commit message, renaming the patch in the process (originally
> "sf: fix sf probe").
>
> board/boundary/nitrogen6x/nitrogen6x.c | 5 +++
> board/embest/mx6boards/mx6boards.c | 5 +++
> board/freescale/mx6qsabreauto/mx6qsabreauto.c | 7 ++++
> board/freescale/mx6sabresd/mx6sabresd.c | 7 ++++
> board/freescale/mx6slevk/mx6slevk.c | 5 +++
> board/gateworks/gw_ventana/gw_ventana.c | 7 +++-
> board/genesi/mx51_efikamx/efikamx.c | 5 +++
> board/ttcontrol/vision2/vision2.c | 5 +++
> drivers/spi/mxc_spi.c | 48 ++++++++++++++-------------
> include/configs/embestmx6boards.h | 2 +-
> include/configs/gw_ventana.h | 2 +-
> include/configs/mx51_efikamx.h | 4 +--
> include/configs/mx6sabre_common.h | 2 +-
> include/configs/mx6slevk.h | 2 +-
> include/configs/nitrogen6x.h | 2 +-
> include/configs/vision2.h | 4 +--
> 16 files changed, 79 insertions(+), 33 deletions(-)
>
> diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c
> index 84294db..aadddb9 100644
> --- a/board/boundary/nitrogen6x/nitrogen6x.c
> +++ b/board/boundary/nitrogen6x/nitrogen6x.c
> @@ -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),
> diff --git a/board/embest/mx6boards/mx6boards.c b/board/embest/mx6boards/mx6boards.c
> index d06b57d..e8a11c2 100644
> --- a/board/embest/mx6boards/mx6boards.c
> +++ b/board/embest/mx6boards/mx6boards.c
> @@ -284,6 +284,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));
> diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
> index 928dadf..836d722 100644
> --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
> +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
> @@ -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 */
> diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
> index d7c4b4f..c5f10f7 100644
> --- a/board/freescale/mx6sabresd/mx6sabresd.c
> +++ b/board/freescale/mx6sabresd/mx6sabresd.c
> @@ -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 */
> diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
> index d2b64cc..ec63d9e 100644
> --- a/board/freescale/mx6slevk/mx6slevk.c
> +++ b/board/freescale/mx6slevk/mx6slevk.c
> @@ -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));
> diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
> index 9d2651f..054f904 100644
> --- a/board/gateworks/gw_ventana/gw_ventana.c
> +++ b/board/gateworks/gw_ventana/gw_ventana.c
> @@ -353,9 +353,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
> diff --git a/board/genesi/mx51_efikamx/efikamx.c b/board/genesi/mx51_efikamx/efikamx.c
> index 16769e5..137e4ed 100644
> --- a/board/genesi/mx51_efikamx/efikamx.c
> +++ b/board/genesi/mx51_efikamx/efikamx.c
> @@ -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;
> diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c
> index b4d3994..b5249e7 100644
> --- a/board/ttcontrol/vision2/vision2.c
> +++ b/board/ttcontrol/vision2/vision2.c
> @@ -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[] = {
> diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
> index 2d5f385..026f680 100644
> --- a/drivers/spi/mxc_spi.c
> +++ b/drivers/spi/mxc_spi.c
> @@ -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);
> diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
> index f1000f3..bcd5ea4 100644
> --- a/include/configs/embestmx6boards.h
> +++ b/include/configs/embestmx6boards.h
> @@ -100,7 +100,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
> diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
> index 8197a72..97398a8 100644
> --- a/include/configs/gw_ventana.h
> +++ b/include/configs/gw_ventana.h
> @@ -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)
> diff --git a/include/configs/mx51_efikamx.h b/include/configs/mx51_efikamx.h
> index 0f2a4ef..fce7ead 100644
> --- a/include/configs/mx51_efikamx.h
> +++ b/include/configs/mx51_efikamx.h
> @@ -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)
> diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h
> index e59a3b4..2d93d6c 100644
> --- a/include/configs/mx6sabre_common.h
> +++ b/include/configs/mx6sabre_common.h
> @@ -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
> diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
> index 3d05a64..5b8309b 100644
> --- a/include/configs/mx6slevk.h
> +++ b/include/configs/mx6slevk.h
> @@ -203,7 +203,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
> diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
> index b2b17ce..d266f7d 100644
> --- a/include/configs/nitrogen6x.h
> +++ b/include/configs/nitrogen6x.h
> @@ -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
> diff --git a/include/configs/vision2.h b/include/configs/vision2.h
> index 6891bf8..3f35076 100644
> --- a/include/configs/vision2.h
> +++ b/include/configs/vision2.h
> @@ -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
> --
> 1.9.1
>
Applied to u-boot-spi/master
thanks!
--
Jagan.
More information about the U-Boot
mailing list