[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