All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jagan Teki <jagannadh.teki@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 1/8] spi: add support of SPI flash commands
Date: Wed, 30 Aug 2017 19:20:13 +0530	[thread overview]
Message-ID: <CAD6G_RR9pxbYVF-xzP_diVk=TG_02jBug1qM-y33OUGtZouq4g@mail.gmail.com> (raw)
In-Reply-To: <20170725070102.1344-2-wenyou.yang@microchip.com>

On Tue, Jul 25, 2017 at 12:30 PM, Wenyou Yang <wenyou.yang@microchip.com> wrote:
> From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
>
> This patch introduces 'struct spi_flash_command' and functions
> spi_is_flash_command_supported() / spi_exec_flash_command().
>

Answer for why this shouldn't be part of SPI area.

[snip]

drivers/spi and include/spi.h is Generic SPI area code - this can deal
all connected slave devices like EEPROM, SPI-NOR etc
drivers/mtd/spi and include/spi_flash.h is SPI-Flash or SPI-NOR code -
this can handle only SPI flashes.

>
> +bool dm_spi_is_flash_command_supported(struct udevice *dev,
> +                                      const struct spi_flash_command *cmd)
> +{
> +       struct udevice *bus = dev->parent;
> +       struct dm_spi_ops *ops = spi_get_ops(bus);
> +
> +       if (ops->is_flash_command_supported)
> +               return ops->is_flash_command_supported(dev, cmd);
> +
> +       return false;
> +}
> +
> +int dm_spi_exec_flash_command(struct udevice *dev,
> +                             const struct spi_flash_command *cmd)
> +{
> +       struct udevice *bus = dev->parent;
> +       struct dm_spi_ops *ops = spi_get_ops(bus);
> +
> +       if (ops->exec_flash_command)
> +               return ops->exec_flash_command(dev, cmd);
> +
> +       return -EINVAL;
> +}
> +
>  int spi_claim_bus(struct spi_slave *slave)
>  {
>         return dm_spi_claim_bus(slave->dev);
> @@ -107,6 +131,18 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
>         return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
>  }
>
> +bool spi_is_flash_command_supported(struct spi_slave *slave,
> +                                   const struct spi_flash_command *cmd)
> +{
> +       return dm_spi_is_flash_command_supported(slave->dev, cmd);
> +}
> +
> +int spi_exec_flash_command(struct spi_slave *slave,
> +                          const struct spi_flash_command *cmd)
> +{
> +       return dm_spi_exec_flash_command(slave->dev, cmd);
> +}

Handling spi-flash stuff in spi core is not proper way of dealing, and
I saw these functions are not-at-all needed for generic controller
drivers in drivers/spi except the Atmel QSPI driver (in v3,8/8).

> +
>  #if !CONFIG_IS_ENABLED(OF_PLATDATA)
>  static int spi_child_post_bind(struct udevice *dev)
>  {
> @@ -144,6 +180,10 @@ static int spi_post_probe(struct udevice *bus)
>                 ops->set_mode += gd->reloc_off;
>         if (ops->cs_info)
>                 ops->cs_info += gd->reloc_off;
> +       if (ops->is_flash_command_supported)
> +               ops->is_flash_command_supported += gd->reloc_off;
> +       if (ops->exec_flash_command)
> +               ops->exec_flash_command += gd->reloc_off;
>  #endif
>
>         return 0;
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 7d81fbd7f8..e47acdc9e4 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -5,6 +5,7 @@
>   */
>
>  #include <common.h>
> +#include <errno.h>
>  #include <fdtdec.h>
>  #include <malloc.h>
>  #include <spi.h>
> @@ -58,3 +59,15 @@ struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
>         return spi_setup_slave(busnum, cs, max_hz, mode);
>  }
>  #endif
> +
> +__weak bool spi_is_flash_command_supported(struct spi_slave *slave,
> +                                          const struct spi_flash_command *cmd)
> +{
> +       return false;
> +}
> +
> +__weak int spi_exec_flash_command(struct spi_slave *slave,
> +                                 const struct spi_flash_command *cmd)
> +{
> +       return -EINVAL;
> +}
> diff --git a/include/spi.h b/include/spi.h
> index 8c4b882c54..a090266b52 100644
> --- a/include/spi.h
> +++ b/include/spi.h
> @@ -10,6 +10,8 @@
>  #ifndef _SPI_H_
>  #define _SPI_H_
>
> +#include <linux/string.h> /* memset() */
> +
>  /* SPI mode flags */
>  #define SPI_CPHA       BIT(0)                  /* clock phase */
>  #define SPI_CPOL       BIT(1)                  /* clock polarity */
> @@ -64,6 +66,116 @@ struct dm_spi_slave_platdata {
>  #endif /* CONFIG_DM_SPI */
>
>  /**
> + * enum spi_flash_protocol - SPI flash command protocol
> + */
> +#define SPI_FPROTO_INST_SHIFT  16
> +#define SPI_FPROTO_INST_MASK   GENMASK(23, 16)
> +#define SPI_FPROTO_INST(nbits)                                 \
> +       ((((unsigned long)(nbits)) << SPI_FPROTO_INST_SHIFT) &  \
> +        SPI_FPROTO_INST_MASK)
> +
> +#define SPI_FPROTO_ADDR_SHIFT  8
> +#define SPI_FPROTO_ADDR_MASK   GENMASK(15, 8)
> +#define SPI_FPROTO_ADDR(nbits)                                 \
> +       ((((unsigned long)(nbits)) << SPI_FPROTO_ADDR_SHIFT) &  \
> +        SPI_FPROTO_ADDR_MASK)
> +
> +#define SPI_FPROTO_DATA_SHIFT  0
> +#define SPI_FPROTO_DATA_MASK   GENMASK(7, 0)
> +#define SPI_FPROTO_DATA(nbits)                                 \
> +       ((((unsigned long)(nbits)) << SPI_FPROTO_DATA_SHIFT) &  \
> +        SPI_FPROTO_DATA_MASK)
> +
> +#define SPI_FPROTO(inst_nbits, addr_nbits, data_nbits) \
> +       (SPI_FPROTO_INST(inst_nbits) |                  \
> +        SPI_FPROTO_ADDR(addr_nbits) |                  \
> +        SPI_FPROTO_DATA(data_nbits))
> +
> +enum spi_flash_protocol {
> +       SPI_FPROTO_1_1_1 = SPI_FPROTO(1, 1, 1),
> +       SPI_FPROTO_1_1_2 = SPI_FPROTO(1, 1, 2),
> +       SPI_FPROTO_1_1_4 = SPI_FPROTO(1, 1, 4),
> +       SPI_FPROTO_1_2_2 = SPI_FPROTO(1, 2, 2),
> +       SPI_FPROTO_1_4_4 = SPI_FPROTO(1, 4, 4),
> +       SPI_FPROTO_2_2_2 = SPI_FPROTO(2, 2, 2),
> +       SPI_FPROTO_4_4_4 = SPI_FPROTO(4, 4, 4),
> +};

these protocol also includes IO's like dual and quad and IO's which
are specific for SPI-NOR flash and not Generic SPI protocols.

> +
> +static inline
> +u8 spi_flash_protocol_get_inst_nbits(enum spi_flash_protocol proto)
> +{
> +       return ((unsigned long)(proto & SPI_FPROTO_INST_MASK)) >>
> +               SPI_FPROTO_INST_SHIFT;
> +}
> +
> +static inline
> +u8 spi_flash_protocol_get_addr_nbits(enum spi_flash_protocol proto)
> +{
> +       return ((unsigned long)(proto & SPI_FPROTO_ADDR_MASK)) >>
> +               SPI_FPROTO_ADDR_SHIFT;
> +}
> +
> +static inline
> +u8 spi_flash_protocol_get_data_nbits(enum spi_flash_protocol proto)
> +{
> +       return ((unsigned long)(proto & SPI_FPROTO_DATA_MASK)) >>
> +               SPI_FPROTO_DATA_SHIFT;
> +}
> +
> +/**
> + * struct spi_flash_command - SPI flash command structure
> + *
> + * @instr:             Opcode sent to the SPI slave during instr clock cycles.
> + * @mode:              Value sent to the SPI slave during mode clock cycles.
> + * @num_mode_cycles:   Number of mode clock cycles.
> + * @num_wait_states:   Number of wait-state clock cycles.
> + * @addr_len:          Number of bytes sent during address clock cycles:
> + *                     should be 0, 3, or 4.
> + * @addr:              Value sent to the SPI slave during address clock cycles.
> + * @data_len:          Number of bytes to be sent during data clock cycles.
> + * @tx_data:           Data sent to the SPI slave during data clock cycles.
> + * @rx_data:           Data read from the SPI slave during data clock cycles.
> + */
> +struct spi_flash_command {
> +       enum spi_flash_protocol proto;
> +       u8 flags;
> +#define SPI_FCMD_TYPE          GENMASK(2, 0)
> +#define SPI_FCMD_READ          (0x0U << 0)
> +#define SPI_FCMD_WRITE         (0x1U << 0)
> +#define SPI_FCMD_ERASE         (0x2U << 0)
> +#define SPI_FCMD_READ_REG      (0x3U << 0)
> +#define SPI_FCMD_WRITE_REG     (0x4U << 0)
> +
> +       u8 inst;
> +       u8 mode;
> +       u8 num_mode_cycles;
> +       u8 num_wait_states;
> +       u8 addr_len;
> +       u32 addr;
> +       size_t data_len;
> +       const void *tx_data;
> +       void *rx_data;
> +};

I saw from the other patches, this structure is initializing for each
I/O interface between SPI to driver/mtd like spi_transfer, if so it
shouldn't have flash attributes. Better to move flash contents to
spi_flash structure and do the respective operations.

thanks!
-- 
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.

  reply	other threads:[~2017-08-30 13:50 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-25  7:00 [U-Boot] [PATCH v3 0/8] sf: improve support of (Q)SPI flash memories Wenyou Yang
2017-07-25  7:00 ` [U-Boot] [PATCH v3 1/8] spi: add support of SPI flash commands Wenyou Yang
2017-08-30 13:50   ` Jagan Teki [this message]
2017-09-01  0:10     ` Wenyou.Yang at microchip.com
2017-07-25  7:00 ` [U-Boot] [PATCH v3 2/8] sf: describe all SPI flash commands with 'struct spi_flash_command' Wenyou Yang
2017-08-30 14:03   ` Jagan Teki
2017-07-25  7:00 ` [U-Boot] [PATCH v3 3/8] sf: select the relevant SPI flash protocol for read and write commands Wenyou Yang
2017-07-25  7:00 ` [U-Boot] [PATCH v3 4/8] sf: differentiate Page Program 1-1-4 and 1-4-4 Wenyou Yang
2017-07-25  7:00 ` [U-Boot] [PATCH v3 5/8] sf: add 'addr_len' member to 'struct spi_flash' Wenyou Yang
2017-07-25  7:01 ` [U-Boot] [PATCH v3 6/8] sf: add new option to support SPI flash above 16MiB Wenyou Yang
2017-07-25  7:01 ` [U-Boot] [PATCH v3 7/8] sf: add support to Microchip SST26 QSPI memories Wenyou Yang
2017-07-25  7:01 ` [U-Boot] [PATCH v3 8/8] sf: add driver for Atmel QSPI controller Wenyou Yang
2017-08-30 13:58   ` Jagan Teki
2017-07-31  7:29 ` [U-Boot] [PATCH v3 0/8] sf: improve support of (Q)SPI flash memories Yang, Wenyou
2017-08-11  1:02 ` Yang, Wenyou
2017-08-11  5:14   ` Jagan Teki
2017-08-25  1:17 ` Yang, Wenyou
2017-08-25 16:07   ` Jagan Teki
2017-08-25 16:13     ` Marek Vasut
2017-08-25 16:28       ` Jagan Teki
2017-08-25 16:45         ` Marek Vasut
2017-08-25 23:05           ` Bin Meng
2017-08-26  6:14             ` Jagan Teki
2017-08-26  8:36               ` Marek Vasut
2017-08-26 19:12                 ` Tom Rini
2017-08-26  6:34 ` Jagan Teki
2017-08-30  1:58   ` Yang, Wenyou
2017-08-30  6:33     ` Jagan Teki
2017-08-30  3:25   ` Yang, Wenyou
2017-08-30  3:43     ` Bin Meng
2017-08-30  5:27       ` Yang, Wenyou
2017-08-30  5:41         ` Bin Meng
2017-08-30  5:51           ` Yang, Wenyou
2017-08-30  6:30           ` Jagan Teki
2017-08-30  7:47             ` Bin Meng
2017-08-30 13:25               ` Jagan Teki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAD6G_RR9pxbYVF-xzP_diVk=TG_02jBug1qM-y33OUGtZouq4g@mail.gmail.com' \
    --to=jagannadh.teki@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.