* [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver
@ 2016-04-25 3:48 Wenyou Yang
2016-05-01 18:56 ` Simon Glass
0 siblings, 1 reply; 4+ messages in thread
From: Wenyou Yang @ 2016-04-25 3:48 UTC (permalink / raw)
To: u-boot
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.yang@atmel.com>
---
drivers/spi/Kconfig | 9 ++
drivers/spi/atmel_spi.c | 254 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 263 insertions(+)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f0258f8..e6b53ce 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -23,6 +23,15 @@ config ALTERA_SPI
IP core. Please find details on the "Embedded Peripherals IP
User Guide" of Altera.
+config ATMEL_SPI
+ bool "Atmel SPI driver"
+ depends on ARCH_AT91
+ select SPI_FLASH
+ select SPI_FLASH_ATMEL
+ 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..24d4a52 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
#include <spi.h>
#include <malloc.h>
@@ -11,9 +13,15 @@
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
+#include <asm/arch/at91_spi.h>
+#include <asm/gpio.h>
#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 +217,249 @@ 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;
+ 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 = (get_spi_clk_rate(0) + 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, &bus_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(&priv->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(&priv->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;
+
+ if (bitlen == 0)
+ goto out;
+
+ /*
+ * The controller can do non-multiple-of-8 bit
+ * transfers, but this driver currently doesn't support it.
+ *
+ * It's also not clear how such transfers are supposed to be
+ * represented as a stream of bytes...this is a limitation of
+ * the current SPI interface.
+ */
+ if (bitlen % 8) {
+ /* Errors always terminate an ongoing transfer */
+ flags |= SPI_XFER_END;
+ goto out;
+ }
+
+ len = bitlen / 8;
+
+ /*
+ * The controller can do automatic CS control, but it is
+ * somewhat quirky, and it doesn't really buy us much anyway
+ * in the context of U-Boot.
+ */
+ if (flags & SPI_XFER_BEGIN) {
+ atmel_spi_cs_activate(dev);
+
+ /*
+ * sometimes the RDR is not empty when we get here,
+ * in theory that should not happen, but it DOES happen.
+ * Read it here to be on the safe side.
+ * That also clears the OVRES flag. Required if the
+ * following loop exits due to OVRES!
+ */
+ readl(®_base->rdr);
+ }
+
+ for (len_tx = 0, len_rx = 0; len_rx < len; ) {
+ status = readl(®_base->sr);
+
+ if (status & ATMEL_SPI_SR_OVRES)
+ return -1;
+
+ if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) {
+ if (txp)
+ value = *txp++;
+ else
+ value = 0;
+ writel(value, ®_base->tdr);
+ len_tx++;
+ }
+
+ if (status & ATMEL_SPI_SR_RDRF) {
+ value = readl(®_base->rdr);
+ if (rxp)
+ *rxp++ = value;
+ len_rx++;
+ }
+ }
+
+out:
+ if (flags & SPI_XFER_END) {
+ /*
+ * Wait until the transfer is completely done before
+ * we deactivate CS.
+ */
+ do {
+ status = readl(®_base->sr);
+ } while (!(status & ATMEL_SPI_SR_TXEMPTY));
+
+ atmel_spi_cs_deactivate(dev);
+ }
+
+ return 0;
+}
+
+static int atmel_spi_set_speed(struct udevice *bus, uint speed)
+{
+ struct atmel_spi_priv *priv = dev_get_priv(bus);
+
+ priv->freq = speed;
+
+ return 0;
+}
+
+static int atmel_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct atmel_spi_priv *priv = dev_get_priv(bus);
+
+ priv->mode = mode;
+
+ return 0;
+}
+
+static const struct dm_spi_ops atmel_spi_ops = {
+ .claim_bus = atmel_spi_claim_bus,
+ .release_bus = atmel_spi_release_bus,
+ .xfer = atmel_spi_xfer,
+ .set_speed = atmel_spi_set_speed,
+ .set_mode = atmel_spi_set_mode,
+ /*
+ * cs_info is not needed, since we require all chip selects to be
+ * in the device tree explicitly
+ */
+};
+
+static int atmel_spi_ofdata_to_platdata(struct udevice *bus)
+{
+ struct atmel_spi_priv *priv = dev_get_priv(bus);
+ int ret;
+
+ ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
+ ARRAY_SIZE(priv->cs_gpios), 0);
+ if (ret < 0) {
+ error("Can't get %s gpios! Error: %d", bus->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int atmel_spi_probe(struct udevice *bus)
+{
+ struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
+
+ bus_plat->regs = (struct at91_spi *)dev_get_addr(bus);
+
+ writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);
+
+ return 0;
+}
+
+static const struct udevice_id atmel_spi_ids[] = {
+ { .compatible = "atmel,at91rm9200-spi" },
+ { }
+};
+
+U_BOOT_DRIVER(atmel_spi) = {
+ .name = "atmel_spi",
+ .id = UCLASS_SPI,
+ .of_match = atmel_spi_ids,
+ .ops = &atmel_spi_ops,
+ .ofdata_to_platdata = atmel_spi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct atmel_spi_platdata),
+ .priv_auto_alloc_size = sizeof(struct atmel_spi_priv),
+ .probe = atmel_spi_probe,
+};
+#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver
2016-04-25 3:48 [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver Wenyou Yang
@ 2016-05-01 18:56 ` Simon Glass
2016-05-03 0:47 ` Yang, Wenyou
0 siblings, 1 reply; 4+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
To: u-boot
Hi Wenyou,
On 24 April 2016 at 21:48, Wenyou Yang <wenyou.yang@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.yang@atmel.com>
It is possible to combine this into the existing driver and reuse much
of the code?
BTW I have WIP patches to convert macb Ethernet and video. See
u-boot-dm/gurnard-working. I plan to post these next week.
Regards,
Simon
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver
2016-05-01 18:56 ` Simon Glass
@ 2016-05-03 0:47 ` Yang, Wenyou
2016-05-03 5:39 ` Heiko Schocher
0 siblings, 1 reply; 4+ messages in thread
From: Yang, Wenyou @ 2016-05-03 0:47 UTC (permalink / raw)
To: u-boot
Hi Simon,
Thank you for your support.
> -----Original Message-----
> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> Sent: 2016?5?2? 2:56
> To: Yang, Wenyou <Wenyou.Yang@atmel.com>
> Cc: U-Boot Mailing List <u-boot@lists.denx.de>
> Subject: Re: [U-Boot] [PATCH] dm: at91: Add driver model support for the spi
> driver
>
> Hi Wenyou,
>
> On 24 April 2016 at 21:48, Wenyou Yang <wenyou.yang@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.yang@atmel.com>
>
> It is possible to combine this into the existing driver and reuse much of the code?
Yes, it is.
As you know, it will take a long time to complete the DT & DM conversion. There is a question,
I don't know how to make all the boards works, inclusive ones which doesn't convert to DT.
>
> BTW I have WIP patches to convert macb Ethernet and video. See u-boot-
> dm/gurnard-working. I plan to post these next week.
Thank you for your information. It is very important for me.
>
> Regards,
> Simon
Best Regards,
Wenyou Yang
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver
2016-05-03 0:47 ` Yang, Wenyou
@ 2016-05-03 5:39 ` Heiko Schocher
0 siblings, 0 replies; 4+ messages in thread
From: Heiko Schocher @ 2016-05-03 5:39 UTC (permalink / raw)
To: u-boot
Hello Simon, Wenyou,
Am 03.05.2016 um 02:47 schrieb Yang, Wenyou:
> Hi Simon,
>
> Thank you for your support.
>
>> -----Original Message-----
>> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
>> Sent: 2016?5?2? 2:56
>> To: Yang, Wenyou <Wenyou.Yang@atmel.com>
>> Cc: U-Boot Mailing List <u-boot@lists.denx.de>
>> Subject: Re: [U-Boot] [PATCH] dm: at91: Add driver model support for the spi
>> driver
>>
>> Hi Wenyou,
>>
>> On 24 April 2016 at 21:48, Wenyou Yang <wenyou.yang@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.yang@atmel.com>
>>
>> It is possible to combine this into the existing driver and reuse much of the code?
>
> Yes, it is.
>
> As you know, it will take a long time to complete the DT & DM conversion. There is a question,
> I don't know how to make all the boards works, inclusive ones which doesn't convert to DT.
>
>>
>> BTW I have WIP patches to convert macb Ethernet and video. See u-boot-
>> dm/gurnard-working. I plan to post these next week.
>
> Thank you for your information. It is very important for me.
I just used the patches from Simon from the "dm/gurnard-working" branch
to convert the mainlined AT91 based boards from siemens (smartweb, corvus,
taurus and axm) to DM / DTS support. Ethernet uart, gpio works fine with
them.
Thanks Simon!
bye,
Heiko
>
>>
>> Regards,
>> Simon
>
>
> Best Regards,
> Wenyou Yang
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-05-03 5:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-25 3:48 [U-Boot] [PATCH] dm: at91: Add driver model support for the spi driver Wenyou Yang
2016-05-01 18:56 ` Simon Glass
2016-05-03 0:47 ` Yang, Wenyou
2016-05-03 5:39 ` Heiko Schocher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox