* [U-Boot] FSL eSPI driver is a mess, hack attached.
@ 2014-03-14 9:46 Joakim Tjernlund
2014-03-14 21:45 ` Michael Walle
2014-04-16 21:09 ` York Sun
0 siblings, 2 replies; 7+ messages in thread
From: Joakim Tjernlund @ 2014-03-14 9:46 UTC (permalink / raw)
To: u-boot
The fsl_espi.c is wreck w.r.t large TX data.
Below is what I had to hack to load a FPGA over SPI and
what is the malloc hack good for? This does not work
well for TXing several MB data.
The driver needs to be rewritten and I do not have the
time so I post what I got in the hope it can help someone
else or trigger a rewrite.
---
drivers/spi/fsl_espi.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c
index 7c84582..2843a8e 100644
--- a/drivers/spi/fsl_espi.c
+++ b/drivers/spi/fsl_espi.c
@@ -28,8 +28,9 @@ struct fsl_spi_slave {
#define ESPI_MAX_CS_NUM 4
-#define ESPI_EV_RNE (1 << 9)
-#define ESPI_EV_TNF (1 << 8)
+#define ESPI_EV_DON (1 << (31 - 17))
+#define ESPI_EV_RNE (1 << (31 - 22))
+#define ESPI_EV_TNF (1 << (31 - 23))
#define ESPI_MODE_EN (1 << 31) /* Enable interface */
#define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */
@@ -37,6 +38,8 @@ struct fsl_spi_slave {
#define ESPI_COM_CS(x) ((x) << 30)
#define ESPI_COM_TRANLEN(x) ((x) << 0)
+#define ESPI_COM_TO (1 << (31 - 4))
+
#define ESPI_CSMODE_CI_INACTIVEHIGH (1 << 31)
#define ESPI_CSMODE_CP_BEGIN_EDGCLK (1 << 30)
@@ -146,8 +149,9 @@ int spi_claim_bus(struct spi_slave *slave)
| ESPI_CSMODE_CI_INACTIVEHIGH);
/* Character bit order: msb first */
- out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
- | ESPI_CSMODE_REV_MSB_FIRST);
+ if (!(mode & SPI_LSB_FIRST))
+ out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
+ | ESPI_CSMODE_REV_MSB_FIRST);
/* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */
out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
@@ -172,7 +176,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
int len = 0;
int num_blks, num_chunks, max_tran_len, tran_len;
int num_bytes;
- unsigned char *ch;
+ //unsigned char *ch;
unsigned char *buffer = NULL;
size_t buf_len;
u8 *cmd_buf = fsl->cmd_buf;
@@ -216,20 +220,21 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
cmd_len = 0;
break;
}
-
+ dout = data_out;
debug("spi_xfer: slave %u:%u dout %08X(%p) din %08X(%p) len %u\n",
slave->bus, slave->cs, *(uint *) dout,
dout, *(uint *) din, din, len);
num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
+ dout = buffer;
while (num_chunks--) {
if (data_in)
din = buffer + rx_offset;
- dout = buffer;
tran_len = min(data_len , max_tran_len);
num_blks = DIV_ROUND_UP(tran_len + cmd_len, 4);
num_bytes = (tran_len + cmd_len) % 4;
fsl->data_len = tran_len + cmd_len;
+ data_len -= tran_len;
spi_cs_activate(slave);
/* Clear all eSPI events */
@@ -253,11 +258,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
}
/* Wait for eSPI transmit to get out */
- udelay(80);
+ udelay(5);
event = in_be32(&espi->event);
if (event & ESPI_EV_RNE) {
tmpdin = in_be32(&espi->rx);
+#if 0
if (num_blks == 0 && num_bytes != 0) {
ch = (unsigned char *)&tmpdin;
while (num_bytes--)
@@ -266,7 +272,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
*(u32 *) din = tmpdin;
din += 4;
}
-
+#endif
out_be32(&espi->event, in_be32(&espi->event)
| ESPI_EV_RNE);
debug("***spi_xfer:...%08x readed\n", tmpdin);
@@ -301,6 +307,7 @@ void spi_cs_activate(struct spi_slave *slave)
com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF));
com |= ESPI_COM_CS(slave->cs);
+ com |= ESPI_COM_TO;
com |= ESPI_COM_TRANLEN(data_len - 1);
out_be32(&espi->com, com);
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
2014-03-14 9:46 [U-Boot] FSL eSPI driver is a mess, hack attached Joakim Tjernlund
@ 2014-03-14 21:45 ` Michael Walle
2014-03-15 11:33 ` Joakim Tjernlund
2014-04-16 21:09 ` York Sun
1 sibling, 1 reply; 7+ messages in thread
From: Michael Walle @ 2014-03-14 21:45 UTC (permalink / raw)
To: u-boot
Am Freitag, 14. M?rz 2014, 10:46:26 schrieb Joakim Tjernlund:
> The fsl_espi.c is wreck w.r.t large TX data.
> Below is what I had to hack to load a FPGA over SPI and
> what is the malloc hack good for? This does not work
> well for TXing several MB data.
>
> The driver needs to be rewritten and I do not have the
> time so I post what I got in the hope it can help someone
> else or trigger a rewrite.
although this is a bit harsh, i'm inclined to agree. last time i tried this
driver, apart from reading from a spi flash, nothing else was working. even a
spi unlock was broken. if you actually capture the spi pins on a scope you see
that mostly garbage is transmitted in some cases (eg. using the raw spi
commands on the cli). fun fact: the spi unlock actually resulted in a spi lock
;)
i guess freescale haven't put much love into this one ;)
-michael
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
2014-03-14 21:45 ` Michael Walle
@ 2014-03-15 11:33 ` Joakim Tjernlund
2014-03-17 12:13 ` Michael Walle
0 siblings, 1 reply; 7+ messages in thread
From: Joakim Tjernlund @ 2014-03-15 11:33 UTC (permalink / raw)
To: u-boot
Michael Walle <michael@walle.cc> wrote on 2014/03/14 22:45:20:
>
> Am Freitag, 14. M?rz 2014, 10:46:26 schrieb Joakim Tjernlund:
> > The fsl_espi.c is wreck w.r.t large TX data.
> > Below is what I had to hack to load a FPGA over SPI and
> > what is the malloc hack good for? This does not work
> > well for TXing several MB data.
> >
> > The driver needs to be rewritten and I do not have the
> > time so I post what I got in the hope it can help someone
> > else or trigger a rewrite.
>
> although this is a bit harsh, i'm inclined to agree. last time i tried
this
> driver, apart from reading from a spi flash, nothing else was working.
even a
> spi unlock was broken. if you actually capture the spi pins on a scope
you see
> that mostly garbage is transmitted in some cases (eg. using the raw spi
> commands on the cli). fun fact: the spi unlock actually resulted in a
spi lock
> ;)
>
> i guess freescale haven't put much love into this one ;)
Yes, the driver is a quick hack to read small amounts of data from an
EEPROM/FLASH.
Have you tried the kernel driver for eSPI? I haven't gotten there yet but
I pray it is better.
Jocke
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
2014-03-15 11:33 ` Joakim Tjernlund
@ 2014-03-17 12:13 ` Michael Walle
0 siblings, 0 replies; 7+ messages in thread
From: Michael Walle @ 2014-03-17 12:13 UTC (permalink / raw)
To: u-boot
Am 2014-03-15 12:33, schrieb Joakim Tjernlund:
> Have you tried the kernel driver for eSPI? I haven't gotten there yet
> but
> I pray it is better.
yeah kernel driver is better.
-michael
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
2014-03-14 9:46 [U-Boot] FSL eSPI driver is a mess, hack attached Joakim Tjernlund
2014-03-14 21:45 ` Michael Walle
@ 2014-04-16 21:09 ` York Sun
2014-04-17 3:48 ` Mingkai.Hu at freescale.com
1 sibling, 1 reply; 7+ messages in thread
From: York Sun @ 2014-04-16 21:09 UTC (permalink / raw)
To: u-boot
Mingkai,
Please take a look at this patch and see if you can verify and polish it.
York
On 03/14/2014 02:46 AM, Joakim Tjernlund wrote:
> The fsl_espi.c is wreck w.r.t large TX data.
> Below is what I had to hack to load a FPGA over SPI and
> what is the malloc hack good for? This does not work
> well for TXing several MB data.
>
> The driver needs to be rewritten and I do not have the
> time so I post what I got in the hope it can help someone
> else or trigger a rewrite.
>
> ---
> drivers/spi/fsl_espi.c | 25 ++++++++++++++++---------
> 1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c
> index 7c84582..2843a8e 100644
> --- a/drivers/spi/fsl_espi.c
> +++ b/drivers/spi/fsl_espi.c
> @@ -28,8 +28,9 @@ struct fsl_spi_slave {
>
> #define ESPI_MAX_CS_NUM 4
>
> -#define ESPI_EV_RNE (1 << 9)
> -#define ESPI_EV_TNF (1 << 8)
> +#define ESPI_EV_DON (1 << (31 - 17))
> +#define ESPI_EV_RNE (1 << (31 - 22))
> +#define ESPI_EV_TNF (1 << (31 - 23))
>
> #define ESPI_MODE_EN (1 << 31) /* Enable interface */
> #define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */
> @@ -37,6 +38,8 @@ struct fsl_spi_slave {
>
> #define ESPI_COM_CS(x) ((x) << 30)
> #define ESPI_COM_TRANLEN(x) ((x) << 0)
> +#define ESPI_COM_TO (1 << (31 - 4))
> +
>
> #define ESPI_CSMODE_CI_INACTIVEHIGH (1 << 31)
> #define ESPI_CSMODE_CP_BEGIN_EDGCLK (1 << 30)
> @@ -146,8 +149,9 @@ int spi_claim_bus(struct spi_slave *slave)
> | ESPI_CSMODE_CI_INACTIVEHIGH);
>
> /* Character bit order: msb first */
> - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
> - | ESPI_CSMODE_REV_MSB_FIRST);
> + if (!(mode & SPI_LSB_FIRST))
> + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
> + | ESPI_CSMODE_REV_MSB_FIRST);
>
> /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */
> out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
> @@ -172,7 +176,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> int len = 0;
> int num_blks, num_chunks, max_tran_len, tran_len;
> int num_bytes;
> - unsigned char *ch;
> + //unsigned char *ch;
> unsigned char *buffer = NULL;
> size_t buf_len;
> u8 *cmd_buf = fsl->cmd_buf;
> @@ -216,20 +220,21 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> cmd_len = 0;
> break;
> }
> -
> + dout = data_out;
> debug("spi_xfer: slave %u:%u dout %08X(%p) din %08X(%p) len %u\n",
> slave->bus, slave->cs, *(uint *) dout,
> dout, *(uint *) din, din, len);
>
> num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
> + dout = buffer;
> while (num_chunks--) {
> if (data_in)
> din = buffer + rx_offset;
> - dout = buffer;
> tran_len = min(data_len , max_tran_len);
> num_blks = DIV_ROUND_UP(tran_len + cmd_len, 4);
> num_bytes = (tran_len + cmd_len) % 4;
> fsl->data_len = tran_len + cmd_len;
> + data_len -= tran_len;
> spi_cs_activate(slave);
>
> /* Clear all eSPI events */
> @@ -253,11 +258,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> }
>
> /* Wait for eSPI transmit to get out */
> - udelay(80);
> + udelay(5);
>
> event = in_be32(&espi->event);
> if (event & ESPI_EV_RNE) {
> tmpdin = in_be32(&espi->rx);
> +#if 0
> if (num_blks == 0 && num_bytes != 0) {
> ch = (unsigned char *)&tmpdin;
> while (num_bytes--)
> @@ -266,7 +272,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> *(u32 *) din = tmpdin;
> din += 4;
> }
> -
> +#endif
> out_be32(&espi->event, in_be32(&espi->event)
> | ESPI_EV_RNE);
> debug("***spi_xfer:...%08x readed\n", tmpdin);
> @@ -301,6 +307,7 @@ void spi_cs_activate(struct spi_slave *slave)
>
> com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF));
> com |= ESPI_COM_CS(slave->cs);
> + com |= ESPI_COM_TO;
> com |= ESPI_COM_TRANLEN(data_len - 1);
> out_be32(&espi->com, com);
> }
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
2014-04-16 21:09 ` York Sun
@ 2014-04-17 3:48 ` Mingkai.Hu at freescale.com
0 siblings, 0 replies; 7+ messages in thread
From: Mingkai.Hu at freescale.com @ 2014-04-17 3:48 UTC (permalink / raw)
To: u-boot
Hi York,
We were also considering to improve the eSPI driver and we will look into this.
Thanks,
Mingkai
-----Original Message-----
From: Sun York-R58495
Sent: Thursday, April 17, 2014 5:09 AM
Cc: u-boot at lists.denx.de; Hu Mingkai-B21284
Subject: Re: [U-Boot] FSL eSPI driver is a mess, hack attached.
Mingkai,
Please take a look at this patch and see if you can verify and polish it.
York
On 03/14/2014 02:46 AM, Joakim Tjernlund wrote:
> The fsl_espi.c is wreck w.r.t large TX data.
> Below is what I had to hack to load a FPGA over SPI and what is the
> malloc hack good for? This does not work well for TXing several MB
> data.
>
> The driver needs to be rewritten and I do not have the time so I post
> what I got in the hope it can help someone else or trigger a rewrite.
>
> ---
> drivers/spi/fsl_espi.c | 25 ++++++++++++++++---------
> 1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c index
> 7c84582..2843a8e 100644
> --- a/drivers/spi/fsl_espi.c
> +++ b/drivers/spi/fsl_espi.c
> @@ -28,8 +28,9 @@ struct fsl_spi_slave {
>
> #define ESPI_MAX_CS_NUM 4
>
> -#define ESPI_EV_RNE (1 << 9)
> -#define ESPI_EV_TNF (1 << 8)
> +#define ESPI_EV_DON (1 << (31 - 17))
> +#define ESPI_EV_RNE (1 << (31 - 22))
> +#define ESPI_EV_TNF (1 << (31 - 23))
>
> #define ESPI_MODE_EN (1 << 31) /* Enable interface */
> #define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */
> @@ -37,6 +38,8 @@ struct fsl_spi_slave {
>
> #define ESPI_COM_CS(x) ((x) << 30)
> #define ESPI_COM_TRANLEN(x) ((x) << 0)
> +#define ESPI_COM_TO (1 << (31 - 4))
> +
>
> #define ESPI_CSMODE_CI_INACTIVEHIGH (1 << 31)
> #define ESPI_CSMODE_CP_BEGIN_EDGCLK (1 << 30)
> @@ -146,8 +149,9 @@ int spi_claim_bus(struct spi_slave *slave)
> | ESPI_CSMODE_CI_INACTIVEHIGH);
>
> /* Character bit order: msb first */
> - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
> - | ESPI_CSMODE_REV_MSB_FIRST);
> + if (!(mode & SPI_LSB_FIRST))
> + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs])
> + | ESPI_CSMODE_REV_MSB_FIRST);
>
> /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */
> out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) @@ -172,7
> +176,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> int len = 0;
> int num_blks, num_chunks, max_tran_len, tran_len;
> int num_bytes;
> - unsigned char *ch;
> + //unsigned char *ch;
> unsigned char *buffer = NULL;
> size_t buf_len;
> u8 *cmd_buf = fsl->cmd_buf;
> @@ -216,20 +220,21 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> cmd_len = 0;
> break;
> }
> -
> + dout = data_out;
> debug("spi_xfer: slave %u:%u dout %08X(%p) din %08X(%p) len %u\n",
> slave->bus, slave->cs, *(uint *) dout,
> dout, *(uint *) din, din, len);
>
> num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
> + dout = buffer;
> while (num_chunks--) {
> if (data_in)
> din = buffer + rx_offset;
> - dout = buffer;
> tran_len = min(data_len , max_tran_len);
> num_blks = DIV_ROUND_UP(tran_len + cmd_len, 4);
> num_bytes = (tran_len + cmd_len) % 4;
> fsl->data_len = tran_len + cmd_len;
> + data_len -= tran_len;
> spi_cs_activate(slave);
>
> /* Clear all eSPI events */
> @@ -253,11 +258,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> }
>
> /* Wait for eSPI transmit to get out */
> - udelay(80);
> + udelay(5);
>
> event = in_be32(&espi->event);
> if (event & ESPI_EV_RNE) {
> tmpdin = in_be32(&espi->rx);
> +#if 0
> if (num_blks == 0 && num_bytes != 0) {
> ch = (unsigned char *)&tmpdin;
> while (num_bytes--)
> @@ -266,7 +272,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
> *(u32 *) din = tmpdin;
> din += 4;
> }
> -
> +#endif
> out_be32(&espi->event, in_be32(&espi->event)
> | ESPI_EV_RNE);
> debug("***spi_xfer:...%08x readed\n", tmpdin); @@ -301,6 +307,7
> @@ void spi_cs_activate(struct spi_slave *slave)
>
> com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF));
> com |= ESPI_COM_CS(slave->cs);
> + com |= ESPI_COM_TO;
> com |= ESPI_COM_TRANLEN(data_len - 1);
> out_be32(&espi->com, com);
> }
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] FSL eSPI driver is a mess, hack attached.
@ 2014-07-23 11:27 Eliot Dudley
0 siblings, 0 replies; 7+ messages in thread
From: Eliot Dudley @ 2014-07-23 11:27 UTC (permalink / raw)
To: u-boot
We're bringing up a board that boots from SPI flash, so we had to re-work
fsl_espi.c for to get it to work at all and for speed.
Been working from 2009.11 because that's what came with a P1022DS box that
Freescale so generously provided. There has been a tremendous amount
divergence since 2009.11 and it will be a long time if ever before I get a
chance to start over with the trunk, plus I am not up to speed with
patches, git, and so forth.
So I'm just going to past in some code fragments here in case anyone wants
to re-work the trunk with a know-good implemntation. From the looks of it
it should be straightforward to revise the current fsl_espi.c
First, a fragment for computing Hz so it is not more than max_hz:
/* Set eSPI BRG clock source */
get_sys_info(&sysinfo);
eSPI_baud_rate_generator = sysinfo.freqSystemBus / 2;
for (prescale = 0; prescale < 2; ++prescale) {
for (pm = 0; pm < 16; ++pm) {
if (
(
(eSPI_baud_rate_generator) /
((prescale ? 16 : 1) * 2 * (pm + 1))
) <=
(max_hz)
) {
goto csmode_DONE;
}
}
}
debug(
"fls_espi: spi_setup_slave: Requested %d Hz is too low, using %d Hz"
,max_hz
,eSPI_baud_rate_generator / ((prescale ? 16 : 1) * 2 * (pm + 1))
);
prescale = 1;
pm = 15;
csmode_DONE:
(prescale) && (espi->csmode[cs] |= ESPI_CSMODE_DIV16);
espi->csmode[cs] |= ESPI_CSMODE_PM(pm);
And here is the xfer code. It is 850 times faster than 2009.11. (Love my
new Saleae Logic 16.)
int espi_xfer(struct spi_slave *slave)
{
volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
struct espi_transfer *t = slave->transfer;
/* Tx logic. */
#define FIFO_BYTES 32
#define TX_IDLE 0xffffffff
unsigned int tx_len = t->cmd_len + t->data_len;
unsigned int cmd_len = t->cmd_len;
u8 *cmd_ptr = (u8*)t->tx_buf;
int tx_fifo_bytes;
int tx_fifo_words;
int tx_bytes;
int cmd_bytes;
unsigned long tx;
/* Rx logic. */
unsigned int rx_len = t->cmd_len + t->data_len;
int rx_bytes;
int rx_words;
u8 *data_dst = (u8*)t->rx_buf;
int data_idx = -((int)cmd_len);
int data_bytes;
unsigned long rx;
/* Variables for computing a non-forever timeout. */
int spin = 0;
int spin_per_timeout;
/* WAG. Using factor of twenty for timeout below so mox nix.*/
unsigned int cpu_clock_per_spin = 60;
unsigned int cpu_clock_per_word;
/*
* This controller automatically asserts and negates CS,
* so we will not pretend that it does not.
* If board has other means for gating CS to the device then
* that is something to be dealt with higher up the stack.
*/
if (
(t->flags & (SPI_XFER_BEGIN | SPI_XFER_END)) !=
(SPI_XFER_BEGIN | SPI_XFER_END)
) {
printf(
"fsl_espi: espi_xfer(): Unsupported mode: flags=0x%08x\n"
,(unsigned int)t->flags
);
return -1;
}
cpu_clock_per_word =
(32) *
(2) *
((espi->csmode[slave->cs] & ESPI_CSMODE_DIV16) ? 16 : 1) *
(2 * (((espi->csmode[slave->cs] >> 24) & 0x0f) + 1))
;
spin_per_timeout = 20 * (cpu_clock_per_word / cpu_clock_per_spin);
spi_cs_activate(slave);
/* Clear all eSPI events. */
espi->event = 0xffffffff;
/* Fill xmt FIFO with as many as FIFO_BYTES (32) bytes. */
tx_fifo_bytes = FIFO_BYTES;
(tx_fifo_bytes > tx_len) && (tx_fifo_bytes = tx_len);
tx_fifo_words = (tx_fifo_bytes + 3) / 4;
while (tx_fifo_words--) {
tx = TX_IDLE;
((tx_bytes = 4) > tx_len) && (tx_bytes = tx_len);
if (cmd_len) {
((cmd_bytes = tx_bytes) > cmd_len) && (cmd_bytes = cmd_len);
memcpy(&tx, cmd_ptr, cmd_bytes);
cmd_len -= cmd_bytes;
cmd_ptr += cmd_bytes;
}
espi->tx = tx;
tx_len -= tx_bytes;
}
for (rx_words = (rx_len + 3) / 4; rx_words--;) {
/* Wait for rx or timeout. */
((rx_bytes = 4) > rx_len) && (rx_bytes = rx_len);
spin = spin_per_timeout;
while ((((espi->event & 0x3f000000) >> 24) < rx_bytes) && (--spin)) {
;
}
/* Timed out? */
if (!spin) {
break;
}
/* Read from rx FIFO. */
rx = espi->rx;
/* Copy to espi_transfer->rx_buf when xmt is done with cmd. */
if (data_dst) {
if (data_idx >= 0) {
memcpy(data_dst, &rx, rx_bytes);
data_dst += rx_bytes;
} else {
if ((data_idx += 4) > 0) {
((data_bytes = data_idx) > rx_len) && (data_bytes = rx_len);
memcpy(data_dst, ((u8 *)&rx) + (4 - data_idx), data_bytes);
data_dst += data_bytes;
}
}
}
rx_len -= rx_bytes;
/* Previous rx is complete so there is room in FIFO for the next tx.
*/
if (tx_len) {
tx = TX_IDLE;
((tx_bytes = 4) > tx_len) && (tx_bytes = tx_len);
if (cmd_len) {
((cmd_bytes = tx_bytes) > cmd_len) && (cmd_bytes = cmd_len);
memcpy(&tx, cmd_ptr, cmd_bytes);
cmd_len -= cmd_bytes;
cmd_ptr += cmd_bytes;
}
espi->tx = tx;
tx_len -= tx_bytes;
}
}
spi_cs_deactivate(slave);
if (!spin) {
printf("fsl_espi: espi_xfer(): timeout");
return -1;
}
return 0;
}
void spi_cs_activate(struct spi_slave *slave)
{
volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
struct espi_transfer *t = slave->transfer;
unsigned int com = 0;
unsigned int len = t->cmd_len + t->data_len;
com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xffff));
com |= ESPI_COM_CS(slave->cs);
com |= ESPI_COM_TRANLEN(len - 1);
espi->com = com;
}
void spi_cs_deactivate(struct spi_slave *slave)
{
volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR);
/* clear the RXCNT and TXCNT */
espi->mode &= ~ESPI_MODE_EN;
espi->mode |= ESPI_MODE_EN;
}
--ewd
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-07-23 11:27 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-14 9:46 [U-Boot] FSL eSPI driver is a mess, hack attached Joakim Tjernlund
2014-03-14 21:45 ` Michael Walle
2014-03-15 11:33 ` Joakim Tjernlund
2014-03-17 12:13 ` Michael Walle
2014-04-16 21:09 ` York Sun
2014-04-17 3:48 ` Mingkai.Hu at freescale.com
2014-07-23 11:27 Eliot Dudley
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.