Re: [U-Boot] [PATCH v6] dm: at91: Add driver model support for the spi driver

2016-07-28 Thread Wenyou.Yang
Hi Jagan,

> -Original Message-
> From: Jagan Teki [mailto:jagannadh.t...@gmail.com]
> Sent: 2016年7月26日 14:21
> To: Wenyou Yang <wenyou.y...@atmel.com>
> Cc: U-Boot Mailing List <u-boot@lists.denx.de>
> Subject: Re: [U-Boot] [PATCH v6] dm: at91: Add driver model support for the 
> spi
> driver
> 
> On 25 July 2016 at 15:27, Wenyou Yang <wenyou.y...@atmel.com> wrote:
> > Add driver model support while retaining the existing legacy code.
> > This allows the driver to support boards that have converted to driver
> > model as well as those that have not.
> >
> > Signed-off-by: Wenyou Yang <wenyou.y...@atmel.com>
> > Reviewed-by: Simon Glass <s...@chromium.org>
> > ---
> >
> > Changes in v6:
> >  - Remove the two flash related options.
> >
> > Changes in v5:
> >  - Change clk_client.h -> clk.h to adapt to clk API conversion.
> >
> > Changes in v4:
> >  - Collect Reviewed-by tag.
> >  - Update the clk API based on [PATCH] clk: convert API to match
> >reset/mailbox fstyle (http://patchwork.ozlabs.org/patch/625342/).
> >  - Remove check on dev_get_parent() return.
> >  - Fixed the return value, -ENODEV->-EINVAL.
> >  - Retain #include  line.
> >
> > Changes in v3:
> >  - Remove redundant log print.
> >
> > Changes in v2:
> >  - Add clock support.
> >
> >  drivers/spi/Kconfig |   7 ++
> >  drivers/spi/atmel_spi.c | 303
> > 
> >  2 files changed, 310 insertions(+)
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > aca385d..16ed231 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -32,6 +32,13 @@ config ATH79_SPI
> >   uses driver model and requires a device tree binding to operate.
> >   please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
> >
> > +config ATMEL_SPI
> > +   bool "Atmel SPI driver"
> > +   depends on ARCH_AT91
> > +   help
> > + Enable the Atmel SPI driver. This driver can be used to access
> > + the SPI Flash, such as AT25DF321.
> > +
> >  config CADENCE_QSPI
> > bool "Cadence QSPI driver"
> > help
> > diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index
> > ed6278b..98bee35 100644
> > --- a/drivers/spi/atmel_spi.c
> > +++ b/drivers/spi/atmel_spi.c
> > @@ -4,6 +4,9 @@
> >   * SPDX-License-Identifier:GPL-2.0+
> >   */
> >  #include 
> > +#include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -11,9 +14,15 @@
> >
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >
> >  #include "atmel_spi.h"
> >
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +#ifndef CONFIG_DM_SPI
> > +
> >  static int spi_has_wdrbt(struct atmel_spi_slave *slave)  {
> > unsigned int ver;
> > @@ -209,3 +218,297 @@ out:
> >
> > return 0;
> >  }
> > +
> > +#else
> > +
> > +#define MAX_CS_COUNT   4
> > +
> > +struct atmel_spi_platdata {
> > +   struct at91_spi *regs;
> > +};
> > +
> > +struct atmel_spi_priv {
> > +   unsigned int freq;  /* Default frequency */
> > +   unsigned int mode;
> > +   ulong bus_clk_rate;
> > +   struct gpio_desc cs_gpios[MAX_CS_COUNT]; };
> > +
> > +static int atmel_spi_claim_bus(struct udevice *dev) {
> > +   struct udevice *bus = dev_get_parent(dev);
> > +   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
> > +   struct atmel_spi_priv *priv = dev_get_priv(bus);
> > +   struct dm_spi_slave_platdata *slave_plat = 
> > dev_get_parent_platdata(dev);
> > +   struct at91_spi *reg_base = bus_plat->regs;
> > +   u32 cs = slave_plat->cs;
> > +   u32 freq = priv->freq;
> > +   u32 scbr, csrx, mode;
> > +
> > +   scbr = (priv->bus_clk_rate + freq - 1) / freq;
> > +   if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
> > +   return -EINVAL;
> > +
> > +   if (scbr < 1)
> > +   scbr = 1;
> > +
> > +   csrx = ATMEL_SPI_CSRx_SCBR(scbr);
> > +   csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
> > +
> > +   if (!(priv->mode & SPI_CPHA))
> > +   csrx |= ATMEL_SPI_CSRx_NCPHA;
> > +   if (priv->mode & SPI_CPOL

Re: [U-Boot] [PATCH v6] dm: at91: Add driver model support for the spi driver

2016-07-26 Thread Jagan Teki
On 25 July 2016 at 15:27, Wenyou Yang  wrote:
> Add driver model support while retaining the existing legacy code.
> This allows the driver to support boards that have converted to
> driver model as well as those that have not.
>
> Signed-off-by: Wenyou Yang 
> Reviewed-by: Simon Glass 
> ---
>
> Changes in v6:
>  - Remove the two flash related options.
>
> Changes in v5:
>  - Change clk_client.h -> clk.h to adapt to clk API conversion.
>
> Changes in v4:
>  - Collect Reviewed-by tag.
>  - Update the clk API based on [PATCH] clk: convert API to match
>reset/mailbox fstyle (http://patchwork.ozlabs.org/patch/625342/).
>  - Remove check on dev_get_parent() return.
>  - Fixed the return value, -ENODEV->-EINVAL.
>  - Retain #include  line.
>
> Changes in v3:
>  - Remove redundant log print.
>
> Changes in v2:
>  - Add clock support.
>
>  drivers/spi/Kconfig |   7 ++
>  drivers/spi/atmel_spi.c | 303 
> 
>  2 files changed, 310 insertions(+)
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index aca385d..16ed231 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -32,6 +32,13 @@ config ATH79_SPI
>   uses driver model and requires a device tree binding to operate.
>   please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
>
> +config ATMEL_SPI
> +   bool "Atmel SPI driver"
> +   depends on ARCH_AT91
> +   help
> + Enable the Atmel SPI driver. This driver can be used to access
> + the SPI Flash, such as AT25DF321.
> +
>  config CADENCE_QSPI
> bool "Cadence QSPI driver"
> help
> diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
> index ed6278b..98bee35 100644
> --- a/drivers/spi/atmel_spi.c
> +++ b/drivers/spi/atmel_spi.c
> @@ -4,6 +4,9 @@
>   * SPDX-License-Identifier:GPL-2.0+
>   */
>  #include 
> +#include 
> +#include 
> +#include 
>  #include 
>  #include 
>
> @@ -11,9 +14,15 @@
>
>  #include 
>  #include 
> +#include 
> +#include 
>
>  #include "atmel_spi.h"
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#ifndef CONFIG_DM_SPI
> +
>  static int spi_has_wdrbt(struct atmel_spi_slave *slave)
>  {
> unsigned int ver;
> @@ -209,3 +218,297 @@ out:
>
> return 0;
>  }
> +
> +#else
> +
> +#define MAX_CS_COUNT   4
> +
> +struct atmel_spi_platdata {
> +   struct at91_spi *regs;
> +};
> +
> +struct atmel_spi_priv {
> +   unsigned int freq;  /* Default frequency */
> +   unsigned int mode;
> +   ulong bus_clk_rate;
> +   struct gpio_desc cs_gpios[MAX_CS_COUNT];
> +};
> +
> +static int atmel_spi_claim_bus(struct udevice *dev)
> +{
> +   struct udevice *bus = dev_get_parent(dev);
> +   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
> +   struct atmel_spi_priv *priv = dev_get_priv(bus);
> +   struct dm_spi_slave_platdata *slave_plat = 
> dev_get_parent_platdata(dev);
> +   struct at91_spi *reg_base = bus_plat->regs;
> +   u32 cs = slave_plat->cs;
> +   u32 freq = priv->freq;
> +   u32 scbr, csrx, mode;
> +
> +   scbr = (priv->bus_clk_rate + freq - 1) / freq;
> +   if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
> +   return -EINVAL;
> +
> +   if (scbr < 1)
> +   scbr = 1;
> +
> +   csrx = ATMEL_SPI_CSRx_SCBR(scbr);
> +   csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
> +
> +   if (!(priv->mode & SPI_CPHA))
> +   csrx |= ATMEL_SPI_CSRx_NCPHA;
> +   if (priv->mode & SPI_CPOL)
> +   csrx |= ATMEL_SPI_CSRx_CPOL;
> +
> +   writel(csrx, _base->csr[cs]);
> +
> +   mode = ATMEL_SPI_MR_MSTR |
> +  ATMEL_SPI_MR_MODFDIS |
> +  ATMEL_SPI_MR_WDRBT |
> +  ATMEL_SPI_MR_PCS(~(1 << cs));
> +
> +   writel(mode, _base->mr);
> +
> +   writel(ATMEL_SPI_CR_SPIEN, _base->cr);
> +
> +   return 0;
> +}
> +
> +static int atmel_spi_release_bus(struct udevice *dev)
> +{
> +   struct udevice *bus = dev_get_parent(dev);
> +   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
> +
> +   writel(ATMEL_SPI_CR_SPIDIS, _plat->regs->cr);
> +
> +   return 0;
> +}
> +
> +static void atmel_spi_cs_activate(struct udevice *dev)
> +{
> +   struct udevice *bus = dev_get_parent(dev);
> +   struct atmel_spi_priv *priv = dev_get_priv(bus);
> +   struct dm_spi_slave_platdata *slave_plat = 
> dev_get_parent_platdata(dev);
> +   u32 cs = slave_plat->cs;
> +
> +   dm_gpio_set_value(>cs_gpios[cs], 0);
> +}
> +
> +static void atmel_spi_cs_deactivate(struct udevice *dev)
> +{
> +   struct udevice *bus = dev_get_parent(dev);
> +   struct atmel_spi_priv *priv = dev_get_priv(bus);
> +   struct dm_spi_slave_platdata *slave_plat = 
> dev_get_parent_platdata(dev);
> +   u32 cs = slave_plat->cs;
> +
> +   dm_gpio_set_value(>cs_gpios[cs], 1);
> +}
> +
> +static int atmel_spi_xfer(struct udevice 

[U-Boot] [PATCH v6] dm: at91: Add driver model support for the spi driver

2016-07-25 Thread Wenyou Yang
Add driver model support while retaining the existing legacy code.
This allows the driver to support boards that have converted to
driver model as well as those that have not.

Signed-off-by: Wenyou Yang 
Reviewed-by: Simon Glass 
---

Changes in v6:
 - Remove the two flash related options.

Changes in v5:
 - Change clk_client.h -> clk.h to adapt to clk API conversion.

Changes in v4:
 - Collect Reviewed-by tag.
 - Update the clk API based on [PATCH] clk: convert API to match
   reset/mailbox fstyle (http://patchwork.ozlabs.org/patch/625342/).
 - Remove check on dev_get_parent() return.
 - Fixed the return value, -ENODEV->-EINVAL.
 - Retain #include  line.

Changes in v3:
 - Remove redundant log print.

Changes in v2:
 - Add clock support.

 drivers/spi/Kconfig |   7 ++
 drivers/spi/atmel_spi.c | 303 
 2 files changed, 310 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index aca385d..16ed231 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -32,6 +32,13 @@ config ATH79_SPI
  uses driver model and requires a device tree binding to operate.
  please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
 
+config ATMEL_SPI
+   bool "Atmel SPI driver"
+   depends on ARCH_AT91
+   help
+ Enable the Atmel SPI driver. This driver can be used to access
+ the SPI Flash, such as AT25DF321.
+
 config CADENCE_QSPI
bool "Cadence QSPI driver"
help
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index ed6278b..98bee35 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -4,6 +4,9 @@
  * SPDX-License-Identifier:GPL-2.0+
  */
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 
@@ -11,9 +14,15 @@
 
 #include 
 #include 
+#include 
+#include 
 
 #include "atmel_spi.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_DM_SPI
+
 static int spi_has_wdrbt(struct atmel_spi_slave *slave)
 {
unsigned int ver;
@@ -209,3 +218,297 @@ out:
 
return 0;
 }
+
+#else
+
+#define MAX_CS_COUNT   4
+
+struct atmel_spi_platdata {
+   struct at91_spi *regs;
+};
+
+struct atmel_spi_priv {
+   unsigned int freq;  /* Default frequency */
+   unsigned int mode;
+   ulong bus_clk_rate;
+   struct gpio_desc cs_gpios[MAX_CS_COUNT];
+};
+
+static int atmel_spi_claim_bus(struct udevice *dev)
+{
+   struct udevice *bus = dev_get_parent(dev);
+   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
+   struct atmel_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+   struct at91_spi *reg_base = bus_plat->regs;
+   u32 cs = slave_plat->cs;
+   u32 freq = priv->freq;
+   u32 scbr, csrx, mode;
+
+   scbr = (priv->bus_clk_rate + freq - 1) / freq;
+   if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
+   return -EINVAL;
+
+   if (scbr < 1)
+   scbr = 1;
+
+   csrx = ATMEL_SPI_CSRx_SCBR(scbr);
+   csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
+
+   if (!(priv->mode & SPI_CPHA))
+   csrx |= ATMEL_SPI_CSRx_NCPHA;
+   if (priv->mode & SPI_CPOL)
+   csrx |= ATMEL_SPI_CSRx_CPOL;
+
+   writel(csrx, _base->csr[cs]);
+
+   mode = ATMEL_SPI_MR_MSTR |
+  ATMEL_SPI_MR_MODFDIS |
+  ATMEL_SPI_MR_WDRBT |
+  ATMEL_SPI_MR_PCS(~(1 << cs));
+
+   writel(mode, _base->mr);
+
+   writel(ATMEL_SPI_CR_SPIEN, _base->cr);
+
+   return 0;
+}
+
+static int atmel_spi_release_bus(struct udevice *dev)
+{
+   struct udevice *bus = dev_get_parent(dev);
+   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
+
+   writel(ATMEL_SPI_CR_SPIDIS, _plat->regs->cr);
+
+   return 0;
+}
+
+static void atmel_spi_cs_activate(struct udevice *dev)
+{
+   struct udevice *bus = dev_get_parent(dev);
+   struct atmel_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+   u32 cs = slave_plat->cs;
+
+   dm_gpio_set_value(>cs_gpios[cs], 0);
+}
+
+static void atmel_spi_cs_deactivate(struct udevice *dev)
+{
+   struct udevice *bus = dev_get_parent(dev);
+   struct atmel_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+   u32 cs = slave_plat->cs;
+
+   dm_gpio_set_value(>cs_gpios[cs], 1);
+}
+
+static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+   struct udevice *bus = dev_get_parent(dev);
+   struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
+   struct at91_spi *reg_base = bus_plat->regs;
+
+   u32 len_tx, len_rx, len;
+   u32 status;
+   const u8 *txp = dout;
+   u8 *rxp = din;
+   u8 value;